From 1cdf8bc18f1ee43a39e543506fff8d5db3020ae1 Mon Sep 17 00:00:00 2001 From: Satish Kharat Date: Mon, 26 Jun 2017 17:46:23 -0700 Subject: scsi: fnic: Zero io_cmpl_skip on fw reset completion io_cmpl_skip keep track of number of completions to skip when stats are reset. If a fw_reset happens immediately after stats reset it could put it out of sync so need to reset io_cmpl_skip when fw reset is completed. Signed-off-by: Satish Kharat Signed-off-by: Sesidhar Baddela Signed-off-by: Martin K. Petersen --- drivers/scsi/fnic/fnic_scsi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/scsi/fnic') diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index d048f3b5006f..beea14c40a95 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -633,6 +633,7 @@ static int fnic_fcpio_fw_reset_cmpl_handler(struct fnic *fnic, atomic64_set(&fnic->fnic_stats.fw_stats.active_fw_reqs, 0); atomic64_set(&fnic->fnic_stats.io_stats.active_ios, 0); + atomic64_set(&fnic->io_cmpl_skip, 0); spin_lock_irqsave(&fnic->fnic_lock, flags); -- cgit v1.2.3 From 43caa03fec79d062c5f7a959a823770d72717b24 Mon Sep 17 00:00:00 2001 From: Satish Kharat Date: Mon, 26 Jun 2017 17:48:08 -0700 Subject: scsi: fnic: added timestamp reporting in fnic debug stats Added the timestamps for 1. current timestamp 2. last fnic stats read timestamp 3. last fnic stats reset timestamp and the deltas since last stats read and last reset in fnic stats. fnic stats uses debugfs Signed-off-by: Sesidhar Baddela Signed-off-by: Satish Kharat Signed-off-by: Martin K. Petersen --- drivers/scsi/fnic/fnic_debugfs.c | 1 + drivers/scsi/fnic/fnic_stats.h | 7 +++++++ drivers/scsi/fnic/fnic_trace.c | 24 ++++++++++++++++++++++++ 3 files changed, 32 insertions(+) (limited to 'drivers/scsi/fnic') diff --git a/drivers/scsi/fnic/fnic_debugfs.c b/drivers/scsi/fnic/fnic_debugfs.c index d6498fabe628..5e3d909cfc53 100644 --- a/drivers/scsi/fnic/fnic_debugfs.c +++ b/drivers/scsi/fnic/fnic_debugfs.c @@ -632,6 +632,7 @@ static ssize_t fnic_reset_stats_write(struct file *file, sizeof(struct io_path_stats) - sizeof(u64)); memset(fw_stats_p+1, 0, sizeof(struct fw_stats) - sizeof(u64)); + getnstimeofday(&stats->stats_timestamps.last_reset_time); } (*ppos)++; diff --git a/drivers/scsi/fnic/fnic_stats.h b/drivers/scsi/fnic/fnic_stats.h index 88c73cccb015..e007feedbf72 100644 --- a/drivers/scsi/fnic/fnic_stats.h +++ b/drivers/scsi/fnic/fnic_stats.h @@ -16,6 +16,12 @@ */ #ifndef _FNIC_STATS_H_ #define _FNIC_STATS_H_ + +struct stats_timestamps { + struct timespec last_reset_time; + struct timespec last_read_time; +}; + struct io_path_stats { atomic64_t active_ios; atomic64_t max_active_ios; @@ -110,6 +116,7 @@ struct misc_stats { }; struct fnic_stats { + struct stats_timestamps stats_timestamps; struct io_path_stats io_stats; struct abort_stats abts_stats; struct terminate_stats term_stats; diff --git a/drivers/scsi/fnic/fnic_trace.c b/drivers/scsi/fnic/fnic_trace.c index b5ac5381a0d7..4826f596cb31 100644 --- a/drivers/scsi/fnic/fnic_trace.c +++ b/drivers/scsi/fnic/fnic_trace.c @@ -219,7 +219,31 @@ int fnic_get_stats_data(struct stats_debug_info *debug, int buf_size = debug->buf_size; struct timespec val1, val2; + getnstimeofday(&val1); len = snprintf(debug->debug_buffer + len, buf_size - len, + "------------------------------------------\n" + "\t\tTime\n" + "------------------------------------------\n"); + + len += snprintf(debug->debug_buffer + len, buf_size - len, + "Current time : [%ld:%ld]\n" + "Last stats reset time: [%ld:%ld]\n" + "Last stats read time: [%ld:%ld]\n" + "delta since last reset: [%ld:%ld]\n" + "delta since last read: [%ld:%ld]\n", + val1.tv_sec, val1.tv_nsec, + stats->stats_timestamps.last_reset_time.tv_sec, + stats->stats_timestamps.last_reset_time.tv_nsec, + stats->stats_timestamps.last_read_time.tv_sec, + stats->stats_timestamps.last_read_time.tv_nsec, + timespec_sub(val1, stats->stats_timestamps.last_reset_time).tv_sec, + timespec_sub(val1, stats->stats_timestamps.last_reset_time).tv_nsec, + timespec_sub(val1, stats->stats_timestamps.last_read_time).tv_sec, + timespec_sub(val1, stats->stats_timestamps.last_read_time).tv_nsec); + + stats->stats_timestamps.last_read_time = val1; + + len += snprintf(debug->debug_buffer + len, buf_size - len, "------------------------------------------\n" "\t\tIO Statistics\n" "------------------------------------------\n"); -- cgit v1.2.3 From c22fa50b2d41f3091d2ab0acf60ffdedb7ccd765 Mon Sep 17 00:00:00 2001 From: Satish Kharat Date: Mon, 26 Jun 2017 17:48:44 -0700 Subject: scsi: fnic: correct speed display and add support for 25,40 and 100G Setting speed based on the vinc device parameter read during linkup. Also adding support to display 25,40 and 100G Signed-off-by: Satish Kharat Signed-off-by: Sesidhar Baddela Signed-off-by: Martin K. Petersen --- drivers/scsi/fnic/fnic_fcs.c | 24 ++++++++++++++++++++++++ drivers/scsi/fnic/fnic_io.h | 9 +++++++++ drivers/scsi/fnic/fnic_main.c | 14 ++++++++++++-- 3 files changed, 45 insertions(+), 2 deletions(-) (limited to 'drivers/scsi/fnic') diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c index 245dcd95e11f..d212eb574c94 100644 --- a/drivers/scsi/fnic/fnic_fcs.c +++ b/drivers/scsi/fnic/fnic_fcs.c @@ -65,6 +65,30 @@ void fnic_handle_link(struct work_struct *work) fnic->link_status = vnic_dev_link_status(fnic->vdev); fnic->link_down_cnt = vnic_dev_link_down_cnt(fnic->vdev); + switch (vnic_dev_port_speed(fnic->vdev)) { + case DCEM_PORTSPEED_10G: + fc_host_speed(fnic->lport->host) = FC_PORTSPEED_10GBIT; + fnic->lport->link_supported_speeds = FC_PORTSPEED_10GBIT; + break; + case DCEM_PORTSPEED_25G: + fc_host_speed(fnic->lport->host) = FC_PORTSPEED_25GBIT; + fnic->lport->link_supported_speeds = FC_PORTSPEED_25GBIT; + break; + case DCEM_PORTSPEED_40G: + case DCEM_PORTSPEED_4x10G: + fc_host_speed(fnic->lport->host) = FC_PORTSPEED_40GBIT; + fnic->lport->link_supported_speeds = FC_PORTSPEED_40GBIT; + break; + case DCEM_PORTSPEED_100G: + fc_host_speed(fnic->lport->host) = FC_PORTSPEED_100GBIT; + fnic->lport->link_supported_speeds = FC_PORTSPEED_100GBIT; + break; + default: + fc_host_speed(fnic->lport->host) = FC_PORTSPEED_UNKNOWN; + fnic->lport->link_supported_speeds = FC_PORTSPEED_UNKNOWN; + break; + } + if (old_link_status == fnic->link_status) { if (!fnic->link_status) { /* DOWN -> DOWN */ diff --git a/drivers/scsi/fnic/fnic_io.h b/drivers/scsi/fnic/fnic_io.h index c35b8f1889ea..e0bc659ed71f 100644 --- a/drivers/scsi/fnic/fnic_io.h +++ b/drivers/scsi/fnic/fnic_io.h @@ -66,4 +66,13 @@ struct fnic_io_req { struct completion *dr_done; /* completion for device reset */ }; +enum fnic_port_speeds { + DCEM_PORTSPEED_NONE = 0, + DCEM_PORTSPEED_1G = 1000, + DCEM_PORTSPEED_10G = 10000, + DCEM_PORTSPEED_40G = 40000, + DCEM_PORTSPEED_4x10G = 41000, + DCEM_PORTSPEED_25G = 25000, + DCEM_PORTSPEED_100G = 100000, +}; #endif /* _FNIC_IO_H_ */ diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index ba58b7953263..aacadbf20b69 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c @@ -176,11 +176,21 @@ static void fnic_get_host_speed(struct Scsi_Host *shost) /* Add in other values as they get defined in fw */ switch (port_speed) { - case 10000: + case DCEM_PORTSPEED_10G: fc_host_speed(shost) = FC_PORTSPEED_10GBIT; break; + case DCEM_PORTSPEED_25G: + fc_host_speed(shost) = FC_PORTSPEED_25GBIT; + break; + case DCEM_PORTSPEED_40G: + case DCEM_PORTSPEED_4x10G: + fc_host_speed(shost) = FC_PORTSPEED_40GBIT; + break; + case DCEM_PORTSPEED_100G: + fc_host_speed(shost) = FC_PORTSPEED_100GBIT; + break; default: - fc_host_speed(shost) = FC_PORTSPEED_10GBIT; + fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; break; } } -- cgit v1.2.3 From 4a1108d6caf7cd0f15d439bee6163ba00c7c1b33 Mon Sep 17 00:00:00 2001 From: Satish Kharat Date: Mon, 26 Jun 2017 17:49:06 -0700 Subject: scsi: fnic: changing queue command to return result DID_IMM_RETRY when rport is init Currently the queue command returns DID_NO_CONNECT anytime the rport is not in RPORT_ST_READY state. Changing it to return DID_NO_CONNECT only when the rport is in RPORT_ST_DELETE state. When the rport is in one of the init states retruning DID_IMM_RETRY. Signed-off-by: Sesidhar Baddela Signed-off-by: Satish Kharat Signed-off-by: Martin K. Petersen --- drivers/scsi/fnic/fnic_scsi.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers/scsi/fnic') diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index beea14c40a95..6c0646d62dfb 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -466,15 +466,27 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_ } rp = rport->dd_data; - if (!rp || rp->rp_state != RPORT_ST_READY) { + if (!rp || rp->rp_state == RPORT_ST_DELETE) { FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, - "returning DID_NO_CONNECT for IO as rport is removed\n"); + "rport 0x%x removed, returning DID_NO_CONNECT\n", + rport->port_id); + atomic64_inc(&fnic_stats->misc_stats.rport_not_ready); sc->result = DID_NO_CONNECT<<16; done(sc); return 0; } + if (rp->rp_state != RPORT_ST_READY) { + FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, + "rport 0x%x in state 0x%x, returning DID_IMM_RETRY\n", + rport->port_id, rp->rp_state); + + sc->result = DID_IMM_RETRY << 16; + done(sc); + return 0; + } + if (lp->state != LPORT_ST_READY || !(lp->link_up)) return SCSI_MLQUEUE_HOST_BUSY; -- cgit v1.2.3