[PATCH 3/3] fnic: Incremented driver version
Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index db7a950..528d43b 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -39,7 +39,7 @@ #define DRV_NAME fnic #define DRV_DESCRIPTIONCisco FCoE HBA Driver -#define DRV_VERSION1.5.0.23 +#define DRV_VERSION1.5.0.45 #define PFXDRV_NAME : #define DFX DRV_NAME %d: -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] fnic: host reset returns nonzero value(errno) on success
From: Narsimhulu Musini nmus...@cisco.com Fixed appropriate error codes that returns negative error number on failure, and 0 on success. fnic_reset() is used directly by the fc transport callback issue_fc_host_lip which requires a negative error number on failure. Signed-off-by: Narsimhulu Musini nmus...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_scsi.c |9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index d014aae..50f3b32 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -2207,7 +2207,7 @@ int fnic_reset(struct Scsi_Host *shost) { struct fc_lport *lp; struct fnic *fnic; - int ret = SUCCESS; + int ret = 0; lp = shost_priv(shost); fnic = lport_priv(lp); @@ -2219,12 +2219,11 @@ int fnic_reset(struct Scsi_Host *shost) * Reset local port, this will clean up libFC exchanges, * reset remote port sessions, and if link is up, begin flogi */ - if (lp-tt.lport_reset(lp)) - ret = FAILED; + ret = lp-tt.lport_reset(lp); FNIC_SCSI_DBG(KERN_DEBUG, fnic-lport-host, Returning from fnic reset %s\n, - (ret == SUCCESS) ? + (ret == 0) ? SUCCESS : FAILED); return ret; @@ -2251,7 +2250,7 @@ int fnic_host_reset(struct scsi_cmnd *sc) * scsi-ml tries to send a TUR to every device if host reset is * successful, so before returning to scsi, fabric should be up */ - ret = fnic_reset(shost); + ret = (fnic_reset(shost) == 0) ? SUCCESS : FAILED; if (ret == SUCCESS) { wait_host_tmo = jiffies + FNIC_HOST_RESET_SETTLE_TIME * HZ; ret = FAILED; -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/9] fnic: On system with 1.1TB RAM, VIC fails multipath after boot up
From: Brian Uchino buch...@cisco.com Issue was seen when SCSI buffer address is more than 40 bits in system with more than 1.1TB RAM. When SCSI buffer is passed to VIC, it is failing to map to correct buffer address, as DMA mask is set to 40 bits in driver initialization. Corrected DMA_MASK from 40-bits to 64-bits to avoid masking 41-64 bits addresses. Signed-off-by: Brian Uchino buch...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_main.c |8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index b619dab..835a9cd 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c @@ -581,10 +581,10 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_master(pdev); /* Query PCI controller on system for DMA addressing -* limitation for the device. Try 40-bit first, and +* limitation for the device. Try 64-bit first, and * fail to 32-bit. */ - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(40)); + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); if (err) { err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (err) { @@ -601,10 +601,10 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_release_regions; } } else { - err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(40)); + err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); if (err) { shost_printk(KERN_ERR, fnic-lport-host, -Unable to obtain 40-bit DMA +Unable to obtain 64-bit DMA for consistent allocations, aborting.\n); goto err_out_release_regions; } -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/9] fnic: host reset returns nonzero value(errno) on success
From: Narsimhulu Musini nmus...@cisco.com Fixed appropriate error codes that returns -1 on failure, and 0 on success Signed-off-by: Narsimhulu Musini nmus...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_scsi.c |8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index a97e6e5..ef3c463 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -2208,7 +2208,7 @@ int fnic_reset(struct Scsi_Host *shost) { struct fc_lport *lp; struct fnic *fnic; - int ret = SUCCESS; + int ret = 0; lp = shost_priv(shost); fnic = lport_priv(lp); @@ -2221,11 +2221,11 @@ int fnic_reset(struct Scsi_Host *shost) * reset remote port sessions, and if link is up, begin flogi */ if (lp-tt.lport_reset(lp)) - ret = FAILED; + ret = -1; FNIC_SCSI_DBG(KERN_DEBUG, fnic-lport-host, Returning from fnic reset %s\n, - (ret == SUCCESS) ? + (ret == 0) ? SUCCESS : FAILED); return ret; @@ -2252,7 +2252,7 @@ int fnic_host_reset(struct scsi_cmnd *sc) * scsi-ml tries to send a TUR to every device if host reset is * successful, so before returning to scsi, fabric should be up */ - ret = fnic_reset(shost); + ret = (fnic_reset(shost) == 0) ? SUCCESS : FAILED; if (ret == SUCCESS) { wait_host_tmo = jiffies + FNIC_HOST_RESET_SETTLE_TIME * HZ; ret = FAILED; -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/9] fnic: Hitting BUG_ON(io_req-abts_done) in fnic_rport_exch_reset
From: Sesidhar Beddel sebad...@cisco.com Hitting BUG_ON(io_req-abts_done) in fnic_rport_exch_reset in case of timing issue and also to some extent locking issue where abts and terminate is happening around same timing. The code changes are intended to update CMD_STATE(sc) and io_req-abts_done together. Signed-off-by: Sesidhar Beddel sebad...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_scsi.c | 70 - 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index a09dd8d..100cdba 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -111,6 +111,12 @@ static inline spinlock_t *fnic_io_lock_hash(struct fnic *fnic, return fnic-io_req_lock[hash]; } +static inline spinlock_t *fnic_io_lock_tag(struct fnic *fnic, + int tag) +{ + return fnic-io_req_lock[tag (FNIC_IO_LOCKS - 1)]; +} + /* * Unmap the data buffer and sense buffer for an io_req, * also unmap and free the device-private scatter/gather list. @@ -956,9 +962,7 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic, spin_unlock_irqrestore(io_lock, flags); return; } - CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE; CMD_ABTS_STATUS(sc) = hdr_status; - CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_DONE; FNIC_SCSI_DBG(KERN_DEBUG, fnic-lport-host, abts cmpl recd. id %d status %s\n, @@ -1116,7 +1120,7 @@ int fnic_wq_copy_cmpl_handler(struct fnic *fnic, int copy_work_to_do) static void fnic_cleanup_io(struct fnic *fnic, int exclude_id) { - unsigned int i; + int i; struct fnic_io_req *io_req; unsigned long flags = 0; struct scsi_cmnd *sc; @@ -1127,12 +1131,14 @@ static void fnic_cleanup_io(struct fnic *fnic, int exclude_id) if (i == exclude_id) continue; + io_lock = fnic_io_lock_tag(fnic, i); + spin_lock_irqsave(io_lock, flags); sc = scsi_host_find_tag(fnic-lport-host, i); - if (!sc) + if (!sc) { + spin_unlock_irqrestore(io_lock, flags); continue; + } - io_lock = fnic_io_lock_hash(fnic, sc); - spin_lock_irqsave(io_lock, flags); io_req = (struct fnic_io_req *)CMD_SP(sc); if ((CMD_FLAGS(sc) FNIC_DEVICE_RESET) !(CMD_FLAGS(sc) FNIC_DEV_RST_DONE)) { @@ -1310,12 +1316,13 @@ static void fnic_rport_exch_reset(struct fnic *fnic, u32 port_id) for (tag = 0; tag FNIC_MAX_IO_REQ; tag++) { abt_tag = tag; + io_lock = fnic_io_lock_tag(fnic, tag); + spin_lock_irqsave(io_lock, flags); sc = scsi_host_find_tag(fnic-lport-host, tag); - if (!sc) + if (!sc) { + spin_unlock_irqrestore(io_lock, flags); continue; - - io_lock = fnic_io_lock_hash(fnic, sc); - spin_lock_irqsave(io_lock, flags); + } io_req = (struct fnic_io_req *)CMD_SP(sc); @@ -1426,16 +1433,19 @@ void fnic_terminate_rport_io(struct fc_rport *rport) for (tag = 0; tag FNIC_MAX_IO_REQ; tag++) { abt_tag = tag; + io_lock = fnic_io_lock_tag(fnic, tag); + spin_lock_irqsave(io_lock, flags); sc = scsi_host_find_tag(fnic-lport-host, tag); - if (!sc) + if (!sc) { + spin_unlock_irqrestore(io_lock, flags); continue; + } cmd_rport = starget_to_rport(scsi_target(sc-device)); - if (rport != cmd_rport) + if (rport != cmd_rport) { + spin_unlock_irqrestore(io_lock, flags); continue; - - io_lock = fnic_io_lock_hash(fnic, sc); - spin_lock_irqsave(io_lock, flags); + } io_req = (struct fnic_io_req *)CMD_SP(sc); @@ -1648,13 +1658,15 @@ int fnic_abort_cmd(struct scsi_cmnd *sc) io_req-abts_done = NULL; /* fw did not complete abort, timed out */ - if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) { + if (CMD_ABTS_STATUS(sc) == FCPIO_INVALID_CODE) { spin_unlock_irqrestore(io_lock, flags); CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_TIMED_OUT; ret = FAILED; goto fnic_abort_cmd_end; } + CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE; + /* * firmware completed the abort, check the status, * free the io_req irrespective of failure or success
[PATCH 9/9] fnic: Incremented driver version
Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index db7a950..528d43b 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -39,7 +39,7 @@ #define DRV_NAME fnic #define DRV_DESCRIPTIONCisco FCoE HBA Driver -#define DRV_VERSION1.5.0.23 +#define DRV_VERSION1.5.0.45 #define PFXDRV_NAME : #define DFX DRV_NAME %d: -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/9] fnic: Kernel panic while running sh/nosh with max lun cfg
From: Sesidhar Beddel sebad...@cisco.com Kernel panics due to NULL lport while executing the log message because of synchronization issues between libfc and scsi transport fc. Checking for NULL pointers at the beginning of this routine would resolve the issue from kernel panic point of view. Signed-off-by: Sesidhar Baddel sebad...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_scsi.c | 23 --- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index 100cdba..b1d1921 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -1416,12 +1416,29 @@ void fnic_terminate_rport_io(struct fc_rport *rport) unsigned long flags; struct scsi_cmnd *sc; struct scsi_lun fc_lun; - struct fc_rport_libfc_priv *rdata = rport-dd_data; - struct fc_lport *lport = rdata-local_port; - struct fnic *fnic = lport_priv(lport); + struct fc_rport_libfc_priv *rdata; + struct fc_lport *lport; + struct fnic *fnic; struct fc_rport *cmd_rport; enum fnic_ioreq_state old_ioreq_state; + if (!rport) { + printk(KERN_ERR fnic_terminate_rport_io: rport is NULL\n); + return; + } + rdata = rport-dd_data; + + if (!rdata) { + printk(KERN_ERR fnic_terminate_rport_io: rdata is NULL\n); + return; + } + lport = rdata-local_port; + + if (!lport) { + printk(KERN_ERR fnic_terminate_rport_io: lport is NULL\n); + return; + } + fnic = lport_priv(lport); FNIC_SCSI_DBG(KERN_DEBUG, fnic-lport-host, fnic_terminate_rport_io called wwpn 0x%llx, wwnn0x%llx, rport 0x%p, portid 0x%06x\n, -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/9] fnic: FC stat param seconds_since_last_reset not getting updated
From: Narsimhulu Musini nmus...@cisco.com Code to reset fc_host statistics. echo 1 /sys/class/fc_host/hostX/statistics/reset_statistics clears fc_host stats, the code also issues command to fnic firmware to clear vnic stats. Signed-off-by: Narsimhulu Musini nmus...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h |5 ++ drivers/scsi/fnic/fnic_main.c | 108 - 2 files changed, 112 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index c18c681..d276aaf 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -154,6 +154,9 @@ do { \ FNIC_CHECK_LOGGING(FNIC_ISR_LOGGING,\ shost_printk(kern_level, host, fmt, ##args);) +#define FNIC_MAIN_NOTE(kern_level, host, fmt, args...) \ + shost_printk(kern_level, host, fmt, ##args) + extern const char *fnic_state_str[]; enum fnic_intx_intr_index { @@ -215,6 +218,7 @@ struct fnic { struct vnic_stats *stats; unsigned long stats_time; /* time of stats update */ + unsigned long stats_reset_time; /* time of stats reset */ struct vnic_nic_cfg *nic_cfg; char name[IFNAMSIZ]; struct timer_list notify_timer; /* used for MSI interrupts */ @@ -359,4 +363,5 @@ fnic_chk_state_flags_locked(struct fnic *fnic, unsigned long st_flags) return ((fnic-state_flags st_flags) == st_flags); } void __fnic_set_state_flags(struct fnic *, unsigned long, unsigned long); +void fnic_dump_fchost_stats(struct Scsi_Host *, struct fc_host_statistics *); #endif /* _FNIC_H_ */ diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index 42e15ee..b619dab 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c @@ -126,6 +126,7 @@ fnic_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout) static void fnic_get_host_speed(struct Scsi_Host *shost); static struct scsi_transport_template *fnic_fc_transport; static struct fc_host_statistics *fnic_get_stats(struct Scsi_Host *); +static void fnic_reset_host_stats(struct Scsi_Host *); static struct fc_function_template fnic_fc_functions = { @@ -153,6 +154,7 @@ static struct fc_function_template fnic_fc_functions = { .set_rport_dev_loss_tmo = fnic_set_rport_dev_loss_tmo, .issue_fc_host_lip = fnic_reset, .get_fc_host_stats = fnic_get_stats, + .reset_fc_host_stats = fnic_reset_host_stats, .dd_fcrport_size = sizeof(struct fc_rport_libfc_priv), .terminate_rport_io = fnic_terminate_rport_io, .bsg_request = fc_lport_bsg_request, @@ -206,13 +208,116 @@ static struct fc_host_statistics *fnic_get_stats(struct Scsi_Host *host) stats-error_frames = vs-tx.tx_errors + vs-rx.rx_errors; stats-dumped_frames = vs-tx.tx_drops + vs-rx.rx_drop; stats-invalid_crc_count = vs-rx.rx_crc_errors; - stats-seconds_since_last_reset = (jiffies - lp-boot_time) / HZ; + stats-seconds_since_last_reset = + (jiffies - fnic-stats_reset_time) / HZ; stats-fcp_input_megabytes = div_u64(fnic-fcp_input_bytes, 100); stats-fcp_output_megabytes = div_u64(fnic-fcp_output_bytes, 100); return stats; } +/* + * fnic_dump_fchost_stats + * note : dumps fc_statistics into system logs + */ +void fnic_dump_fchost_stats(struct Scsi_Host *host, + struct fc_host_statistics *stats) +{ + FNIC_MAIN_NOTE(KERN_NOTICE, host, + fnic: seconds since last reset = %llu\n, + stats-seconds_since_last_reset); + FNIC_MAIN_NOTE(KERN_NOTICE, host, + fnic: tx frames= %llu\n, + stats-tx_frames); + FNIC_MAIN_NOTE(KERN_NOTICE, host, + fnic: tx words = %llu\n, + stats-tx_words); + FNIC_MAIN_NOTE(KERN_NOTICE, host, + fnic: rx frames= %llu\n, + stats-rx_frames); + FNIC_MAIN_NOTE(KERN_NOTICE, host, + fnic: rx words = %llu\n, + stats-rx_words); + FNIC_MAIN_NOTE(KERN_NOTICE, host, + fnic: lip count= %llu\n, + stats-lip_count); + FNIC_MAIN_NOTE(KERN_NOTICE, host, + fnic: nos count= %llu\n, + stats-nos_count); + FNIC_MAIN_NOTE(KERN_NOTICE, host, + fnic: error frames = %llu\n, + stats-error_frames); + FNIC_MAIN_NOTE(KERN_NOTICE, host, + fnic: dumped frames= %llu\n, + stats-dumped_frames); + FNIC_MAIN_NOTE(KERN_NOTICE, host
[PATCH 7/9] fnic: fnic Driver Tuneables Exposed through CLI
Introduced module params to provide dynamic way of configuring queue depth. Added support to get max io throttle count through UCSM to configure maximum outstanding IOs supported by fnic and push that value to scsi mid-layer. Supported IO throttle values: UCSM IO THROTTLE VALUEFNIC MAX OUTSTANDING IOS -- 16 (Default)2048 = 256 256 256 ucsm value Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h |3 +++ drivers/scsi/fnic/fnic_main.c | 29 + drivers/scsi/fnic/fnic_scsi.c | 16 drivers/scsi/fnic/vnic_scsi.h |4 ++-- 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index d276aaf..e4dd3d7 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -43,6 +43,8 @@ #define DFX DRV_NAME %d: #define DESC_CLEAN_LOW_WATERMARK 8 +#define FNIC_UCSM_DFLT_THROTTLE_CNT_BLD16 /* UCSM default throttle count */ +#define FNIC_MIN_IO_REQ256 /* Min IO throttle count */ #define FNIC_MAX_IO_REQ2048 /* scsi_cmnd tag map entries */ #defineFNIC_IO_LOCKS 64 /* IO locks: power of 2 */ #define FNIC_DFLT_QUEUE_DEPTH 32 @@ -223,6 +225,7 @@ struct fnic { char name[IFNAMSIZ]; struct timer_list notify_timer; /* used for MSI interrupts */ + unsigned int fnic_max_tag_id; unsigned int err_intr_offset; unsigned int link_intr_offset; diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index 835a9cd..bbf81ea 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c @@ -74,6 +74,10 @@ module_param(fnic_trace_max_pages, uint, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(fnic_trace_max_pages, Total allocated memory pages for fnic trace buffer); +static unsigned int fnic_max_qdepth = FNIC_DFLT_QUEUE_DEPTH; +module_param(fnic_max_qdepth, uint, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(fnic_max_qdepth, Queue depth to report for each LUN); + static struct libfc_function_template fnic_transport_template = { .frame_send = fnic_send, .lport_set_port_id = fnic_set_port_id, @@ -91,7 +95,7 @@ static int fnic_slave_alloc(struct scsi_device *sdev) if (!rport || fc_remote_port_chkready(rport)) return -ENXIO; - scsi_activate_tcq(sdev, FNIC_DFLT_QUEUE_DEPTH); + scsi_activate_tcq(sdev, fnic_max_qdepth); return 0; } @@ -552,13 +556,6 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) host-transportt = fnic_fc_transport; - err = scsi_init_shared_tag_map(host, FNIC_MAX_IO_REQ); - if (err) { - shost_printk(KERN_ERR, fnic-lport-host, -Unable to alloc shared tag map\n); - goto err_out_free_hba; - } - /* Setup PCI resources */ pci_set_drvdata(pdev, fnic); @@ -671,6 +668,22 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) aborting.\n); goto err_out_dev_close; } + + /* Configure Maximum Outstanding IO reqs*/ + if (fnic-config.io_throttle_count != FNIC_UCSM_DFLT_THROTTLE_CNT_BLD) { + host-can_queue = min_t(u32, FNIC_MAX_IO_REQ, + max_t(u32, FNIC_MIN_IO_REQ, + fnic-config.io_throttle_count)); + } + fnic-fnic_max_tag_id = host-can_queue; + + err = scsi_init_shared_tag_map(host, fnic-fnic_max_tag_id); + if (err) { + shost_printk(KERN_ERR, fnic-lport-host, + Unable to alloc shared tag map\n); + goto err_out_dev_close; + } + host-max_lun = fnic-config.luns_per_tgt; host-max_id = FNIC_MAX_FCP_TARGET; host-max_cmd_len = FCOE_MAX_CMD_LEN; diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index b1d1921..fdb2b8b 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -736,7 +736,7 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic, fcpio_tag_id_dec(tag, id); icmnd_cmpl = desc-u.icmnd_cmpl; - if (id = FNIC_MAX_IO_REQ) { + if (id = fnic-fnic_max_tag_id) { shost_printk(KERN_ERR, fnic-lport-host, Tag out of range tag %x hdr status = %s\n, id, fnic_fcpio_status_to_str(hdr_status)); @@ -913,7 +913,7 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic, fcpio_header_dec(desc-hdr, type, hdr_status, tag); fcpio_tag_id_dec(tag, id); - if ((id FNIC_TAG_MASK) = FNIC_MAX_IO_REQ
[PATCH 4/9] fnic: Remove QUEUE_FULL handling code
From: Suma Ramars sram...@cisco.com Remove fnic driver QUEUE_FULL handling code instead let SCSI mid layer handle queue full and use its algorithm to ramp down/up queue Signed-off-by: Suma Ramars sram...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_scsi.c | 32 1 file changed, 32 deletions(-) diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index ef3c463..a09dd8d 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -818,38 +818,6 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic, if (icmnd_cmpl-flags FCPIO_ICMND_CMPL_RESID_UNDER) xfer_len -= icmnd_cmpl-residual; - /* -* If queue_full, then try to reduce queue depth for all -* LUNS on the target. Todo: this should be accompanied -* by a periodic queue_depth rampup based on successful -* IO completion. -*/ - if (icmnd_cmpl-scsi_status == QUEUE_FULL) { - struct scsi_device *t_sdev; - int qd = 0; - - shost_for_each_device(t_sdev, sc-device-host) { - if (t_sdev-id != sc-device-id) - continue; - - if (t_sdev-queue_depth 1) { - qd = scsi_track_queue_full - (t_sdev, -t_sdev-queue_depth - 1); - if (qd == -1) - qd = t_sdev-host-cmd_per_lun; - shost_printk(KERN_INFO, -fnic-lport-host, -scsi[%d:%d:%d:%d -] queue full detected, -new depth = %d\n, -t_sdev-host-host_no, -t_sdev-channel, -t_sdev-id, t_sdev-lun, -t_sdev-queue_depth); - } - } - } break; case FCPIO_TIMEOUT: /* request was timed out */ -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/9] fnic: FC stat param seconds_since_last_reset not getting updated
Hi James, Yes for this patch Narsimhulu Musini is the author of this patch. Thanks, Hiral On 9/6/13 10:35 AM, James Bottomley james.bottom...@hansenpartnership.com wrote: On Thu, 2013-08-29 at 10:57 -0700, Hiral Patel wrote: Code to reset fc_host statistics. echo 1 /sys/class/fc_host/hostX/statistics/reset_statistics clears fc_host stats, the code also issues command to fnic firmware to clear vnic stats. Signed-off-by: Narsimhulu Musini nmus...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com Explain this signoff order, please? It looks from this like Narsimhulu Musini should be the author? James -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 7/9] fnic: fnic Driver Tuneables Exposed through CLI
Introduced module params to provide dynamic way of configuring queue depth. Added support to get max io throttle count through UCSM to configure maximum outstanding IOs supported by fnic and push that value to scsi mid-layer. Supported IO throttle values: UCSM IO THROTTLE VALUEFNIC MAX OUTSTANDING IOS -- 16 (Default)2048 = 256 256 256 ucsm value Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h |3 +++ drivers/scsi/fnic/fnic_main.c | 29 + drivers/scsi/fnic/fnic_scsi.c | 16 drivers/scsi/fnic/vnic_scsi.h |4 ++-- 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index d276aaf..e4dd3d7 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -43,6 +43,8 @@ #define DFX DRV_NAME %d: #define DESC_CLEAN_LOW_WATERMARK 8 +#define FNIC_UCSM_DFLT_THROTTLE_CNT_BLD16 /* UCSM default throttle count */ +#define FNIC_MIN_IO_REQ256 /* Min IO throttle count */ #define FNIC_MAX_IO_REQ2048 /* scsi_cmnd tag map entries */ #defineFNIC_IO_LOCKS 64 /* IO locks: power of 2 */ #define FNIC_DFLT_QUEUE_DEPTH 32 @@ -223,6 +225,7 @@ struct fnic { char name[IFNAMSIZ]; struct timer_list notify_timer; /* used for MSI interrupts */ + unsigned int fnic_max_tag_id; unsigned int err_intr_offset; unsigned int link_intr_offset; diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index 835a9cd..bbf81ea 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c @@ -74,6 +74,10 @@ module_param(fnic_trace_max_pages, uint, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(fnic_trace_max_pages, Total allocated memory pages for fnic trace buffer); +static unsigned int fnic_max_qdepth = FNIC_DFLT_QUEUE_DEPTH; +module_param(fnic_max_qdepth, uint, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(fnic_max_qdepth, Queue depth to report for each LUN); + static struct libfc_function_template fnic_transport_template = { .frame_send = fnic_send, .lport_set_port_id = fnic_set_port_id, @@ -91,7 +95,7 @@ static int fnic_slave_alloc(struct scsi_device *sdev) if (!rport || fc_remote_port_chkready(rport)) return -ENXIO; - scsi_activate_tcq(sdev, FNIC_DFLT_QUEUE_DEPTH); + scsi_activate_tcq(sdev, fnic_max_qdepth); return 0; } @@ -552,13 +556,6 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) host-transportt = fnic_fc_transport; - err = scsi_init_shared_tag_map(host, FNIC_MAX_IO_REQ); - if (err) { - shost_printk(KERN_ERR, fnic-lport-host, -Unable to alloc shared tag map\n); - goto err_out_free_hba; - } - /* Setup PCI resources */ pci_set_drvdata(pdev, fnic); @@ -671,6 +668,22 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) aborting.\n); goto err_out_dev_close; } + + /* Configure Maximum Outstanding IO reqs*/ + if (fnic-config.io_throttle_count != FNIC_UCSM_DFLT_THROTTLE_CNT_BLD) { + host-can_queue = min_t(u32, FNIC_MAX_IO_REQ, + max_t(u32, FNIC_MIN_IO_REQ, + fnic-config.io_throttle_count)); + } + fnic-fnic_max_tag_id = host-can_queue; + + err = scsi_init_shared_tag_map(host, fnic-fnic_max_tag_id); + if (err) { + shost_printk(KERN_ERR, fnic-lport-host, + Unable to alloc shared tag map\n); + goto err_out_dev_close; + } + host-max_lun = fnic-config.luns_per_tgt; host-max_id = FNIC_MAX_FCP_TARGET; host-max_cmd_len = FCOE_MAX_CMD_LEN; diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index b1d1921..fdb2b8b 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -736,7 +736,7 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic, fcpio_tag_id_dec(tag, id); icmnd_cmpl = desc-u.icmnd_cmpl; - if (id = FNIC_MAX_IO_REQ) { + if (id = fnic-fnic_max_tag_id) { shost_printk(KERN_ERR, fnic-lport-host, Tag out of range tag %x hdr status = %s\n, id, fnic_fcpio_status_to_str(hdr_status)); @@ -913,7 +913,7 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic, fcpio_header_dec(desc-hdr, type, hdr_status, tag); fcpio_tag_id_dec(tag, id); - if ((id FNIC_TAG_MASK) = FNIC_MAX_IO_REQ
[PATCH 3/9] fnic: On system with 1.1TB RAM, VIC fails multipath after boot up
Issue was seen when SCSI buffer address is more than 40 bits in system with more than 1.1TB RAM. When SCSI buffer is passed to VIC, it is failing to map to correct buffer address, as DMA mask is set to 40 bits in driver initialization. Corrected DMA_MASK from 40-bits to 64-bits to avoid masking 41-64 bits addresses. Signed-off-by: Brian Uchino buch...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_main.c |8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index b619dab..835a9cd 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c @@ -581,10 +581,10 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_master(pdev); /* Query PCI controller on system for DMA addressing -* limitation for the device. Try 40-bit first, and +* limitation for the device. Try 64-bit first, and * fail to 32-bit. */ - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(40)); + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); if (err) { err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (err) { @@ -601,10 +601,10 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_release_regions; } } else { - err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(40)); + err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); if (err) { shost_printk(KERN_ERR, fnic-lport-host, -Unable to obtain 40-bit DMA +Unable to obtain 64-bit DMA for consistent allocations, aborting.\n); goto err_out_release_regions; } -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 9/9] fnic: Incremented driver version
Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index db7a950..528d43b 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -39,7 +39,7 @@ #define DRV_NAME fnic #define DRV_DESCRIPTIONCisco FCoE HBA Driver -#define DRV_VERSION1.5.0.23 +#define DRV_VERSION1.5.0.45 #define PFXDRV_NAME : #define DFX DRV_NAME %d: -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/9] fnic: Kernel panic while running sh/nosh with max lun cfg
Kernel panics due to NULL lport while executing the log message because of synchronization issues between libfc and scsi transport fc. Checking for NULL pointers at the beginning of this routine would resolve the issue from kernel panic point of view. Signed-off-by: Sesidhar Baddel sebad...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_scsi.c | 23 --- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index 100cdba..b1d1921 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -1416,12 +1416,29 @@ void fnic_terminate_rport_io(struct fc_rport *rport) unsigned long flags; struct scsi_cmnd *sc; struct scsi_lun fc_lun; - struct fc_rport_libfc_priv *rdata = rport-dd_data; - struct fc_lport *lport = rdata-local_port; - struct fnic *fnic = lport_priv(lport); + struct fc_rport_libfc_priv *rdata; + struct fc_lport *lport; + struct fnic *fnic; struct fc_rport *cmd_rport; enum fnic_ioreq_state old_ioreq_state; + if (!rport) { + printk(KERN_ERR fnic_terminate_rport_io: rport is NULL\n); + return; + } + rdata = rport-dd_data; + + if (!rdata) { + printk(KERN_ERR fnic_terminate_rport_io: rdata is NULL\n); + return; + } + lport = rdata-local_port; + + if (!lport) { + printk(KERN_ERR fnic_terminate_rport_io: lport is NULL\n); + return; + } + fnic = lport_priv(lport); FNIC_SCSI_DBG(KERN_DEBUG, fnic-lport-host, fnic_terminate_rport_io called wwpn 0x%llx, wwnn0x%llx, rport 0x%p, portid 0x%06x\n, -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/9] fnic: Hitting BUG_ON(io_req-abts_done) in fnic_rport_exch_reset
Hitting BUG_ON(io_req-abts_done) in fnic_rport_exch_reset in case of timing issue and also to some extent locking issue where abts and terminate is happening around same timing. The code changes are intended to update CMD_STATE(sc) and io_req-abts_done together. Signed-off-by: Sesidhar Beddel sebad...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_scsi.c | 70 - 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index a09dd8d..100cdba 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -111,6 +111,12 @@ static inline spinlock_t *fnic_io_lock_hash(struct fnic *fnic, return fnic-io_req_lock[hash]; } +static inline spinlock_t *fnic_io_lock_tag(struct fnic *fnic, + int tag) +{ + return fnic-io_req_lock[tag (FNIC_IO_LOCKS - 1)]; +} + /* * Unmap the data buffer and sense buffer for an io_req, * also unmap and free the device-private scatter/gather list. @@ -956,9 +962,7 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic, spin_unlock_irqrestore(io_lock, flags); return; } - CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE; CMD_ABTS_STATUS(sc) = hdr_status; - CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_DONE; FNIC_SCSI_DBG(KERN_DEBUG, fnic-lport-host, abts cmpl recd. id %d status %s\n, @@ -1116,7 +1120,7 @@ int fnic_wq_copy_cmpl_handler(struct fnic *fnic, int copy_work_to_do) static void fnic_cleanup_io(struct fnic *fnic, int exclude_id) { - unsigned int i; + int i; struct fnic_io_req *io_req; unsigned long flags = 0; struct scsi_cmnd *sc; @@ -1127,12 +1131,14 @@ static void fnic_cleanup_io(struct fnic *fnic, int exclude_id) if (i == exclude_id) continue; + io_lock = fnic_io_lock_tag(fnic, i); + spin_lock_irqsave(io_lock, flags); sc = scsi_host_find_tag(fnic-lport-host, i); - if (!sc) + if (!sc) { + spin_unlock_irqrestore(io_lock, flags); continue; + } - io_lock = fnic_io_lock_hash(fnic, sc); - spin_lock_irqsave(io_lock, flags); io_req = (struct fnic_io_req *)CMD_SP(sc); if ((CMD_FLAGS(sc) FNIC_DEVICE_RESET) !(CMD_FLAGS(sc) FNIC_DEV_RST_DONE)) { @@ -1310,12 +1316,13 @@ static void fnic_rport_exch_reset(struct fnic *fnic, u32 port_id) for (tag = 0; tag FNIC_MAX_IO_REQ; tag++) { abt_tag = tag; + io_lock = fnic_io_lock_tag(fnic, tag); + spin_lock_irqsave(io_lock, flags); sc = scsi_host_find_tag(fnic-lport-host, tag); - if (!sc) + if (!sc) { + spin_unlock_irqrestore(io_lock, flags); continue; - - io_lock = fnic_io_lock_hash(fnic, sc); - spin_lock_irqsave(io_lock, flags); + } io_req = (struct fnic_io_req *)CMD_SP(sc); @@ -1426,16 +1433,19 @@ void fnic_terminate_rport_io(struct fc_rport *rport) for (tag = 0; tag FNIC_MAX_IO_REQ; tag++) { abt_tag = tag; + io_lock = fnic_io_lock_tag(fnic, tag); + spin_lock_irqsave(io_lock, flags); sc = scsi_host_find_tag(fnic-lport-host, tag); - if (!sc) + if (!sc) { + spin_unlock_irqrestore(io_lock, flags); continue; + } cmd_rport = starget_to_rport(scsi_target(sc-device)); - if (rport != cmd_rport) + if (rport != cmd_rport) { + spin_unlock_irqrestore(io_lock, flags); continue; - - io_lock = fnic_io_lock_hash(fnic, sc); - spin_lock_irqsave(io_lock, flags); + } io_req = (struct fnic_io_req *)CMD_SP(sc); @@ -1648,13 +1658,15 @@ int fnic_abort_cmd(struct scsi_cmnd *sc) io_req-abts_done = NULL; /* fw did not complete abort, timed out */ - if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) { + if (CMD_ABTS_STATUS(sc) == FCPIO_INVALID_CODE) { spin_unlock_irqrestore(io_lock, flags); CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_TIMED_OUT; ret = FAILED; goto fnic_abort_cmd_end; } + CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE; + /* * firmware completed the abort, check the status, * free the io_req irrespective of failure or success @@ -1753,16 +1765,17 @@ static int
[PATCH 1/9] fnic: FC stat param seconds_since_last_reset not getting updated
Code to reset fc_host statistics. echo 1 /sys/class/fc_host/hostX/statistics/reset_statistics clears fc_host stats, the code also issues command to fnic firmware to clear vnic stats. Signed-off-by: Narsimhulu Musini nmus...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h |5 ++ drivers/scsi/fnic/fnic_main.c | 108 - 2 files changed, 112 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index c18c681..d276aaf 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -154,6 +154,9 @@ do { \ FNIC_CHECK_LOGGING(FNIC_ISR_LOGGING,\ shost_printk(kern_level, host, fmt, ##args);) +#define FNIC_MAIN_NOTE(kern_level, host, fmt, args...) \ + shost_printk(kern_level, host, fmt, ##args) + extern const char *fnic_state_str[]; enum fnic_intx_intr_index { @@ -215,6 +218,7 @@ struct fnic { struct vnic_stats *stats; unsigned long stats_time; /* time of stats update */ + unsigned long stats_reset_time; /* time of stats reset */ struct vnic_nic_cfg *nic_cfg; char name[IFNAMSIZ]; struct timer_list notify_timer; /* used for MSI interrupts */ @@ -359,4 +363,5 @@ fnic_chk_state_flags_locked(struct fnic *fnic, unsigned long st_flags) return ((fnic-state_flags st_flags) == st_flags); } void __fnic_set_state_flags(struct fnic *, unsigned long, unsigned long); +void fnic_dump_fchost_stats(struct Scsi_Host *, struct fc_host_statistics *); #endif /* _FNIC_H_ */ diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index 42e15ee..b619dab 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c @@ -126,6 +126,7 @@ fnic_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout) static void fnic_get_host_speed(struct Scsi_Host *shost); static struct scsi_transport_template *fnic_fc_transport; static struct fc_host_statistics *fnic_get_stats(struct Scsi_Host *); +static void fnic_reset_host_stats(struct Scsi_Host *); static struct fc_function_template fnic_fc_functions = { @@ -153,6 +154,7 @@ static struct fc_function_template fnic_fc_functions = { .set_rport_dev_loss_tmo = fnic_set_rport_dev_loss_tmo, .issue_fc_host_lip = fnic_reset, .get_fc_host_stats = fnic_get_stats, + .reset_fc_host_stats = fnic_reset_host_stats, .dd_fcrport_size = sizeof(struct fc_rport_libfc_priv), .terminate_rport_io = fnic_terminate_rport_io, .bsg_request = fc_lport_bsg_request, @@ -206,13 +208,116 @@ static struct fc_host_statistics *fnic_get_stats(struct Scsi_Host *host) stats-error_frames = vs-tx.tx_errors + vs-rx.rx_errors; stats-dumped_frames = vs-tx.tx_drops + vs-rx.rx_drop; stats-invalid_crc_count = vs-rx.rx_crc_errors; - stats-seconds_since_last_reset = (jiffies - lp-boot_time) / HZ; + stats-seconds_since_last_reset = + (jiffies - fnic-stats_reset_time) / HZ; stats-fcp_input_megabytes = div_u64(fnic-fcp_input_bytes, 100); stats-fcp_output_megabytes = div_u64(fnic-fcp_output_bytes, 100); return stats; } +/* + * fnic_dump_fchost_stats + * note : dumps fc_statistics into system logs + */ +void fnic_dump_fchost_stats(struct Scsi_Host *host, + struct fc_host_statistics *stats) +{ + FNIC_MAIN_NOTE(KERN_NOTICE, host, + fnic: seconds since last reset = %llu\n, + stats-seconds_since_last_reset); + FNIC_MAIN_NOTE(KERN_NOTICE, host, + fnic: tx frames= %llu\n, + stats-tx_frames); + FNIC_MAIN_NOTE(KERN_NOTICE, host, + fnic: tx words = %llu\n, + stats-tx_words); + FNIC_MAIN_NOTE(KERN_NOTICE, host, + fnic: rx frames= %llu\n, + stats-rx_frames); + FNIC_MAIN_NOTE(KERN_NOTICE, host, + fnic: rx words = %llu\n, + stats-rx_words); + FNIC_MAIN_NOTE(KERN_NOTICE, host, + fnic: lip count= %llu\n, + stats-lip_count); + FNIC_MAIN_NOTE(KERN_NOTICE, host, + fnic: nos count= %llu\n, + stats-nos_count); + FNIC_MAIN_NOTE(KERN_NOTICE, host, + fnic: error frames = %llu\n, + stats-error_frames); + FNIC_MAIN_NOTE(KERN_NOTICE, host, + fnic: dumped frames= %llu\n, + stats-dumped_frames); + FNIC_MAIN_NOTE(KERN_NOTICE, host, + fnic: link failure count
[PATCH 4/9] fnic: Remove QUEUE_FULL handling code
Remove fnic driver QUEUE_FULL handling code instead let SCSI mid layer handle queue full and use its algorithm to ramp down/up queue Signed-off-by: Suma Ramars sram...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_scsi.c | 32 1 file changed, 32 deletions(-) diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index ef3c463..a09dd8d 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -818,38 +818,6 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic, if (icmnd_cmpl-flags FCPIO_ICMND_CMPL_RESID_UNDER) xfer_len -= icmnd_cmpl-residual; - /* -* If queue_full, then try to reduce queue depth for all -* LUNS on the target. Todo: this should be accompanied -* by a periodic queue_depth rampup based on successful -* IO completion. -*/ - if (icmnd_cmpl-scsi_status == QUEUE_FULL) { - struct scsi_device *t_sdev; - int qd = 0; - - shost_for_each_device(t_sdev, sc-device-host) { - if (t_sdev-id != sc-device-id) - continue; - - if (t_sdev-queue_depth 1) { - qd = scsi_track_queue_full - (t_sdev, -t_sdev-queue_depth - 1); - if (qd == -1) - qd = t_sdev-host-cmd_per_lun; - shost_printk(KERN_INFO, -fnic-lport-host, -scsi[%d:%d:%d:%d -] queue full detected, -new depth = %d\n, -t_sdev-host-host_no, -t_sdev-channel, -t_sdev-id, t_sdev-lun, -t_sdev-queue_depth); - } - } - } break; case FCPIO_TIMEOUT: /* request was timed out */ -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/9] fnic: host reset returns nonzero value(errno) on success
Fixed appropriate error codes that returns -1 on failure, and 0 on success Signed-off-by: Narsimhulu Musini nmus...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_scsi.c |8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index a97e6e5..ef3c463 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -2208,7 +2208,7 @@ int fnic_reset(struct Scsi_Host *shost) { struct fc_lport *lp; struct fnic *fnic; - int ret = SUCCESS; + int ret = 0; lp = shost_priv(shost); fnic = lport_priv(lp); @@ -2221,11 +2221,11 @@ int fnic_reset(struct Scsi_Host *shost) * reset remote port sessions, and if link is up, begin flogi */ if (lp-tt.lport_reset(lp)) - ret = FAILED; + ret = -1; FNIC_SCSI_DBG(KERN_DEBUG, fnic-lport-host, Returning from fnic reset %s\n, - (ret == SUCCESS) ? + (ret == 0) ? SUCCESS : FAILED); return ret; @@ -2252,7 +2252,7 @@ int fnic_host_reset(struct scsi_cmnd *sc) * scsi-ml tries to send a TUR to every device if host reset is * successful, so before returning to scsi, fabric should be up */ - ret = fnic_reset(shost); + ret = (fnic_reset(shost) == 0) ? SUCCESS : FAILED; if (ret == SUCCESS) { wait_host_tmo = jiffies + FNIC_HOST_RESET_SETTLE_TIME * HZ; ret = FAILED; -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] fnic: BUG: sleeping function called from invalid context during probe
FIP work queue - create failed\n); - err = -ENOMEM; - goto err_out_free_max_pool; - } - } - spin_unlock_irqrestore(fnic_list_lock, flags); INIT_LIST_HEAD(fnic-evlist); INIT_LIST_HEAD(fnic-vlans); } else { @@ -960,6 +947,13 @@ static int __init fnic_init_module(void) spin_lock_init(fnic_list_lock); INIT_LIST_HEAD(fnic_list); + fnic_fip_queue = create_singlethread_workqueue(fnic_fip_q); + if (!fnic_fip_queue) { + printk(KERN_ERR PFX fnic FIP work queue create failed\n); + err = -ENOMEM; + goto err_create_fip_workq; + } + fnic_fc_transport = fc_attach_transport(fnic_fc_functions); if (!fnic_fc_transport) { printk(KERN_ERR PFX fc_attach_transport error\n); @@ -978,6 +972,8 @@ static int __init fnic_init_module(void) err_pci_register: fc_release_transport(fnic_fc_transport); err_fc_transport: + destroy_workqueue(fnic_fip_queue); +err_create_fip_workq: destroy_workqueue(fnic_event_queue); err_create_fnic_workq: kmem_cache_destroy(fnic_io_req_cache); -- 1.8.1.4 Tested-by: Anantha Tungarakodi atung...@cisco.com Acked-by: Hiral Patel hiral...@cisco.com -Hiral -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] fnic: use simple_open instead of fnic_trace_ctrl_open
On 7/11/13 11:50 PM, Camelia Groza camelia.gr...@gmail.com wrote: This removes the open coded fnic_trace_ctrl_open() function and replaces file operations references to the function with simple_open() instead. Found using coccinelle. Signed-off-by: Camelia Groza camelia.gr...@gmail.com --- drivers/scsi/fnic/fnic_debugfs.c | 19 +-- 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/drivers/scsi/fnic/fnic_debugfs.c b/drivers/scsi/fnic/fnic_debugfs.c index cbcb012..ddc7e94 100644 --- a/drivers/scsi/fnic/fnic_debugfs.c +++ b/drivers/scsi/fnic/fnic_debugfs.c @@ -25,23 +25,6 @@ static struct dentry *fnic_trace_debugfs_file; static struct dentry *fnic_trace_enable; /* - * fnic_trace_ctrl_open - Open the trace_enable file - * @inode: The inode pointer. - * @file: The file pointer to attach the trace enable/disable flag. - * - * Description: - * This routine opens a debugsfs file trace_enable. - * - * Returns: - * This function returns zero if successful. - */ -static int fnic_trace_ctrl_open(struct inode *inode, struct file *filp) -{ - filp-private_data = inode-i_private; - return 0; -} - -/* * fnic_trace_ctrl_read - Read a trace_enable debugfs file * @filp: The file pointer to read from. * @ubuf: The buffer to copy the data to. @@ -222,7 +205,7 @@ static int fnic_trace_debugfs_release(struct inode *inode, static const struct file_operations fnic_trace_ctrl_fops = { .owner = THIS_MODULE, - .open = fnic_trace_ctrl_open, + .open = simple_open, .read = fnic_trace_ctrl_read, .write = fnic_trace_ctrl_write, }; -- 1.7.10.4 Acked-by: Hiral Patel hiral...@cisco.com -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [patch] [SCSI] fnic: potential dead lock in fnic_is_abts_pending()
On 5/30/13 12:50 AM, Dan Carpenter dan.carpen...@oracle.com wrote: There is an unlock missing if the == FNIC_IOREQ_ABTS_PENDING is false. Signed-off-by: Dan Carpenter dan.carpen...@oracle.com --- Static analysis. I can't test this. diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index be99e75..a97e6e5 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -2432,11 +2432,9 @@ int fnic_is_abts_pending(struct fnic *fnic, struct scsi_cmnd *lr_sc) Found IO in %s on lun\n, fnic_ioreq_state_to_str(CMD_STATE(sc))); - if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) { - spin_unlock_irqrestore(io_lock, flags); + if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) ret = 1; - continue; - } + spin_unlock_irqrestore(io_lock, flags); } return ret; Tested-by: Hiral Patel hiral...@cisco.com Acked-by: Hiral Patel hiral...@cisco.com -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] fnic: Kernel panic due to FIP mode misconfiguration
If switch configured in FIP and adapter configured in non-fip mode, driver panics while queueing FIP frame in non-existing fip_frame_queue. Added config check before queueing FIP frame in misconfiguration case to avoid kernel panic. Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_fcs.c |6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c index 41faca4..a0092e8 100644 --- a/drivers/scsi/fnic/fnic_fcs.c +++ b/drivers/scsi/fnic/fnic_fcs.c @@ -603,6 +603,12 @@ static inline int fnic_import_rq_eth_pkt(struct fnic *fnic, struct sk_buff *skb) skb_reset_mac_header(skb); } if (eh-h_proto == htons(ETH_P_FIP)) { + if (!(fnic-config.flags VFCF_FIP_CAPABLE)) { + printk(KERN_ERR Dropped FIP frame, as firmware + uses non-FIP mode, Enable FIP + using UCSM\n); + goto drop; + } skb_queue_tail(fnic-fip_frame_queue, skb); queue_work(fnic_fip_queue, fnic-fip_frame_work); return 1; /* let caller know packet was used */ -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] fnic: Incremented driver version
Incrementing driver versio after bug fixes and new feature commits. Signed-off-by: Brian Uchino buch...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index acec42a..b6d1f92 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -38,7 +38,7 @@ #define DRV_NAME fnic #define DRV_DESCRIPTIONCisco FCoE HBA Driver -#define DRV_VERSION1.5.0.2 +#define DRV_VERSION1.5.0.22 #define PFXDRV_NAME : #define DFX DRV_NAME %d: -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] fnic: FIP VLAN Discovery Feature Support
FIP VLAN discovery discovers the FCoE VLAN that will be used by all other FIP protocols as well as by the FCoE encapsulation for Fibre Channel payloads on the established virtual link. One of the goals of FC-BB-5 was to be as nonintrusive as possible on initiators and targets, and therefore FIP VLAN discovery occurs in the native VLAN used by the initiator or target to exchange Ethernet traffic. The FIP VLAN discovery protocol is the only FIP protocol running on the native VLAN; all other FIP protocols run on the discovered FCoE VLANs. If an administrator has manually configured FCoE VLANs on ENodes and FCFs, there is no need to use this protocol. FIP and FCoE will run over the configured VLANs. An ENode without FCoE VLANs configuration would use this automated discovery protocol to discover over which VLANs FCoE is running. The ENode sends a FIP VLAN discovery request to a multicast MAC address called All-FCF-MACs, which is a multicast MAC address to which all FCFs listen. All FCFs that can be reached in the native VLAN of the ENode are expected to respond on the same VLAN with a response that lists one or more FCoE VLANs that are available for the ENode's VN_Port login. This protocol has the sole purpose of allowing the ENode to discover all the available FCoE VLANs. Now the ENode may enable a subset of these VLANs for FCoE Running the FIP protocol in these VLANs on a per VLAN basis. And FCoE data transactions also would occur on this VLAN. Hence, Except for FIP VLAN discovery, all other FIP and FCoE traffic runs on the selected FCoE VLAN. Its only the FIP VLAN Discovery protocol that is permitted to run on the Default native VLAN of the system. [ NOTE ] We are working on moving this feature definitions and functionality to libfcoe module. We need this patch to be approved, as Suse is looking forward to merge this feature in SLES 11 SP3 release. Once this patch is approved, we will submit patch which should move vlan discovery feature to libfoce. Signed-off-by: Anantha Prakash T atung...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h| 32 +++ drivers/scsi/fnic/fnic_fcs.c| 558 ++- drivers/scsi/fnic/fnic_fip.h| 68 + drivers/scsi/fnic/fnic_main.c | 51 +++- drivers/scsi/fnic/vnic_dev.c| 10 + drivers/scsi/fnic/vnic_dev.h|2 + drivers/scsi/fnic/vnic_devcmd.h | 67 + 7 files changed, 784 insertions(+), 4 deletions(-) create mode 100644 drivers/scsi/fnic/fnic_fip.h diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 98436c3..acec42a 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -192,6 +192,18 @@ enum fnic_state { struct mempool; +enum fnic_evt { + FNIC_EVT_START_VLAN_DISC = 1, + FNIC_EVT_START_FCF_DISC = 2, + FNIC_EVT_MAX, +}; + +struct fnic_event { + struct list_head list; + struct fnic *fnic; + enum fnic_evt event; +}; + /* Per-instance private data structure */ struct fnic { struct fc_lport *lport; @@ -254,6 +266,18 @@ struct fnic { struct sk_buff_head frame_queue; struct sk_buff_head tx_queue; + /*** FIP related data members -- start ***/ + void (*set_vlan)(struct fnic *, u16 vlan); + struct work_struct fip_frame_work; + struct sk_buff_head fip_frame_queue; + struct timer_list fip_timer; + struct list_headvlans; + spinlock_t vlans_lock; + + struct work_struct event_work; + struct list_headevlist; + /*** FIP related data members -- end ***/ + /* copy work queue cache line section */ cacheline_aligned struct vnic_wq_copy wq_copy[FNIC_WQ_COPY_MAX]; /* completion queue cache line section */ @@ -278,6 +302,7 @@ static inline struct fnic *fnic_from_ctlr(struct fcoe_ctlr *fip) } extern struct workqueue_struct *fnic_event_queue; +extern struct workqueue_struct *fnic_fip_queue; extern struct device_attribute *fnic_attrs[]; void fnic_clear_intr_mode(struct fnic *fnic); @@ -289,6 +314,7 @@ int fnic_send(struct fc_lport *, struct fc_frame *); void fnic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf); void fnic_handle_frame(struct work_struct *work); void fnic_handle_link(struct work_struct *work); +void fnic_handle_event(struct work_struct *work); int fnic_rq_cmpl_handler(struct fnic *fnic, int); int fnic_alloc_rq_frame(struct vnic_rq *rq); void fnic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf); @@ -321,6 +347,12 @@ void fnic_handle_link_event(struct fnic *fnic); int fnic_is_abts_pending(struct fnic *, struct scsi_cmnd *); +void fnic_handle_fip_frame(struct work_struct *work); +void fnic_handle_fip_event(struct fnic *fnic); +void fnic_fcoe_reset_vlans(struct fnic *fnic); +void fnic_fcoe_evlist_free(struct fnic *fnic); +extern void fnic_handle_fip_timer(struct fnic *fnic); + static
Re: [scsi:misc 102/104] drivers/scsi/fnic/fnic_fcs.c:381:31: sparse: cast to restricted __be16
Hey James, I have fixed FIP Vlan discovery patch for sparse warnings and resubmitted 3 pending patches. The patches 1-7 got committed to misc branch already has the fix for sparse and other problems. Thanks, Hiral On 2/24/13 12:18 AM, James Bottomley jbottom...@parallels.com wrote: On Sat, 2013-02-23 at 03:07 +0800, kbuild test robot wrote: tree: git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git misc head: c2983bd66114a8047bb74e4d347db8ffde381f71 commit: 5f0d0de727c055e15c2602e4905c6b75509ce9d7 [102/104] [SCSI] fnic: FIP VLAN Discovery Feature Support sparse warnings: (new ones prefixed by ) drivers/scsi/fnic/fnic_fcs.c:381:31: sparse: cast to restricted __be16 drivers/scsi/fnic/fnic_fcs.c:381:31: sparse: cast to restricted __be16 drivers/scsi/fnic/fnic_fcs.c:381:31: sparse: cast to restricted __be16 drivers/scsi/fnic/fnic_fcs.c:381:31: sparse: cast to restricted __be16 drivers/scsi/fnic/cq_enet_desc.h:142:39: sparse: restricted __le16 degrades to integer include/scsi/fc/fc_fcoe.h:101:36: sparse: cast truncates bits from constant value (efc becomes fc) include/scsi/fc/fc_fcoe.h:102:23: sparse: cast truncates bits from constant value (efc00 becomes 0) drivers/scsi/fnic/fnic_fcs.c:1198:6: sparse: context imbalance in 'fnic_handle_fip_timer' - different lock contexts for basic block vim +381 drivers/scsi/fnic/fnic_fcs.c 365 Received VLAN response...\n); 366 367 fiph = (struct fip_header *) skb-data; 368 369 FNIC_FCS_DBG(KERN_INFO, fnic-lport-host, 370 Received VLAN response... OP 0x%x SUB_OP 0x%x\n, 371 ntohs(fiph-fip_op), fiph-fip_subcode); 372 373 rlen = ntohs(fiph-fip_dl_len) * 4; 374 fnic_fcoe_reset_vlans(fnic); 375 spin_lock_irqsave(fnic-vlans_lock, flags); 376 desc = (struct fip_desc *)(fiph + 1); 377 while (rlen 0) { 378 dlen = desc-fip_dlen * FIP_BPW; 379 switch (desc-fip_dtype) { 380 case FIP_DT_VLAN: 381 vid = ntohs(((struct fip_vlan_desc *)desc)-fd_vlan); 382 shost_printk(KERN_INFO, fnic-lport-host, 383 process_vlan_resp: FIP VLAN %d\n, vid); 384 vlan = (struct fcoe_vlan *) kmalloc(sizeof(*vlan), 385 GFP_ATOMIC); 386 if (!vlan) { 387 /* retry from timer */ 388 spin_unlock_irqrestore(fnic-vlans_lock, 389 flags); OK, I'll drop the series from this patch on. I take it the sparse and other problems in the patches before this are all fixed? James -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 08/10] fnic: FIP VLAN Discovery Feature Support
Thanks James for the fix. -Hiral On 2/22/13 10:09 AM, James Bottomley jbottom...@parallels.com wrote: On Tue, 2013-02-12 at 17:01 -0800, Hiral Patel wrote: FIP VLAN discovery discovers the FCoE VLAN that will be used by all other FIP protocols as well as by the FCoE encapsulation for Fibre Channel payloads on the established virtual link. One of the goals of FC-BB-5 was to be as nonintrusive as possible on initiators and targets, and therefore FIP VLAN discovery occurs in the native VLAN used by the initiator or target to exchange Ethernet traffic. The FIP VLAN discovery protocol is the only FIP protocol running on the native VLAN; all other FIP protocols run on the discovered FCoE VLANs. If an administrator has manually configured FCoE VLANs on ENodes and FCFs, there is no need to use this protocol. FIP and FCoE will run over the configured VLANs. An ENode without FCoE VLANs configuration would use this automated discovery protocol to discover over which VLANs FCoE is running. The ENode sends a FIP VLAN discovery request to a multicast MAC address called All-FCF-MACs, which is a multicast MAC address to which all FCFs listen. All FCFs that can be reached in the native VLAN of the ENode are expected to respond on the same VLAN with a response that lists one or more FCoE VLANs that are available for the ENode's VN_Port login. This protocol has the sole purpose of allowing the ENode to discover all the available FCoE VLANs. Now the ENode may enable a subset of these VLANs for FCoE Running the FIP protocol in these VLANs on a per VLAN basis. And FCoE data transactions also would occur on this VLAN. Hence, Except for FIP VLAN discovery, all other FIP and FCoE traffic runs on the selected FCoE VLAN. Its only the FIP VLAN Discovery protocol that is permitted to run on the Default native VLAN of the system. [ NOTE ] We are working on moving this feature definitions and functionality to libfcoe module. We need this patch to be approved, as Suse is looking forward to merge this feature in SLES 11 SP3 release. Once this patch is approved, we will submit patch which should move vlan discovery feature to libfoce. Signed-off-by: Anantha Prakash T atung...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com This is still rejecting: jejb@dabdike patch -p1 .git/rebase-apply/patch patching file drivers/scsi/fnic/fnic.h patching file drivers/scsi/fnic/fnic_fcs.c patching file drivers/scsi/fnic/fnic_fip.h patching file drivers/scsi/fnic/fnic_main.c Hunk #3 FAILED at 411. Hunk #4 succeeded at 628 (offset -1 lines). Hunk #5 succeeded at 837 (offset -1 lines). Hunk #6 succeeded at 926 (offset -1 lines). Hunk #7 succeeded at 988 (offset -1 lines). 1 out of 7 hunks FAILED -- saving rejects to file drivers/scsi/fnic/fnic_main.c.rej The rejection is because of the __devinit removal patch that went into the 3.8 merge window. This definitely means you're not building with the misc branch of the scsi tree, which is based on 3.8-rc6. I fixed it up because we were making no progress otherwise. James -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/10] fnic:fixing issues in device and firmware reset code
1. Handling overlapped firmware resets This fix serialize multiple firmware resets to avoid situation where fnic device fails to come up for link up event, when firmware resets are issued back to back. If there are overlapped firmware resets are issued, the firmware reset operation checks whether there is any firmware reset in progress, if so it polls for its completion in a loop with 100ms delay. 2. Handling device reset timeout fnic_device_reset code has been modified to handle Device reset timeout: - Issue terminate on device reset timeout. - Introduced flags field (one of the scratch fields in scsi_cmnd). With this, device reset request would have DEVICE_RESET flag set for other routines to determine the type of the request. Also modified fnic_terminate_rport_io, fnic_rport_exch_rset, completion routines to handle SCSI commands with DEVICE_RESET flag. 3. LUN/Device Reset hangs when issued through IOCTL using utilities like sg_reset. Each SCSI command is associated with a valid tag, fnic uses this tag to retrieve associated scsi command on completion. the LUN/Device Reset issued through IOCTL resulting into a SCSI command that is not associated with a valid tag. So fnic fails to retrieve associated scsi command on completion, which causes hang. This fix allocates tag, associates it with the scsi command and frees the tag, when the operation completed. 4. Preventing IOs during firmware reset. Current fnic implementation allows IO submissions during firmware reset. This fix synchronizes IO submissions and firmware reset operations. It ensures that IOs issued to fnic prior to reset will be issued to the firmware before firmware reset. Signed-off-by: Narsimhulu Musini nmus...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h | 42 + drivers/scsi/fnic/fnic_main.c |3 + drivers/scsi/fnic/fnic_scsi.c | 384 + 3 files changed, 397 insertions(+), 32 deletions(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 95a5ba2..63b35c8 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -56,6 +56,19 @@ #define FNIC_NO_TAG -1 /* + * Command flags to identify the type of command and for other future + * use. + */ +#define FNIC_NO_FLAGS 0 +#define FNIC_CDB_REQ BIT(1) /* All IOs with a valid CDB */ +#define FNIC_BLOCKING_REQ BIT(2) /* All blocking Requests */ +#define FNIC_DEVICE_RESET BIT(3) /* Device reset request */ +#define FNIC_DEV_RST_PENDING BIT(4) /* Device reset pending */ +#define FNIC_DEV_RST_TIMED_OUT BIT(5) /* Device reset timed out */ +#define FNIC_DEV_RST_TERM_ISSUED BIT(6) /* Device reset terminate */ +#define FNIC_DEV_RST_DONE BIT(7) /* Device reset done */ + +/* * Usage of the scsi_cmnd scratchpad. * These fields are locked by the hashed io_req_lock. */ @@ -64,6 +77,7 @@ #define CMD_ABTS_STATUS(Cmnd) ((Cmnd)-SCp.Message) #define CMD_LR_STATUS(Cmnd)((Cmnd)-SCp.have_data_in) #define CMD_TAG(Cmnd) ((Cmnd)-SCp.sent_command) +#define CMD_FLAGS(Cmnd) ((Cmnd)-SCp.Status) #define FCPIO_INVALID_CODE 0x100 /* hdr_status value unused by firmware */ @@ -71,9 +85,28 @@ #define FNIC_HOST_RESET_TIMEOUT 1 /* mSec */ #define FNIC_RMDEVICE_TIMEOUT1000 /* mSec */ #define FNIC_HOST_RESET_SETTLE_TIME 30 /* Sec */ +#define FNIC_ABT_TERM_DELAY_TIMEOUT 500/* mSec */ #define FNIC_MAX_FCP_TARGET 256 +/** + * state_flags to identify host state along along with fnic's state + **/ +#define __FNIC_FLAGS_FWRESET BIT(0) /* fwreset in progress */ +#define __FNIC_FLAGS_BLOCK_IO BIT(1) /* IOs are blocked */ + +#define FNIC_FLAGS_NONE(0) +#define FNIC_FLAGS_FWRESET (__FNIC_FLAGS_FWRESET | \ + __FNIC_FLAGS_BLOCK_IO) + +#define FNIC_FLAGS_IO_BLOCKED (__FNIC_FLAGS_BLOCK_IO) + +#define fnic_set_state_flags(fnicp, st_flags) \ + __fnic_set_state_flags(fnicp, st_flags, 0) + +#define fnic_clear_state_flags(fnicp, st_flags) \ + __fnic_set_state_flags(fnicp, st_flags, 1) + extern unsigned int fnic_log_level; #define FNIC_MAIN_LOGGING 0x01 @@ -170,6 +203,9 @@ struct fnic { struct completion *remove_wait; /* device remove thread blocks */ + atomic_t in_flight; /* io counter */ + u32 _reserved; /* fill hole */ + unsigned long state_flags; /* protected by host lock */ enum fnic_state state; spinlock_t fnic_lock; @@ -267,4 +303,10 @@ const char *fnic_state_to_str(unsigned int state); void fnic_log_q_error(struct fnic *fnic); void fnic_handle_link_event(struct fnic *fnic); +static inline
[PATCH 05/10] fnic: fnic driver may hit BUG_ON on device reset
The issue was observed when LUN Reset is issued through IOCTL or sg_reset utility. fnic driver issues LUN RESET to firmware. On successful completion of device reset, driver cleans up all the pending IOs that were issued prior to device reset. These pending IOs are expected to be in ABTS_PENDING state. This works fine, when the device reset operation resulted from midlayer, but not when device reset was triggered from IOCTL path as the pending IOs were not in ABTS_PENDING state. execution path hits panic if the pending IO is not in ABTS_PENDING state. Changes: The fix replaces BUG_ON check in fnic_clean_pending_aborts() with marking pending IOs as ABTS_PENDING if they were not in ABTS_PENDING state and skips if they were already in ABTS_PENDING state. An extra check is added to validate the abort status of the commands after a delay of 2 * E_D_TOV using a helper function. The helper function returns 1 if it finds any pending IO in ABTS_PENDING state, belong to the LUN on which device reset was issued else 0. With this, device reset operation returns success only if the helper funciton returns 0, otherwise it returns failure. Other changes: - Removed code in fnic_clean_pending_aborts() that returns failure if it finds io_req NULL, instead of returning failure added code to continue with next io - Added device reset flags for debugging in fnic_terminate_rport_io, fnic_rport_exch_reset, and fnic_clean_pending_aborts Signed-off-by: Narsimhulu Musini nmus...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h |2 + drivers/scsi/fnic/fnic_scsi.c | 121 ++--- 2 files changed, 116 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 63b35c8..b8e6644 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -303,6 +303,8 @@ const char *fnic_state_to_str(unsigned int state); void fnic_log_q_error(struct fnic *fnic); void fnic_handle_link_event(struct fnic *fnic); +int fnic_is_abts_pending(struct fnic *, struct scsi_cmnd *); + static inline int fnic_chk_state_flags_locked(struct fnic *fnic, unsigned long st_flags) { diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index 2f46509..6483081 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -1271,7 +1271,8 @@ static void fnic_rport_exch_reset(struct fnic *fnic, u32 port_id) spin_unlock_irqrestore(io_lock, flags); } else { spin_lock_irqsave(io_lock, flags); - CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED; + if (CMD_FLAGS(sc) FNIC_DEVICE_RESET) + CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED; spin_unlock_irqrestore(io_lock, flags); } } @@ -1379,7 +1380,8 @@ void fnic_terminate_rport_io(struct fc_rport *rport) spin_unlock_irqrestore(io_lock, flags); } else { spin_lock_irqsave(io_lock, flags); - CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED; + if (CMD_FLAGS(sc) FNIC_DEVICE_RESET) + CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED; spin_unlock_irqrestore(io_lock, flags); } } @@ -1592,7 +1594,7 @@ lr_io_req_end: static int fnic_clean_pending_aborts(struct fnic *fnic, struct scsi_cmnd *lr_sc) { - int tag; + int tag, abt_tag; struct fnic_io_req *io_req; spinlock_t *io_lock; unsigned long flags; @@ -1601,6 +1603,7 @@ static int fnic_clean_pending_aborts(struct fnic *fnic, struct scsi_lun fc_lun; struct scsi_device *lun_dev = lr_sc-device; DECLARE_COMPLETION_ONSTACK(tm_done); + enum fnic_ioreq_state old_ioreq_state; for (tag = 0; tag FNIC_MAX_IO_REQ; tag++) { sc = scsi_host_find_tag(fnic-lport-host, tag); @@ -1629,7 +1632,41 @@ static int fnic_clean_pending_aborts(struct fnic *fnic, Found IO in %s on lun\n, fnic_ioreq_state_to_str(CMD_STATE(sc))); - BUG_ON(CMD_STATE(sc) != FNIC_IOREQ_ABTS_PENDING); + if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) { + spin_unlock_irqrestore(io_lock, flags); + continue; + } + if ((CMD_FLAGS(sc) FNIC_DEVICE_RESET) + (!(CMD_FLAGS(sc) FNIC_DEV_RST_PENDING))) { + FNIC_SCSI_DBG(KERN_INFO, fnic-lport-host, + %s dev rst not pending sc 0x%p\n, __func__, + sc); + spin_unlock_irqrestore(io_lock, flags); + continue
[PATCH 10/10] fnic: Incremented driver version
Incrementing driver versio after bug fixes and new feature commits. Signed-off-by: Brian Uchino buch...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index acec42a..b6d1f92 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -38,7 +38,7 @@ #define DRV_NAME fnic #define DRV_DESCRIPTIONCisco FCoE HBA Driver -#define DRV_VERSION1.5.0.2 +#define DRV_VERSION1.5.0.22 #define PFXDRV_NAME : #define DFX DRV_NAME %d: -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 09/10] fnic: Kernel panic due to FIP mode misconfiguration
If switch configured in FIP and adapter configured in non-fip mode, driver panics while queueing FIP frame in non-existing fip_frame_queue. Added config check before queueing FIP frame in misconfiguration case to avoid kernel panic. Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_fcs.c |6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c index 41faca4..a0092e8 100644 --- a/drivers/scsi/fnic/fnic_fcs.c +++ b/drivers/scsi/fnic/fnic_fcs.c @@ -603,6 +603,12 @@ static inline int fnic_import_rq_eth_pkt(struct fnic *fnic, struct sk_buff *skb) skb_reset_mac_header(skb); } if (eh-h_proto == htons(ETH_P_FIP)) { + if (!(fnic-config.flags VFCF_FIP_CAPABLE)) { + printk(KERN_ERR Dropped FIP frame, as firmware + uses non-FIP mode, Enable FIP + using UCSM\n); + goto drop; + } skb_queue_tail(fnic-fip_frame_queue, skb); queue_work(fnic_fip_queue, fnic-fip_frame_work); return 1; /* let caller know packet was used */ -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 08/10] fnic: FIP VLAN Discovery Feature Support
FIP VLAN discovery discovers the FCoE VLAN that will be used by all other FIP protocols as well as by the FCoE encapsulation for Fibre Channel payloads on the established virtual link. One of the goals of FC-BB-5 was to be as nonintrusive as possible on initiators and targets, and therefore FIP VLAN discovery occurs in the native VLAN used by the initiator or target to exchange Ethernet traffic. The FIP VLAN discovery protocol is the only FIP protocol running on the native VLAN; all other FIP protocols run on the discovered FCoE VLANs. If an administrator has manually configured FCoE VLANs on ENodes and FCFs, there is no need to use this protocol. FIP and FCoE will run over the configured VLANs. An ENode without FCoE VLANs configuration would use this automated discovery protocol to discover over which VLANs FCoE is running. The ENode sends a FIP VLAN discovery request to a multicast MAC address called All-FCF-MACs, which is a multicast MAC address to which all FCFs listen. All FCFs that can be reached in the native VLAN of the ENode are expected to respond on the same VLAN with a response that lists one or more FCoE VLANs that are available for the ENode's VN_Port login. This protocol has the sole purpose of allowing the ENode to discover all the available FCoE VLANs. Now the ENode may enable a subset of these VLANs for FCoE Running the FIP protocol in these VLANs on a per VLAN basis. And FCoE data transactions also would occur on this VLAN. Hence, Except for FIP VLAN discovery, all other FIP and FCoE traffic runs on the selected FCoE VLAN. Its only the FIP VLAN Discovery protocol that is permitted to run on the Default native VLAN of the system. [ NOTE ] We are working on moving this feature definitions and functionality to libfcoe module. We need this patch to be approved, as Suse is looking forward to merge this feature in SLES 11 SP3 release. Once this patch is approved, we will submit patch which should move vlan discovery feature to libfoce. Signed-off-by: Anantha Prakash T atung...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h| 32 +++ drivers/scsi/fnic/fnic_fcs.c| 558 ++- drivers/scsi/fnic/fnic_fip.h| 68 + drivers/scsi/fnic/fnic_main.c | 51 +++- drivers/scsi/fnic/vnic_dev.c| 10 + drivers/scsi/fnic/vnic_dev.h|2 + drivers/scsi/fnic/vnic_devcmd.h | 67 + 7 files changed, 784 insertions(+), 4 deletions(-) create mode 100644 drivers/scsi/fnic/fnic_fip.h diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 98436c3..acec42a 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -192,6 +192,18 @@ enum fnic_state { struct mempool; +enum fnic_evt { + FNIC_EVT_START_VLAN_DISC = 1, + FNIC_EVT_START_FCF_DISC = 2, + FNIC_EVT_MAX, +}; + +struct fnic_event { + struct list_head list; + struct fnic *fnic; + enum fnic_evt event; +}; + /* Per-instance private data structure */ struct fnic { struct fc_lport *lport; @@ -254,6 +266,18 @@ struct fnic { struct sk_buff_head frame_queue; struct sk_buff_head tx_queue; + /*** FIP related data members -- start ***/ + void (*set_vlan)(struct fnic *, u16 vlan); + struct work_struct fip_frame_work; + struct sk_buff_head fip_frame_queue; + struct timer_list fip_timer; + struct list_headvlans; + spinlock_t vlans_lock; + + struct work_struct event_work; + struct list_headevlist; + /*** FIP related data members -- end ***/ + /* copy work queue cache line section */ cacheline_aligned struct vnic_wq_copy wq_copy[FNIC_WQ_COPY_MAX]; /* completion queue cache line section */ @@ -278,6 +302,7 @@ static inline struct fnic *fnic_from_ctlr(struct fcoe_ctlr *fip) } extern struct workqueue_struct *fnic_event_queue; +extern struct workqueue_struct *fnic_fip_queue; extern struct device_attribute *fnic_attrs[]; void fnic_clear_intr_mode(struct fnic *fnic); @@ -289,6 +314,7 @@ int fnic_send(struct fc_lport *, struct fc_frame *); void fnic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf); void fnic_handle_frame(struct work_struct *work); void fnic_handle_link(struct work_struct *work); +void fnic_handle_event(struct work_struct *work); int fnic_rq_cmpl_handler(struct fnic *fnic, int); int fnic_alloc_rq_frame(struct vnic_rq *rq); void fnic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf); @@ -321,6 +347,12 @@ void fnic_handle_link_event(struct fnic *fnic); int fnic_is_abts_pending(struct fnic *, struct scsi_cmnd *); +void fnic_handle_fip_frame(struct work_struct *work); +void fnic_handle_fip_event(struct fnic *fnic); +void fnic_fcoe_reset_vlans(struct fnic *fnic); +void fnic_fcoe_evlist_free(struct fnic *fnic); +extern void fnic_handle_fip_timer(struct fnic *fnic
[PATCH 07/10] fnic: Fnic Trace Utility
Fnic Trace utility is a tracing functionality built directly into fnic driver to trace events. The benefit that trace buffer brings to fnic driver is the ability to see what it happening inside the fnic driver. It also provides the capability to trace every IO event inside fnic driver to debug panics, hangs and potentially IO corruption issues. This feature makes it easy to find problems in fnic driver and it also helps in tracking down strange bugs in a more manageable way. Trace buffer is shared across all fnic instances for this implementation. Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/Makefile |2 + drivers/scsi/fnic/fnic.h |1 + drivers/scsi/fnic/fnic_debugfs.c | 314 ++ drivers/scsi/fnic/fnic_main.c| 14 ++ drivers/scsi/fnic/fnic_scsi.c| 120 +-- drivers/scsi/fnic/fnic_trace.c | 273 + drivers/scsi/fnic/fnic_trace.h | 90 +++ 7 files changed, 803 insertions(+), 11 deletions(-) create mode 100644 drivers/scsi/fnic/fnic_debugfs.c create mode 100644 drivers/scsi/fnic/fnic_trace.c create mode 100644 drivers/scsi/fnic/fnic_trace.h diff --git a/drivers/scsi/fnic/Makefile b/drivers/scsi/fnic/Makefile index 37c3440..383598f 100644 --- a/drivers/scsi/fnic/Makefile +++ b/drivers/scsi/fnic/Makefile @@ -7,6 +7,8 @@ fnic-y := \ fnic_res.o \ fnic_fcs.o \ fnic_scsi.o \ + fnic_trace.o \ + fnic_debugfs.o \ vnic_cq.o \ vnic_dev.o \ vnic_intr.o \ diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 9c95a1a..98436c3 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -26,6 +26,7 @@ #include scsi/libfcoe.h #include fnic_io.h #include fnic_res.h +#include fnic_trace.h #include vnic_dev.h #include vnic_wq.h #include vnic_rq.h diff --git a/drivers/scsi/fnic/fnic_debugfs.c b/drivers/scsi/fnic/fnic_debugfs.c new file mode 100644 index 000..adc1f7f --- /dev/null +++ b/drivers/scsi/fnic/fnic_debugfs.c @@ -0,0 +1,314 @@ +/* + * Copyright 2012 Cisco Systems, Inc. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include linux/module.h +#include linux/errno.h +#include linux/debugfs.h +#include fnic.h + +static struct dentry *fnic_trace_debugfs_root; +static struct dentry *fnic_trace_debugfs_file; +static struct dentry *fnic_trace_enable; + +/* + * fnic_trace_ctrl_open - Open the trace_enable file + * @inode: The inode pointer. + * @file: The file pointer to attach the trace enable/disable flag. + * + * Description: + * This routine opens a debugsfs file trace_enable. + * + * Returns: + * This function returns zero if successful. + */ +static int fnic_trace_ctrl_open(struct inode *inode, struct file *filp) +{ + filp-private_data = inode-i_private; + return 0; +} + +/* + * fnic_trace_ctrl_read - Read a trace_enable debugfs file + * @filp: The file pointer to read from. + * @ubuf: The buffer to copy the data to. + * @cnt: The number of bytes to read. + * @ppos: The position in the file to start reading from. + * + * Description: + * This routine reads value of variable fnic_tracing_enabled + * and stores into local @buf. It will start reading file at @ppos and + * copy up to @cnt of data to @ubuf from @buf. + * + * Returns: + * This function returns the amount of data that was read. + */ +static ssize_t fnic_trace_ctrl_read(struct file *filp, + char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + char buf[64]; + int len; + len = sprintf(buf, %u\n, fnic_tracing_enabled); + + return simple_read_from_buffer(ubuf, cnt, ppos, buf, len); +} + +/* + * fnic_trace_ctrl_write - Write to trace_enable debugfs file + * @filp: The file pointer to write from. + * @ubuf: The buffer to copy the data from. + * @cnt: The number of bytes to write. + * @ppos: The position in the file to start writing to. + * + * Description: + * This routine writes data from user buffer @ubuf to buffer @buf and + * sets fnic_tracing_enabled value as per user input. + * + * Returns: + * This function returns the amount of data that was written. + */ +static ssize_t fnic_trace_ctrl_write(struct file *filp
Re: [scsi:misc 61/65] drivers/scsi/fnic/fnic_scsi.c:441:3: warning: cast from pointer to integer of different size
Hi James, I have fixed fnic patches 3-10 for sparse and smatch errors. Thanks, Hiral On 1/29/13 10:26 PM, kbuild test robot fengguang...@intel.com wrote: tree: git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git misc head: 52cb5cbe9b8ed89db0f8c9eeec8410fcfb0887fd commit: 6f3b5679f2af1ef3becbf7832d2bce977907c08a [61/65] [SCSI] fnic: fixing issues in device and firmware reset code config: make ARCH=i386 allmodconfig All warnings: drivers/scsi/fnic/fnic_scsi.c:190:39: sparse: context imbalance in '__fnic_set_state_flags' - unexpected unlock drivers/scsi/fnic/fnic_scsi.c:419:19: sparse: context imbalance in 'fnic_queuecommand_lck' - unexpected unlock drivers/scsi/fnic/fnic_scsi.c:2411:49: sparse: context imbalance in 'fnic_is_abts_pending' - different lock contexts for basic block drivers/scsi/fnic/fnic_scsi.c: In function 'fnic_queuecommand_lck': drivers/scsi/fnic/fnic_scsi.c:441:3: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] drivers/scsi/fnic/fnic_scsi.c:441:3: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] drivers/scsi/fnic/fnic_scsi.c:493:3: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] drivers/scsi/fnic/fnic_scsi.c:493:3: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] drivers/scsi/fnic/fnic_scsi.c:515:2: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] drivers/scsi/fnic/fnic_scsi.c:515:2: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] drivers/scsi/fnic/fnic_scsi.c:515:2: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] drivers/scsi/fnic/fnic_scsi.c: In function 'fnic_fcpio_ack_handler': drivers/scsi/fnic/fnic_scsi.c:703:2: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] drivers/scsi/fnic/fnic_scsi.c: In function 'fnic_fcpio_icmnd_cmpl_handler': drivers/scsi/fnic/fnic_scsi.c:747:3: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] drivers/scsi/fnic/fnic_scsi.c:747:3: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] drivers/scsi/fnic/fnic_scsi.c:904:2: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] drivers/scsi/fnic/fnic_scsi.c:904:2: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] drivers/scsi/fnic/fnic_scsi.c:904:2: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] drivers/scsi/fnic/fnic_scsi.c: In function 'fnic_fcpio_itmf_cmpl_handler': drivers/scsi/fnic/fnic_scsi.c:1022:5: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] drivers/scsi/fnic/fnic_scsi.c:1022:5: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] drivers/scsi/fnic/fnic_scsi.c:1022:5: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] drivers/scsi/fnic/fnic_scsi.c:1044:4: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] drivers/scsi/fnic/fnic_scsi.c:1044:4: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] drivers/scsi/fnic/fnic_scsi.c:1044:4: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] drivers/scsi/fnic/fnic_scsi.c:1059:4: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] -- drivers/scsi/fnic/fnic_trace.c: In function 'fnic_trace_get_buf': drivers/scsi/fnic/fnic_trace.c:80:9: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] drivers/scsi/fnic/fnic_trace.c: In function 'fnic_get_trace_data': drivers/scsi/fnic/fnic_trace.c:112:10: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] drivers/scsi/fnic/fnic_trace.c:149:10: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] drivers/scsi/fnic/fnic_trace.c: In function 'fnic_trace_buf_init': drivers/scsi/fnic/fnic_trace.c:200:21: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] drivers/scsi/fnic/fnic_trace.c:207:2: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] drivers/scsi/fnic/fnic_trace.c:215:10: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] drivers/scsi/fnic/fnic_trace.c: In function 'fnic_trace_free': drivers/scsi/fnic/fnic_trace.c:260:9: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] sparse warnings: (new ones prefixed by ) drivers/scsi/fnic/fnic_scsi.c:190:39: sparse: context imbalance in '__fnic_set_state_flags' - unexpected unlock drivers/scsi/fnic/fnic_scsi.c:419:19: sparse: context imbalance in 'fnic_queuecommand_lck' - unexpected unlock drivers/scsi/fnic/fnic_scsi.c:2411:49: sparse: context imbalance in 'fnic_is_abts_pending' - different lock contexts for basic
Re: [scsi:for-next 23/27] drivers/scsi/fnic/fnic_scsi.c:183:35: sparse: invalid assignment: =
Hi James, Sorry, somehow I missed looking at kbuild emails. I have fixed sparse and smatch issues and resubmitted patches 3-10. Thanks, Hiral On 1/28/13 7:16 PM, James Bottomley james.bottom...@hansenpartnership.com wrote: On Mon, 2012-12-17 at 21:50 +0800, kbuild test robot wrote: tree: git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next head: e3ff197a750d2912d0bb2a0161c23c18bad250ad commit: 188061001ac78b40780af042dd2156e2213e29ed [23/27] [SCSI] fnic:fixing issues in device and firmware reset code sparse warnings: + drivers/scsi/fnic/fnic_scsi.c:183:35: sparse: invalid assignment: = drivers/scsi/fnic/fnic_scsi.c:183:35:left side has type restricted unsigned long long drivers/scsi/fnic/fnic_scsi.c:183:35:right side has type unsigned long long drivers/scsi/fnic/fnic_scsi.c:185:35: sparse: invalid assignment: |= drivers/scsi/fnic/fnic_scsi.c:185:35:left side has type restricted unsigned long long drivers/scsi/fnic/fnic_scsi.c:185:35:right side has type unsigned long long I still haven't seen fixes for these patches. I've flushed the fnic patches from the tree pending resolution. That means the only remaining fnic patches I have are 1/10 fnic: updated MAINTAINERS list 2/10 fnic: fix for trusted cos Please fix this and the smatch issues and resubmit the other eight. Thanks, James -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 10/10] fnic: Incremented driver version
Incrementing driver versio after bug fixes and new feature commits. Signed-off-by: Brian Uchino buch...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index acec42a..b6d1f92 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -38,7 +38,7 @@ #define DRV_NAME fnic #define DRV_DESCRIPTIONCisco FCoE HBA Driver -#define DRV_VERSION1.5.0.2 +#define DRV_VERSION1.5.0.22 #define PFXDRV_NAME : #define DFX DRV_NAME %d: -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 08/10] fnic: FIP VLAN Discovery Feature Support
FIP VLAN discovery discovers the FCoE VLAN that will be used by all other FIP protocols as well as by the FCoE encapsulation for Fibre Channel payloads on the established virtual link. One of the goals of FC-BB-5 was to be as nonintrusive as possible on initiators and targets, and therefore FIP VLAN discovery occurs in the native VLAN used by the initiator or target to exchange Ethernet traffic. The FIP VLAN discovery protocol is the only FIP protocol running on the native VLAN; all other FIP protocols run on the discovered FCoE VLANs. If an administrator has manually configured FCoE VLANs on ENodes and FCFs, there is no need to use this protocol. FIP and FCoE will run over the configured VLANs. An ENode without FCoE VLANs configuration would use this automated discovery protocol to discover over which VLANs FCoE is running. The ENode sends a FIP VLAN discovery request to a multicast MAC address called All-FCF-MACs, which is a multicast MAC address to which all FCFs listen. All FCFs that can be reached in the native VLAN of the ENode are expected to respond on the same VLAN with a response that lists one or more FCoE VLANs that are available for the ENode's VN_Port login. This protocol has the sole purpose of allowing the ENode to discover all the available FCoE VLANs. Now the ENode may enable a subset of these VLANs for FCoE Running the FIP protocol in these VLANs on a per VLAN basis. And FCoE data transactions also would occur on this VLAN. Hence, Except for FIP VLAN discovery, all other FIP and FCoE traffic runs on the selected FCoE VLAN. Its only the FIP VLAN Discovery protocol that is permitted to run on the Default native VLAN of the system. [ NOTE ] We are working on moving this feature definitions and functionality to libfcoe module. We need this patch to be approved, as Suse is looking forward to merge this feature in SLES 11 SP3 release. Once this patch is approved, we will submit patch which should move vlan discovery feature to libfoce. Signed-off-by: Anantha Prakash T atung...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h| 32 +++ drivers/scsi/fnic/fnic_fcs.c| 557 ++- drivers/scsi/fnic/fnic_fip.h| 68 + drivers/scsi/fnic/fnic_main.c | 51 +++- drivers/scsi/fnic/vnic_dev.c| 10 + drivers/scsi/fnic/vnic_dev.h|2 + drivers/scsi/fnic/vnic_devcmd.h | 67 + 7 files changed, 783 insertions(+), 4 deletions(-) create mode 100644 drivers/scsi/fnic/fnic_fip.h diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 98436c3..acec42a 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -192,6 +192,18 @@ enum fnic_state { struct mempool; +enum fnic_evt { + FNIC_EVT_START_VLAN_DISC = 1, + FNIC_EVT_START_FCF_DISC = 2, + FNIC_EVT_MAX, +}; + +struct fnic_event { + struct list_head list; + struct fnic *fnic; + enum fnic_evt event; +}; + /* Per-instance private data structure */ struct fnic { struct fc_lport *lport; @@ -254,6 +266,18 @@ struct fnic { struct sk_buff_head frame_queue; struct sk_buff_head tx_queue; + /*** FIP related data members -- start ***/ + void (*set_vlan)(struct fnic *, u16 vlan); + struct work_struct fip_frame_work; + struct sk_buff_head fip_frame_queue; + struct timer_list fip_timer; + struct list_headvlans; + spinlock_t vlans_lock; + + struct work_struct event_work; + struct list_headevlist; + /*** FIP related data members -- end ***/ + /* copy work queue cache line section */ cacheline_aligned struct vnic_wq_copy wq_copy[FNIC_WQ_COPY_MAX]; /* completion queue cache line section */ @@ -278,6 +302,7 @@ static inline struct fnic *fnic_from_ctlr(struct fcoe_ctlr *fip) } extern struct workqueue_struct *fnic_event_queue; +extern struct workqueue_struct *fnic_fip_queue; extern struct device_attribute *fnic_attrs[]; void fnic_clear_intr_mode(struct fnic *fnic); @@ -289,6 +314,7 @@ int fnic_send(struct fc_lport *, struct fc_frame *); void fnic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf); void fnic_handle_frame(struct work_struct *work); void fnic_handle_link(struct work_struct *work); +void fnic_handle_event(struct work_struct *work); int fnic_rq_cmpl_handler(struct fnic *fnic, int); int fnic_alloc_rq_frame(struct vnic_rq *rq); void fnic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf); @@ -321,6 +347,12 @@ void fnic_handle_link_event(struct fnic *fnic); int fnic_is_abts_pending(struct fnic *, struct scsi_cmnd *); +void fnic_handle_fip_frame(struct work_struct *work); +void fnic_handle_fip_event(struct fnic *fnic); +void fnic_fcoe_reset_vlans(struct fnic *fnic); +void fnic_fcoe_evlist_free(struct fnic *fnic); +extern void fnic_handle_fip_timer(struct fnic *fnic
[PATCH 04/10] fnic: Fix SGEs limit
Driver allows IOs with more SGEs than max SGEs supported by Palo. The current max SGEs supported by the fnic driver is 1024. The current register settings on Palo supports a max of 256 only. Palo would return any IO with more than 256 SGEs with an error indicating INVALID_SGLS. Fnic driver should limit the max supported SGLs in the driver to 256 to avoid this error. Signed-off-by: Sesidhar Baddela sebad...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_io.h |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/fnic/fnic_io.h b/drivers/scsi/fnic/fnic_io.h index f0b8969..3455c34 100644 --- a/drivers/scsi/fnic/fnic_io.h +++ b/drivers/scsi/fnic/fnic_io.h @@ -21,7 +21,7 @@ #include scsi/fc/fc_fcp.h #define FNIC_DFLT_SG_DESC_CNT 32 -#define FNIC_MAX_SG_DESC_CNT1024/* Maximum descriptors per sgl */ +#define FNIC_MAX_SG_DESC_CNT256 /* Maximum descriptors per sgl */ #define FNIC_SG_DESC_ALIGN 16 /* Descriptor address alignment */ struct host_sg_desc { -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 06/10] fnic: New debug flags and debug log messages
Added new fnic debug flags for identifying IO state at every stage of IO while debugging and also added more log messages for better debugging capability. Signed-off-by: Sesidhar Baddela sebad...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h | 31 --- drivers/scsi/fnic/fnic_io.h |4 +- drivers/scsi/fnic/fnic_scsi.c | 121 + 3 files changed, 135 insertions(+), 21 deletions(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index b8e6644..9c95a1a 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -59,14 +59,29 @@ * Command flags to identify the type of command and for other future * use. */ -#define FNIC_NO_FLAGS 0 -#define FNIC_CDB_REQ BIT(1) /* All IOs with a valid CDB */ -#define FNIC_BLOCKING_REQ BIT(2) /* All blocking Requests */ -#define FNIC_DEVICE_RESET BIT(3) /* Device reset request */ -#define FNIC_DEV_RST_PENDING BIT(4) /* Device reset pending */ -#define FNIC_DEV_RST_TIMED_OUT BIT(5) /* Device reset timed out */ -#define FNIC_DEV_RST_TERM_ISSUED BIT(6) /* Device reset terminate */ -#define FNIC_DEV_RST_DONE BIT(7) /* Device reset done */ +#define FNIC_NO_FLAGS 0 +#define FNIC_IO_INITIALIZED BIT(0) +#define FNIC_IO_ISSUED BIT(1) +#define FNIC_IO_DONEBIT(2) +#define FNIC_IO_REQ_NULLBIT(3) +#define FNIC_IO_ABTS_PENDINGBIT(4) +#define FNIC_IO_ABORTED BIT(5) +#define FNIC_IO_ABTS_ISSUED BIT(6) +#define FNIC_IO_TERM_ISSUED BIT(7) +#define FNIC_IO_INTERNAL_TERM_ISSUEDBIT(8) +#define FNIC_IO_ABT_TERM_DONE BIT(9) +#define FNIC_IO_ABT_TERM_REQ_NULL BIT(10) +#define FNIC_IO_ABT_TERM_TIMED_OUT BIT(11) +#define FNIC_DEVICE_RESET BIT(12) /* Device reset request */ +#define FNIC_DEV_RST_ISSUED BIT(13) +#define FNIC_DEV_RST_TIMED_OUT BIT(14) +#define FNIC_DEV_RST_ABTS_ISSUEDBIT(15) +#define FNIC_DEV_RST_TERM_ISSUEDBIT(16) +#define FNIC_DEV_RST_DONE BIT(17) +#define FNIC_DEV_RST_REQ_NULL BIT(18) +#define FNIC_DEV_RST_ABTS_DONE BIT(19) +#define FNIC_DEV_RST_TERM_DONE BIT(20) +#define FNIC_DEV_RST_ABTS_PENDING BIT(21) /* * Usage of the scsi_cmnd scratchpad. diff --git a/drivers/scsi/fnic/fnic_io.h b/drivers/scsi/fnic/fnic_io.h index 3455c34..c35b8f1 100644 --- a/drivers/scsi/fnic/fnic_io.h +++ b/drivers/scsi/fnic/fnic_io.h @@ -45,7 +45,8 @@ enum fnic_sgl_list_type { }; enum fnic_ioreq_state { - FNIC_IOREQ_CMD_PENDING = 0, + FNIC_IOREQ_NOT_INITED = 0, + FNIC_IOREQ_CMD_PENDING, FNIC_IOREQ_ABTS_PENDING, FNIC_IOREQ_ABTS_COMPLETE, FNIC_IOREQ_CMD_COMPLETE, @@ -60,6 +61,7 @@ struct fnic_io_req { u8 sgl_type; /* device DMA descriptor list type */ u8 io_completed:1; /* set to 1 when fw completes IO */ u32 port_id; /* remote port DID */ + unsigned long start_time; /* in jiffies */ struct completion *abts_done; /* completion for abts */ struct completion *dr_done; /* completion for device reset */ }; diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index 6483081..661efa4 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -47,6 +47,7 @@ const char *fnic_state_str[] = { }; static const char *fnic_ioreq_state_str[] = { + [FNIC_IOREQ_NOT_INITED] = FNIC_IOREQ_NOT_INITED, [FNIC_IOREQ_CMD_PENDING] = FNIC_IOREQ_CMD_PENDING, [FNIC_IOREQ_ABTS_PENDING] = FNIC_IOREQ_ABTS_PENDING, [FNIC_IOREQ_ABTS_COMPLETE] = FNIC_IOREQ_ABTS_COMPLETE, @@ -349,6 +350,8 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic, if (unlikely(!vnic_wq_copy_desc_avail(wq))) { spin_unlock_irqrestore(fnic-wq_copy_lock[0], intr_flags); + FNIC_SCSI_DBG(KERN_INFO, fnic-lport-host, + fnic_queue_wq_copy_desc failure - no descriptors\n); return SCSI_MLQUEUE_HOST_BUSY; } @@ -420,7 +423,8 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_ * caller disabling them. */ spin_unlock(lp-host-host_lock); - CMD_FLAGS(sc) = FNIC_CDB_REQ; + CMD_STATE(sc) = FNIC_IOREQ_NOT_INITED; + CMD_FLAGS(sc) = FNIC_NO_FLAGS; /* Get a new io_req for this SCSI IO */ io_req = mempool_alloc(fnic-io_req_pool, GFP_ATOMIC); @@ -467,8 +471,10 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_ /* initialize rest of io_req */ io_req-port_id = rport-port_id; + io_req-start_time = jiffies; CMD_STATE(sc) = FNIC_IOREQ_CMD_PENDING; CMD_SP(sc) = (char
[PATCH 03/10] fnic:fixing issues in device and firmware reset code
1. Handling overlapped firmware resets This fix serialize multiple firmware resets to avoid situation where fnic device fails to come up for link up event, when firmware resets are issued back to back. If there are overlapped firmware resets are issued, the firmware reset operation checks whether there is any firmware reset in progress, if so it polls for its completion in a loop with 100ms delay. 2. Handling device reset timeout fnic_device_reset code has been modified to handle Device reset timeout: - Issue terminate on device reset timeout. - Introduced flags field (one of the scratch fields in scsi_cmnd). With this, device reset request would have DEVICE_RESET flag set for other routines to determine the type of the request. Also modified fnic_terminate_rport_io, fnic_rport_exch_rset, completion routines to handle SCSI commands with DEVICE_RESET flag. 3. LUN/Device Reset hangs when issued through IOCTL using utilities like sg_reset. Each SCSI command is associated with a valid tag, fnic uses this tag to retrieve associated scsi command on completion. the LUN/Device Reset issued through IOCTL resulting into a SCSI command that is not associated with a valid tag. So fnic fails to retrieve associated scsi command on completion, which causes hang. This fix allocates tag, associates it with the scsi command and frees the tag, when the operation completed. 4. Preventing IOs during firmware reset. Current fnic implementation allows IO submissions during firmware reset. This fix synchronizes IO submissions and firmware reset operations. It ensures that IOs issued to fnic prior to reset will be issued to the firmware before firmware reset. Signed-off-by: Narsimhulu Musini nmus...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h | 42 + drivers/scsi/fnic/fnic_main.c |3 + drivers/scsi/fnic/fnic_scsi.c | 384 + 3 files changed, 397 insertions(+), 32 deletions(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 95a5ba2..63b35c8 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -56,6 +56,19 @@ #define FNIC_NO_TAG -1 /* + * Command flags to identify the type of command and for other future + * use. + */ +#define FNIC_NO_FLAGS 0 +#define FNIC_CDB_REQ BIT(1) /* All IOs with a valid CDB */ +#define FNIC_BLOCKING_REQ BIT(2) /* All blocking Requests */ +#define FNIC_DEVICE_RESET BIT(3) /* Device reset request */ +#define FNIC_DEV_RST_PENDING BIT(4) /* Device reset pending */ +#define FNIC_DEV_RST_TIMED_OUT BIT(5) /* Device reset timed out */ +#define FNIC_DEV_RST_TERM_ISSUED BIT(6) /* Device reset terminate */ +#define FNIC_DEV_RST_DONE BIT(7) /* Device reset done */ + +/* * Usage of the scsi_cmnd scratchpad. * These fields are locked by the hashed io_req_lock. */ @@ -64,6 +77,7 @@ #define CMD_ABTS_STATUS(Cmnd) ((Cmnd)-SCp.Message) #define CMD_LR_STATUS(Cmnd)((Cmnd)-SCp.have_data_in) #define CMD_TAG(Cmnd) ((Cmnd)-SCp.sent_command) +#define CMD_FLAGS(Cmnd) ((Cmnd)-SCp.Status) #define FCPIO_INVALID_CODE 0x100 /* hdr_status value unused by firmware */ @@ -71,9 +85,28 @@ #define FNIC_HOST_RESET_TIMEOUT 1 /* mSec */ #define FNIC_RMDEVICE_TIMEOUT1000 /* mSec */ #define FNIC_HOST_RESET_SETTLE_TIME 30 /* Sec */ +#define FNIC_ABT_TERM_DELAY_TIMEOUT 500/* mSec */ #define FNIC_MAX_FCP_TARGET 256 +/** + * state_flags to identify host state along along with fnic's state + **/ +#define __FNIC_FLAGS_FWRESET BIT(0) /* fwreset in progress */ +#define __FNIC_FLAGS_BLOCK_IO BIT(1) /* IOs are blocked */ + +#define FNIC_FLAGS_NONE(0) +#define FNIC_FLAGS_FWRESET (__FNIC_FLAGS_FWRESET | \ + __FNIC_FLAGS_BLOCK_IO) + +#define FNIC_FLAGS_IO_BLOCKED (__FNIC_FLAGS_BLOCK_IO) + +#define fnic_set_state_flags(fnicp, st_flags) \ + __fnic_set_state_flags(fnicp, st_flags, 0) + +#define fnic_clear_state_flags(fnicp, st_flags) \ + __fnic_set_state_flags(fnicp, st_flags, 1) + extern unsigned int fnic_log_level; #define FNIC_MAIN_LOGGING 0x01 @@ -170,6 +203,9 @@ struct fnic { struct completion *remove_wait; /* device remove thread blocks */ + atomic_t in_flight; /* io counter */ + u32 _reserved; /* fill hole */ + unsigned long state_flags; /* protected by host lock */ enum fnic_state state; spinlock_t fnic_lock; @@ -267,4 +303,10 @@ const char *fnic_state_to_str(unsigned int state); void fnic_log_q_error(struct fnic *fnic); void fnic_handle_link_event(struct fnic *fnic); +static inline
[PATCH 05/10] fnic: fnic driver may hit BUG_ON on device reset
The issue was observed when LUN Reset is issued through IOCTL or sg_reset utility. fnic driver issues LUN RESET to firmware. On successful completion of device reset, driver cleans up all the pending IOs that were issued prior to device reset. These pending IOs are expected to be in ABTS_PENDING state. This works fine, when the device reset operation resulted from midlayer, but not when device reset was triggered from IOCTL path as the pending IOs were not in ABTS_PENDING state. execution path hits panic if the pending IO is not in ABTS_PENDING state. Changes: The fix replaces BUG_ON check in fnic_clean_pending_aborts() with marking pending IOs as ABTS_PENDING if they were not in ABTS_PENDING state and skips if they were already in ABTS_PENDING state. An extra check is added to validate the abort status of the commands after a delay of 2 * E_D_TOV using a helper function. The helper function returns 1 if it finds any pending IO in ABTS_PENDING state, belong to the LUN on which device reset was issued else 0. With this, device reset operation returns success only if the helper funciton returns 0, otherwise it returns failure. Other changes: - Removed code in fnic_clean_pending_aborts() that returns failure if it finds io_req NULL, instead of returning failure added code to continue with next io - Added device reset flags for debugging in fnic_terminate_rport_io, fnic_rport_exch_reset, and fnic_clean_pending_aborts Signed-off-by: Narsimhulu Musini nmus...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h |2 + drivers/scsi/fnic/fnic_scsi.c | 121 ++--- 2 files changed, 116 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 63b35c8..b8e6644 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -303,6 +303,8 @@ const char *fnic_state_to_str(unsigned int state); void fnic_log_q_error(struct fnic *fnic); void fnic_handle_link_event(struct fnic *fnic); +int fnic_is_abts_pending(struct fnic *, struct scsi_cmnd *); + static inline int fnic_chk_state_flags_locked(struct fnic *fnic, unsigned long st_flags) { diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index 2f46509..6483081 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -1271,7 +1271,8 @@ static void fnic_rport_exch_reset(struct fnic *fnic, u32 port_id) spin_unlock_irqrestore(io_lock, flags); } else { spin_lock_irqsave(io_lock, flags); - CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED; + if (CMD_FLAGS(sc) FNIC_DEVICE_RESET) + CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED; spin_unlock_irqrestore(io_lock, flags); } } @@ -1379,7 +1380,8 @@ void fnic_terminate_rport_io(struct fc_rport *rport) spin_unlock_irqrestore(io_lock, flags); } else { spin_lock_irqsave(io_lock, flags); - CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED; + if (CMD_FLAGS(sc) FNIC_DEVICE_RESET) + CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED; spin_unlock_irqrestore(io_lock, flags); } } @@ -1592,7 +1594,7 @@ lr_io_req_end: static int fnic_clean_pending_aborts(struct fnic *fnic, struct scsi_cmnd *lr_sc) { - int tag; + int tag, abt_tag; struct fnic_io_req *io_req; spinlock_t *io_lock; unsigned long flags; @@ -1601,6 +1603,7 @@ static int fnic_clean_pending_aborts(struct fnic *fnic, struct scsi_lun fc_lun; struct scsi_device *lun_dev = lr_sc-device; DECLARE_COMPLETION_ONSTACK(tm_done); + enum fnic_ioreq_state old_ioreq_state; for (tag = 0; tag FNIC_MAX_IO_REQ; tag++) { sc = scsi_host_find_tag(fnic-lport-host, tag); @@ -1629,7 +1632,41 @@ static int fnic_clean_pending_aborts(struct fnic *fnic, Found IO in %s on lun\n, fnic_ioreq_state_to_str(CMD_STATE(sc))); - BUG_ON(CMD_STATE(sc) != FNIC_IOREQ_ABTS_PENDING); + if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) { + spin_unlock_irqrestore(io_lock, flags); + continue; + } + if ((CMD_FLAGS(sc) FNIC_DEVICE_RESET) + (!(CMD_FLAGS(sc) FNIC_DEV_RST_PENDING))) { + FNIC_SCSI_DBG(KERN_INFO, fnic-lport-host, + %s dev rst not pending sc 0x%p\n, __func__, + sc); + spin_unlock_irqrestore(io_lock, flags); + continue
[PATCH 09/10] fnic: Kernel panic due to FIP mode misconfiguration
If switch configured in FIP and adapter configured in non-fip mode, driver panics while queueing FIP frame in non-existing fip_frame_queue. Added config check before queueing FIP frame in misconfiguration case to avoid kernel panic. Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_fcs.c |6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c index d8aceb0..b9950f1 100644 --- a/drivers/scsi/fnic/fnic_fcs.c +++ b/drivers/scsi/fnic/fnic_fcs.c @@ -602,6 +602,12 @@ static inline int fnic_import_rq_eth_pkt(struct fnic *fnic, struct sk_buff *skb) skb_reset_mac_header(skb); } if (eh-h_proto == htons(ETH_P_FIP)) { + if (!(fnic-config.flags VFCF_FIP_CAPABLE)) { + printk(KERN_ERR Dropped FIP frame, as firmware + uses non-FIP mode, Enable FIP + using UCSM\n); + goto drop; + } skb_queue_tail(fnic-fip_frame_queue, skb); queue_work(fnic_fip_queue, fnic-fip_frame_work); return 1; /* let caller know packet was used */ -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 07/10] fnic: Fnic Trace Utility
Fnic Trace utility is a tracing functionality built directly into fnic driver to trace events. The benefit that trace buffer brings to fnic driver is the ability to see what it happening inside the fnic driver. It also provides the capability to trace every IO event inside fnic driver to debug panics, hangs and potentially IO corruption issues. This feature makes it easy to find problems in fnic driver and it also helps in tracking down strange bugs in a more manageable way. Trace buffer is shared across all fnic instances for this implementation. Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/Makefile |2 + drivers/scsi/fnic/fnic.h |1 + drivers/scsi/fnic/fnic_debugfs.c | 312 ++ drivers/scsi/fnic/fnic_main.c| 14 ++ drivers/scsi/fnic/fnic_scsi.c| 120 +-- drivers/scsi/fnic/fnic_trace.c | 264 drivers/scsi/fnic/fnic_trace.h | 80 ++ 7 files changed, 782 insertions(+), 11 deletions(-) create mode 100644 drivers/scsi/fnic/fnic_debugfs.c create mode 100644 drivers/scsi/fnic/fnic_trace.c create mode 100644 drivers/scsi/fnic/fnic_trace.h diff --git a/drivers/scsi/fnic/Makefile b/drivers/scsi/fnic/Makefile index 37c3440..383598f 100644 --- a/drivers/scsi/fnic/Makefile +++ b/drivers/scsi/fnic/Makefile @@ -7,6 +7,8 @@ fnic-y := \ fnic_res.o \ fnic_fcs.o \ fnic_scsi.o \ + fnic_trace.o \ + fnic_debugfs.o \ vnic_cq.o \ vnic_dev.o \ vnic_intr.o \ diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 9c95a1a..98436c3 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -26,6 +26,7 @@ #include scsi/libfcoe.h #include fnic_io.h #include fnic_res.h +#include fnic_trace.h #include vnic_dev.h #include vnic_wq.h #include vnic_rq.h diff --git a/drivers/scsi/fnic/fnic_debugfs.c b/drivers/scsi/fnic/fnic_debugfs.c new file mode 100644 index 000..bc06f9b --- /dev/null +++ b/drivers/scsi/fnic/fnic_debugfs.c @@ -0,0 +1,312 @@ +/* + * Copyright 2012 Cisco Systems, Inc. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include linux/module.h +#include linux/errno.h +#include linux/debugfs.h +#include fnic.h + +static struct dentry *fnic_trace_debugfs_root; +static struct dentry *fnic_trace_debugfs_file; +static struct dentry *fnic_trace_enable; + +/* + * fnic_trace_ctrl_open - Open the trace_enable file + * @inode: The inode pointer. + * @file: The file pointer to attach the trace enable/disable flag. + * + * Description: + * This routine opens a debugsfs file trace_enable. + * + * Returns: + * This function returns zero if successful. + */ +static int fnic_trace_ctrl_open(struct inode *inode, struct file *filp) +{ + filp-private_data = inode-i_private; + return 0; +} + +/* + * fnic_trace_ctrl_read - Read a trace_enable debugfs file + * @filp: The file pointer to read from. + * @ubuf: The buffer to copy the data to. + * @cnt: The number of bytes to read. + * @ppos: The position in the file to start reading from. + * + * Description: + * This routine reads value of variable fnic_tracing_enabled + * and stores into local @buf. It will start reading file at @ppos and + * copy up to @cnt of data to @ubuf from @buf. + * + * Returns: + * This function returns the amount of data that was read. + */ +static ssize_t fnic_trace_ctrl_read(struct file *filp, + char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + char buf[64]; + int len; + len = sprintf(buf, %u\n, fnic_tracing_enabled); + + return simple_read_from_buffer(ubuf, cnt, ppos, buf, len); +} + +/* + * fnic_trace_ctrl_write - Write to trace_enable debugfs file + * @filp: The file pointer to write from. + * @ubuf: The buffer to copy the data from. + * @cnt: The number of bytes to write. + * @ppos: The position in the file to start writing to. + * + * Description: + * This routine writes data from user buffer @ubuf to buffer @buf and + * sets fnic_tracing_enabled value as per user input. + * + * Returns: + * This function returns the amount of data that was written. + */ +static ssize_t fnic_trace_ctrl_write(struct file *filp
Re: [scsi:for-next 23/27] drivers/scsi/fnic/fnic_scsi.c:1260 fnic_rport_exch_reset() error: we previously assumed 'sc-device' could be null (see line 1237)
Hi Dan, I have fixed the new smatch warnings which was introduced by fnic update patches and resubmitted new patches. Thanks, Hiral On 12/17/12 5:49 AM, Dan Carpenter dan.carpen...@oracle.com wrote: [ It doesn't make sense to check for NULL, print an error and then dereference the pointer. The normal Oops message is easy to debug without the extra code added here. Or maybe it is possible for the pointer to be NULL in that case we should handle it correctly. ] Hi Hiral, FYI, there are new smatch warnings show up in tree: git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next head: e3ff197a750d2912d0bb2a0161c23c18bad250ad commit: 188061001ac78b40780af042dd2156e2213e29ed [23/27] [SCSI] fnic:fixing issues in device and firmware reset code drivers/scsi/fnic/fnic_scsi.c:404 fnic_queuecommand_lck() error: potential NULL dereference 'rport'. drivers/scsi/fnic/fnic_scsi.c:303 fnic_queue_wq_copy_desc() error: potential NULL dereference 'rport'. + drivers/scsi/fnic/fnic_scsi.c:1260 fnic_rport_exch_reset() error: we previously assumed 'sc-device' could be null (see line 1237) + drivers/scsi/fnic/fnic_scsi.c:1325 fnic_terminate_rport_io() error: we previously assumed 'sc-device' could be null (see line 1314) drivers/scsi/fnic/fnic_scsi.c:1431 fnic_abort_cmd() error: potential NULL dereference 'rport'. drivers/scsi/fnic/fnic_scsi.c:1787 fnic_device_reset() error: potential NULL dereference 'rport'. git remote add scsi git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git git remote update scsi git checkout 188061001ac78b40780af042dd2156e2213e29ed vim +1260 drivers/scsi/fnic/fnic_scsi.c 18806100 Hiral Patel 2012-12-10 1231if (io_req-abts_done) { 18806100 Hiral Patel 2012-12-10 1232 shost_printk(KERN_ERR, fnic-lport-host, 18806100 Hiral Patel 2012-12-10 1233 fnic_rport_exch_reset: io_req-abts_done is set 18806100 Hiral Patel 2012-12-10 1234state is %s\n, 18806100 Hiral Patel 2012-12-10 1235 fnic_ioreq_state_to_str(CMD_STATE(sc))); 18806100 Hiral Patel 2012-12-10 1236} 18806100 Hiral Patel 2012-12-10 @1237if (sc-device == NULL) 18806100 Hiral Patel 2012-12-10 1238 shost_printk(KERN_ERR, fnic-lport-host, 18806100 Hiral Patel 2012-12-10 1239 fnic_rport_exch_reset: sc-device is null state is 18806100 Hiral Patel 2012-12-10 1240%s\n, fnic_ioreq_state_to_str(CMD_STATE(sc))); 18806100 Hiral Patel 2012-12-10 1241 5df6d737 Abhijeet Joglekar 2009-04-17 1242old_ioreq_state = CMD_STATE(sc); 5df6d737 Abhijeet Joglekar 2009-04-17 1243CMD_STATE(sc) = FNIC_IOREQ_ABTS_PENDING; 5df6d737 Abhijeet Joglekar 2009-04-17 1244CMD_ABTS_STATUS(sc) = FCPIO_INVALID_CODE; 18806100 Hiral Patel 2012-12-10 1245if (CMD_FLAGS(sc) FNIC_DEVICE_RESET) { 18806100 Hiral Patel 2012-12-10 1246abt_tag = (tag | FNIC_TAG_DEV_RST); 18806100 Hiral Patel 2012-12-10 1247 FNIC_SCSI_DBG(KERN_DEBUG, fnic-lport-host, 18806100 Hiral Patel 2012-12-10 1248 fnic_rport_exch_reset dev rst sc 0x%p\n, 18806100 Hiral Patel 2012-12-10 1249sc); 18806100 Hiral Patel 2012-12-10 1250} 5df6d737 Abhijeet Joglekar 2009-04-17 1251 5df6d737 Abhijeet Joglekar 2009-04-17 1252 BUG_ON(io_req-abts_done); 5df6d737 Abhijeet Joglekar 2009-04-17 1253 5df6d737 Abhijeet Joglekar 2009-04-17 1254 FNIC_SCSI_DBG(KERN_DEBUG, fnic-lport-host, 5df6d737 Abhijeet Joglekar 2009-04-17 1255 fnic_rport_reset_exch: Issuing abts\n); 5df6d737 Abhijeet Joglekar 2009-04-17 1256 5df6d737 Abhijeet Joglekar 2009-04-17 1257 spin_unlock_irqrestore(io_lock, flags); 5df6d737 Abhijeet Joglekar 2009-04-17 1258 5df6d737 Abhijeet Joglekar 2009-04-17 1259/* Now queue the abort command to firmware */ 5df6d737 Abhijeet Joglekar 2009-04-17 @1260 int_to_scsilun(sc-device-lun, fc_lun); 5df6d737 Abhijeet Joglekar 2009-04-17 1261 18806100 Hiral Patel 2012-12-10 1262if (fnic_queue_abort_io_req(fnic, abt_tag, 5df6d737 Abhijeet Joglekar 2009-04-17 1263 FCPIO_ITMF_ABT_TASK_TERM, 5df6d737 Abhijeet Joglekar 2009-04-17 1264 fc_lun.scsi_lun, io_req)) { 5df6d737 Abhijeet Joglekar 2009-04-17 1265/* 5df6d737 Abhijeet Joglekar 2009-04-17 1266 * Revert the cmd state back to old state, if 25985edc Lucas De Marchi 2011-03-30 1267 * it hasn't changed in between. This cmd will get 5df6d737 Abhijeet Joglekar 2009-04-17 1268 * aborted later by scsi_eh, or cleaned up during 5df6d737 Abhijeet
[PATCH 06/10] fnic: New debug flags and debug log messages
Added new fnic debug flags for identifying IO state at every stage of IO while debugging and also added more log messages for better debugging capability. Signed-off-by: Sesidhar Baddela sebad...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h | 31 --- drivers/scsi/fnic/fnic_io.h |4 +- drivers/scsi/fnic/fnic_scsi.c | 121 + 3 files changed, 135 insertions(+), 21 deletions(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 9b62fc3..191ad1c 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -59,14 +59,29 @@ * Command flags to identify the type of command and for other future * use. */ -#define FNIC_NO_FLAGS 0 -#define FNIC_CDB_REQ BIT(1) /* All IOs with a valid CDB */ -#define FNIC_BLOCKING_REQ BIT(2) /* All blocking Requests */ -#define FNIC_DEVICE_RESET BIT(3) /* Device reset request */ -#define FNIC_DEV_RST_PENDING BIT(4) /* Device reset pending */ -#define FNIC_DEV_RST_TIMED_OUT BIT(5) /* Device reset timed out */ -#define FNIC_DEV_RST_TERM_ISSUED BIT(6) /* Device reset terminate */ -#define FNIC_DEV_RST_DONE BIT(7) /* Device reset done */ +#define FNIC_NO_FLAGS 0 +#define FNIC_IO_INITIALIZED BIT(0) +#define FNIC_IO_ISSUED BIT(1) +#define FNIC_IO_DONEBIT(2) +#define FNIC_IO_REQ_NULLBIT(3) +#define FNIC_IO_ABTS_PENDINGBIT(4) +#define FNIC_IO_ABORTED BIT(5) +#define FNIC_IO_ABTS_ISSUED BIT(6) +#define FNIC_IO_TERM_ISSUED BIT(7) +#define FNIC_IO_INTERNAL_TERM_ISSUEDBIT(8) +#define FNIC_IO_ABT_TERM_DONE BIT(9) +#define FNIC_IO_ABT_TERM_REQ_NULL BIT(10) +#define FNIC_IO_ABT_TERM_TIMED_OUT BIT(11) +#define FNIC_DEVICE_RESET BIT(12) /* Device reset request */ +#define FNIC_DEV_RST_ISSUED BIT(13) +#define FNIC_DEV_RST_TIMED_OUT BIT(14) +#define FNIC_DEV_RST_ABTS_ISSUEDBIT(15) +#define FNIC_DEV_RST_TERM_ISSUEDBIT(16) +#define FNIC_DEV_RST_DONE BIT(17) +#define FNIC_DEV_RST_REQ_NULL BIT(18) +#define FNIC_DEV_RST_ABTS_DONE BIT(19) +#define FNIC_DEV_RST_TERM_DONE BIT(20) +#define FNIC_DEV_RST_ABTS_PENDING BIT(21) /* * Usage of the scsi_cmnd scratchpad. diff --git a/drivers/scsi/fnic/fnic_io.h b/drivers/scsi/fnic/fnic_io.h index 3455c34..c35b8f1 100644 --- a/drivers/scsi/fnic/fnic_io.h +++ b/drivers/scsi/fnic/fnic_io.h @@ -45,7 +45,8 @@ enum fnic_sgl_list_type { }; enum fnic_ioreq_state { - FNIC_IOREQ_CMD_PENDING = 0, + FNIC_IOREQ_NOT_INITED = 0, + FNIC_IOREQ_CMD_PENDING, FNIC_IOREQ_ABTS_PENDING, FNIC_IOREQ_ABTS_COMPLETE, FNIC_IOREQ_CMD_COMPLETE, @@ -60,6 +61,7 @@ struct fnic_io_req { u8 sgl_type; /* device DMA descriptor list type */ u8 io_completed:1; /* set to 1 when fw completes IO */ u32 port_id; /* remote port DID */ + unsigned long start_time; /* in jiffies */ struct completion *abts_done; /* completion for abts */ struct completion *dr_done; /* completion for device reset */ }; diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index a9f436c..e1e817f 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -47,6 +47,7 @@ const char *fnic_state_str[] = { }; static const char *fnic_ioreq_state_str[] = { + [FNIC_IOREQ_NOT_INITED] = FNIC_IOREQ_NOT_INITED, [FNIC_IOREQ_CMD_PENDING] = FNIC_IOREQ_CMD_PENDING, [FNIC_IOREQ_ABTS_PENDING] = FNIC_IOREQ_ABTS_PENDING, [FNIC_IOREQ_ABTS_COMPLETE] = FNIC_IOREQ_ABTS_COMPLETE, @@ -348,6 +349,8 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic, if (unlikely(!vnic_wq_copy_desc_avail(wq))) { spin_unlock_irqrestore(fnic-wq_copy_lock[0], intr_flags); + FNIC_SCSI_DBG(KERN_INFO, fnic-lport-host, + fnic_queue_wq_copy_desc failure - no descriptors\n); return SCSI_MLQUEUE_HOST_BUSY; } @@ -419,7 +422,8 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_ * caller disabling them. */ spin_unlock(lp-host-host_lock); - CMD_FLAGS(sc) = FNIC_CDB_REQ; + CMD_STATE(sc) = FNIC_IOREQ_NOT_INITED; + CMD_FLAGS(sc) = FNIC_NO_FLAGS; /* Get a new io_req for this SCSI IO */ io_req = mempool_alloc(fnic-io_req_pool, GFP_ATOMIC); @@ -466,8 +470,10 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_ /* initialize rest of io_req */ io_req-port_id = rport-port_id; + io_req-start_time = jiffies; CMD_STATE(sc) = FNIC_IOREQ_CMD_PENDING; CMD_SP(sc) = (char
Re: [PATCH 06/10] fnic: New debug flags and debug log messages
Hi James, I agree with your comment. I missed on duplicate definition, as gcc didn¹t give me error while compiling. I just resubmitted patch 06 after removing duplicate definition. Thanks, Hiral On 12/19/12 2:01 AM, James Bottomley james.bottom...@hansenpartnership.com wrote: On Mon, 2012-12-17 at 15:29 -0800, Hiral Patel wrote: Added new fnic debug flags for identifying IO state at every stage of IO while debugging and also added more log messages for better debugging capability. Signed-off-by: Sesidhar Baddela sebad...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h | 32 --- drivers/scsi/fnic/fnic_io.h |4 +- drivers/scsi/fnic/fnic_scsi.c | 121 + 3 files changed, 136 insertions(+), 21 deletions(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 9b62fc3..cba8c0e 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -50,6 +50,7 @@ /* * Tag bits used for special requests. */ +#define BIT(nr) (1UL (nr)) There already is a macro for this with exactly the same name in linux/bitops.h. You were using it before this patch (although you probably need an explicit #include of it). Doing a duplicate definition is going to cause compiler problems (I'm not sure why gcc isn't complaining even now). James #define FNIC_TAG_ABORT BIT(30) /* tag bit indicating abort */ #define FNIC_TAG_DEV_RSTBIT(29) /* indicates device reset */ #define FNIC_TAG_MASK (BIT(24) - 1) /* mask for lookup */ @@ -59,14 +60,29 @@ * Command flags to identify the type of command and for other future * use. */ -#define FNIC_NO_FLAGS 0 -#define FNIC_CDB_REQBIT(1) /* All IOs with a valid CDB */ -#define FNIC_BLOCKING_REQ BIT(2) /* All blocking Requests */ -#define FNIC_DEVICE_RESET BIT(3) /* Device reset request */ -#define FNIC_DEV_RST_PENDINGBIT(4) /* Device reset pending */ -#define FNIC_DEV_RST_TIMED_OUT BIT(5) /* Device reset timed out */ -#define FNIC_DEV_RST_TERM_ISSUEDBIT(6) /* Device reset terminate */ -#define FNIC_DEV_RST_DONE BIT(7) /* Device reset done */ +#define FNIC_NO_FLAGS 0 +#define FNIC_IO_INITIALIZED BIT(0) +#define FNIC_IO_ISSUED BIT(1) +#define FNIC_IO_DONEBIT(2) +#define FNIC_IO_REQ_NULLBIT(3) +#define FNIC_IO_ABTS_PENDINGBIT(4) +#define FNIC_IO_ABORTED BIT(5) +#define FNIC_IO_ABTS_ISSUED BIT(6) +#define FNIC_IO_TERM_ISSUED BIT(7) +#define FNIC_IO_INTERNAL_TERM_ISSUEDBIT(8) +#define FNIC_IO_ABT_TERM_DONE BIT(9) +#define FNIC_IO_ABT_TERM_REQ_NULL BIT(10) +#define FNIC_IO_ABT_TERM_TIMED_OUT BIT(11) +#define FNIC_DEVICE_RESET BIT(12) /* Device reset request */ +#define FNIC_DEV_RST_ISSUED BIT(13) +#define FNIC_DEV_RST_TIMED_OUT BIT(14) +#define FNIC_DEV_RST_ABTS_ISSUEDBIT(15) +#define FNIC_DEV_RST_TERM_ISSUEDBIT(16) +#define FNIC_DEV_RST_DONE BIT(17) +#define FNIC_DEV_RST_REQ_NULL BIT(18) +#define FNIC_DEV_RST_ABTS_DONE BIT(19) +#define FNIC_DEV_RST_TERM_DONE BIT(20) +#define FNIC_DEV_RST_ABTS_PENDING BIT(21) /* * Usage of the scsi_cmnd scratchpad. diff --git a/drivers/scsi/fnic/fnic_io.h b/drivers/scsi/fnic/fnic_io.h index 3455c34..c35b8f1 100644 --- a/drivers/scsi/fnic/fnic_io.h +++ b/drivers/scsi/fnic/fnic_io.h @@ -45,7 +45,8 @@ enum fnic_sgl_list_type { }; enum fnic_ioreq_state { -FNIC_IOREQ_CMD_PENDING = 0, +FNIC_IOREQ_NOT_INITED = 0, +FNIC_IOREQ_CMD_PENDING, FNIC_IOREQ_ABTS_PENDING, FNIC_IOREQ_ABTS_COMPLETE, FNIC_IOREQ_CMD_COMPLETE, @@ -60,6 +61,7 @@ struct fnic_io_req { u8 sgl_type; /* device DMA descriptor list type */ u8 io_completed:1; /* set to 1 when fw completes IO */ u32 port_id; /* remote port DID */ +unsigned long start_time; /* in jiffies */ struct completion *abts_done; /* completion for abts */ struct completion *dr_done; /* completion for device reset */ }; diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index a9f436c..e1e817f 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -47,6 +47,7 @@ const char *fnic_state_str[] = { }; static const char *fnic_ioreq_state_str[] = { +[FNIC_IOREQ_NOT_INITED] = FNIC_IOREQ_NOT_INITED, [FNIC_IOREQ_CMD_PENDING] = FNIC_IOREQ_CMD_PENDING, [FNIC_IOREQ_ABTS_PENDING] = FNIC_IOREQ_ABTS_PENDING, [FNIC_IOREQ_ABTS_COMPLETE] = FNIC_IOREQ_ABTS_COMPLETE, @@ -348,6 +349,8 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic
[PATCH 05/10] fnic: fnic driver may hit BUG_ON on device reset
The issue was observed when LUN Reset is issued through IOCTL or sg_reset utility. fnic driver issues LUN RESET to firmware. On successful completion of device reset, driver cleans up all the pending IOs that were issued prior to device reset. These pending IOs are expected to be in ABTS_PENDING state. This works fine, when the device reset operation resulted from midlayer, but not when device reset was triggered from IOCTL path as the pending IOs were not in ABTS_PENDING state. execution path hits panic if the pending IO is not in ABTS_PENDING state. Changes: The fix replaces BUG_ON check in fnic_clean_pending_aborts() with marking pending IOs as ABTS_PENDING if they were not in ABTS_PENDING state and skips if they were already in ABTS_PENDING state. An extra check is added to validate the abort status of the commands after a delay of 2 * E_D_TOV using a helper function. The helper function returns 1 if it finds any pending IO in ABTS_PENDING state, belong to the LUN on which device reset was issued else 0. With this, device reset operation returns success only if the helper funciton returns 0, otherwise it returns failure. Other changes: - Removed code in fnic_clean_pending_aborts() that returns failure if it finds io_req NULL, instead of returning failure added code to continue with next io - Added device reset flags for debugging in fnic_terminate_rport_io, fnic_rport_exch_reset, and fnic_clean_pending_aborts Signed-off-by: Narsimhulu Musini nmus...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h |2 + drivers/scsi/fnic/fnic_scsi.c | 121 ++--- 2 files changed, 116 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 2403c62..9b62fc3 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -303,6 +303,8 @@ const char *fnic_state_to_str(unsigned int state); void fnic_log_q_error(struct fnic *fnic); void fnic_handle_link_event(struct fnic *fnic); +int fnic_is_abts_pending(struct fnic *, struct scsi_cmnd *); + static inline int fnic_chk_state_flags_locked(struct fnic *fnic, u64 __bitwise__ st_flags) { diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index 188bc5f..a9f436c 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -1274,7 +1274,8 @@ void fnic_rport_exch_reset(struct fnic *fnic, u32 port_id) spin_unlock_irqrestore(io_lock, flags); } else { spin_lock_irqsave(io_lock, flags); - CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED; + if (CMD_FLAGS(sc) FNIC_DEVICE_RESET) + CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED; spin_unlock_irqrestore(io_lock, flags); } } @@ -1393,7 +1394,8 @@ void fnic_terminate_rport_io(struct fc_rport *rport) spin_unlock_irqrestore(io_lock, flags); } else { spin_lock_irqsave(io_lock, flags); - CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED; + if (CMD_FLAGS(sc) FNIC_DEVICE_RESET) + CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED; spin_unlock_irqrestore(io_lock, flags); } } @@ -1606,7 +1608,7 @@ lr_io_req_end: static int fnic_clean_pending_aborts(struct fnic *fnic, struct scsi_cmnd *lr_sc) { - int tag; + int tag, abt_tag; struct fnic_io_req *io_req; spinlock_t *io_lock; unsigned long flags; @@ -1615,6 +1617,7 @@ static int fnic_clean_pending_aborts(struct fnic *fnic, struct scsi_lun fc_lun; struct scsi_device *lun_dev = lr_sc-device; DECLARE_COMPLETION_ONSTACK(tm_done); + enum fnic_ioreq_state old_ioreq_state; for (tag = 0; tag FNIC_MAX_IO_REQ; tag++) { sc = scsi_host_find_tag(fnic-lport-host, tag); @@ -1643,7 +1646,41 @@ static int fnic_clean_pending_aborts(struct fnic *fnic, Found IO in %s on lun\n, fnic_ioreq_state_to_str(CMD_STATE(sc))); - BUG_ON(CMD_STATE(sc) != FNIC_IOREQ_ABTS_PENDING); + if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) { + spin_unlock_irqrestore(io_lock, flags); + continue; + } + if ((CMD_FLAGS(sc) FNIC_DEVICE_RESET) + (!(CMD_FLAGS(sc) FNIC_DEV_RST_PENDING))) { + FNIC_SCSI_DBG(KERN_INFO, fnic-lport-host, + %s dev rst not pending sc 0x%p\n, __func__, + sc); + spin_unlock_irqrestore(io_lock, flags); + continue; + } + old_ioreq_state
[PATCH 06/10] fnic: New debug flags and debug log messages
Added new fnic debug flags for identifying IO state at every stage of IO while debugging and also added more log messages for better debugging capability. Signed-off-by: Sesidhar Baddela sebad...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h | 32 --- drivers/scsi/fnic/fnic_io.h |4 +- drivers/scsi/fnic/fnic_scsi.c | 121 + 3 files changed, 136 insertions(+), 21 deletions(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 9b62fc3..cba8c0e 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -50,6 +50,7 @@ /* * Tag bits used for special requests. */ +#define BIT(nr)(1UL (nr)) #define FNIC_TAG_ABORT BIT(30) /* tag bit indicating abort */ #define FNIC_TAG_DEV_RST BIT(29) /* indicates device reset */ #define FNIC_TAG_MASK (BIT(24) - 1) /* mask for lookup */ @@ -59,14 +60,29 @@ * Command flags to identify the type of command and for other future * use. */ -#define FNIC_NO_FLAGS 0 -#define FNIC_CDB_REQ BIT(1) /* All IOs with a valid CDB */ -#define FNIC_BLOCKING_REQ BIT(2) /* All blocking Requests */ -#define FNIC_DEVICE_RESET BIT(3) /* Device reset request */ -#define FNIC_DEV_RST_PENDING BIT(4) /* Device reset pending */ -#define FNIC_DEV_RST_TIMED_OUT BIT(5) /* Device reset timed out */ -#define FNIC_DEV_RST_TERM_ISSUED BIT(6) /* Device reset terminate */ -#define FNIC_DEV_RST_DONE BIT(7) /* Device reset done */ +#define FNIC_NO_FLAGS 0 +#define FNIC_IO_INITIALIZED BIT(0) +#define FNIC_IO_ISSUED BIT(1) +#define FNIC_IO_DONEBIT(2) +#define FNIC_IO_REQ_NULLBIT(3) +#define FNIC_IO_ABTS_PENDINGBIT(4) +#define FNIC_IO_ABORTED BIT(5) +#define FNIC_IO_ABTS_ISSUED BIT(6) +#define FNIC_IO_TERM_ISSUED BIT(7) +#define FNIC_IO_INTERNAL_TERM_ISSUEDBIT(8) +#define FNIC_IO_ABT_TERM_DONE BIT(9) +#define FNIC_IO_ABT_TERM_REQ_NULL BIT(10) +#define FNIC_IO_ABT_TERM_TIMED_OUT BIT(11) +#define FNIC_DEVICE_RESET BIT(12) /* Device reset request */ +#define FNIC_DEV_RST_ISSUED BIT(13) +#define FNIC_DEV_RST_TIMED_OUT BIT(14) +#define FNIC_DEV_RST_ABTS_ISSUEDBIT(15) +#define FNIC_DEV_RST_TERM_ISSUEDBIT(16) +#define FNIC_DEV_RST_DONE BIT(17) +#define FNIC_DEV_RST_REQ_NULL BIT(18) +#define FNIC_DEV_RST_ABTS_DONE BIT(19) +#define FNIC_DEV_RST_TERM_DONE BIT(20) +#define FNIC_DEV_RST_ABTS_PENDING BIT(21) /* * Usage of the scsi_cmnd scratchpad. diff --git a/drivers/scsi/fnic/fnic_io.h b/drivers/scsi/fnic/fnic_io.h index 3455c34..c35b8f1 100644 --- a/drivers/scsi/fnic/fnic_io.h +++ b/drivers/scsi/fnic/fnic_io.h @@ -45,7 +45,8 @@ enum fnic_sgl_list_type { }; enum fnic_ioreq_state { - FNIC_IOREQ_CMD_PENDING = 0, + FNIC_IOREQ_NOT_INITED = 0, + FNIC_IOREQ_CMD_PENDING, FNIC_IOREQ_ABTS_PENDING, FNIC_IOREQ_ABTS_COMPLETE, FNIC_IOREQ_CMD_COMPLETE, @@ -60,6 +61,7 @@ struct fnic_io_req { u8 sgl_type; /* device DMA descriptor list type */ u8 io_completed:1; /* set to 1 when fw completes IO */ u32 port_id; /* remote port DID */ + unsigned long start_time; /* in jiffies */ struct completion *abts_done; /* completion for abts */ struct completion *dr_done; /* completion for device reset */ }; diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index a9f436c..e1e817f 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -47,6 +47,7 @@ const char *fnic_state_str[] = { }; static const char *fnic_ioreq_state_str[] = { + [FNIC_IOREQ_NOT_INITED] = FNIC_IOREQ_NOT_INITED, [FNIC_IOREQ_CMD_PENDING] = FNIC_IOREQ_CMD_PENDING, [FNIC_IOREQ_ABTS_PENDING] = FNIC_IOREQ_ABTS_PENDING, [FNIC_IOREQ_ABTS_COMPLETE] = FNIC_IOREQ_ABTS_COMPLETE, @@ -348,6 +349,8 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic, if (unlikely(!vnic_wq_copy_desc_avail(wq))) { spin_unlock_irqrestore(fnic-wq_copy_lock[0], intr_flags); + FNIC_SCSI_DBG(KERN_INFO, fnic-lport-host, + fnic_queue_wq_copy_desc failure - no descriptors\n); return SCSI_MLQUEUE_HOST_BUSY; } @@ -419,7 +422,8 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_ * caller disabling them. */ spin_unlock(lp-host-host_lock); - CMD_FLAGS(sc) = FNIC_CDB_REQ; + CMD_STATE(sc) = FNIC_IOREQ_NOT_INITED; + CMD_FLAGS(sc) = FNIC_NO_FLAGS; /* Get a new io_req for this SCSI IO */ io_req
[PATCH 07/10] fnic: Fnic Trace Utility
Fnic Trace utility is a tracing functionality built directly into fnic driver to trace events. The benefit that trace buffer brings to fnic driver is the ability to see what it happening inside the fnic driver. It also provides the capability to trace every IO event inside fnic driver to debug panics, hangs and potentially IO corruption issues. This feature makes it easy to find problems in fnic driver and it also helps in tracking down strange bugs in a more manageable way. Trace buffer is shared across all fnic instances for this implementation. Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/Makefile |2 + drivers/scsi/fnic/fnic.h |1 + drivers/scsi/fnic/fnic_debugfs.c | 312 ++ drivers/scsi/fnic/fnic_main.c| 14 ++ drivers/scsi/fnic/fnic_scsi.c| 120 +-- drivers/scsi/fnic/fnic_trace.c | 260 +++ drivers/scsi/fnic/fnic_trace.h | 80 ++ 7 files changed, 778 insertions(+), 11 deletions(-) create mode 100644 drivers/scsi/fnic/fnic_debugfs.c create mode 100644 drivers/scsi/fnic/fnic_trace.c create mode 100644 drivers/scsi/fnic/fnic_trace.h diff --git a/drivers/scsi/fnic/Makefile b/drivers/scsi/fnic/Makefile index 37c3440..383598f 100644 --- a/drivers/scsi/fnic/Makefile +++ b/drivers/scsi/fnic/Makefile @@ -7,6 +7,8 @@ fnic-y := \ fnic_res.o \ fnic_fcs.o \ fnic_scsi.o \ + fnic_trace.o \ + fnic_debugfs.o \ vnic_cq.o \ vnic_dev.o \ vnic_intr.o \ diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index cba8c0e..e03a3c6 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -26,6 +26,7 @@ #include scsi/libfcoe.h #include fnic_io.h #include fnic_res.h +#include fnic_trace.h #include vnic_dev.h #include vnic_wq.h #include vnic_rq.h diff --git a/drivers/scsi/fnic/fnic_debugfs.c b/drivers/scsi/fnic/fnic_debugfs.c new file mode 100644 index 000..d89fc04 --- /dev/null +++ b/drivers/scsi/fnic/fnic_debugfs.c @@ -0,0 +1,312 @@ +/* + * Copyright 2012 Cisco Systems, Inc. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include linux/module.h +#include linux/errno.h +#include linux/debugfs.h +#include fnic.h + +static struct dentry *fnic_trace_debugfs_root; +static struct dentry *fnic_trace_debugfs_file; +static struct dentry *fnic_trace_enable; + +/* + * fnic_trace_ctrl_open - Open the trace_enable file + * @inode: The inode pointer. + * @file: The file pointer to attach the trace enable/disable flag. + * + * Description: + * This routine opens a debugsfs file trace_enable. + * + * Returns: + * This function returns zero if successful. + */ +int fnic_trace_ctrl_open(struct inode *inode, struct file *filp) +{ + filp-private_data = inode-i_private; + return 0; +} + +/* + * fnic_trace_ctrl_read - Read a trace_enable debugfs file + * @filp: The file pointer to read from. + * @ubuf: The buffer to copy the data to. + * @cnt: The number of bytes to read. + * @ppos: The position in the file to start reading from. + * + * Description: + * This routine reads value of variable fnic_tracing_enabled + * and stores into local @buf. It will start reading file at @ppos and + * copy up to @cnt of data to @ubuf from @buf. + * + * Returns: + * This function returns the amount of data that was read. + */ +static ssize_t fnic_trace_ctrl_read(struct file *filp, + char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + char buf[64]; + int len; + len = sprintf(buf, %u\n, fnic_tracing_enabled); + + return simple_read_from_buffer(ubuf, cnt, ppos, buf, len); +} + +/* + * fnic_trace_ctrl_write - Write to trace_enable debugfs file + * @filp: The file pointer to write from. + * @ubuf: The buffer to copy the data from. + * @cnt: The number of bytes to write. + * @ppos: The position in the file to start writing to. + * + * Description: + * This routine writes data from user buffer @ubuf to buffer @buf and + * sets fnic_tracing_enabled value as per user input. + * + * Returns: + * This function returns the amount of data that was written. + */ +static ssize_t fnic_trace_ctrl_write(struct file *filp, + const
[PATCH 08/10] fnic: FIP VLAN Discovery Feature Support
FIP VLAN discovery discovers the FCoE VLAN that will be used by all other FIP protocols as well as by the FCoE encapsulation for Fibre Channel payloads on the established virtual link. One of the goals of FC-BB-5 was to be as nonintrusive as possible on initiators and targets, and therefore FIP VLAN discovery occurs in the native VLAN used by the initiator or target to exchange Ethernet traffic. The FIP VLAN discovery protocol is the only FIP protocol running on the native VLAN; all other FIP protocols run on the discovered FCoE VLANs. If an administrator has manually configured FCoE VLANs on ENodes and FCFs, there is no need to use this protocol. FIP and FCoE will run over the configured VLANs. An ENode without FCoE VLANs configuration would use this automated discovery protocol to discover over which VLANs FCoE is running. The ENode sends a FIP VLAN discovery request to a multicast MAC address called All-FCF-MACs, which is a multicast MAC address to which all FCFs listen. All FCFs that can be reached in the native VLAN of the ENode are expected to respond on the same VLAN with a response that lists one or more FCoE VLANs that are available for the ENode's VN_Port login. This protocol has the sole purpose of allowing the ENode to discover all the available FCoE VLANs. Now the ENode may enable a subset of these VLANs for FCoE Running the FIP protocol in these VLANs on a per VLAN basis. And FCoE data transactions also would occur on this VLAN. Hence, Except for FIP VLAN discovery, all other FIP and FCoE traffic runs on the selected FCoE VLAN. Its only the FIP VLAN Discovery protocol that is permitted to run on the Default native VLAN of the system. [ NOTE ] We are working on moving this feature definitions and functionality to libfcoe module. We need this patch to be approved, as Suse is looking forward to merge this feature in SLES 11 SP3 release. Once this patch is approved, we will submit patch which should move vlan discovery feature to libfoce. Signed-off-by: Anantha Prakash T atung...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h| 32 +++ drivers/scsi/fnic/fnic_fcs.c| 557 ++- drivers/scsi/fnic/fnic_fip.h| 68 + drivers/scsi/fnic/fnic_main.c | 51 +++- drivers/scsi/fnic/vnic_dev.c| 10 + drivers/scsi/fnic/vnic_dev.h|2 + drivers/scsi/fnic/vnic_devcmd.h | 67 + 7 files changed, 783 insertions(+), 4 deletions(-) create mode 100644 drivers/scsi/fnic/fnic_fip.h diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index e03a3c6..2adbda4 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -193,6 +193,18 @@ enum fnic_state { struct mempool; +enum fnic_evt { + FNIC_EVT_START_VLAN_DISC = 1, + FNIC_EVT_START_FCF_DISC = 2, + FNIC_EVT_MAX, +}; + +struct fnic_event { + struct list_head list; + struct fnic *fnic; + enum fnic_evt event; +}; + /* Per-instance private data structure */ struct fnic { struct fc_lport *lport; @@ -255,6 +267,18 @@ struct fnic { struct sk_buff_head frame_queue; struct sk_buff_head tx_queue; + /*** FIP related data members -- start ***/ + void (*set_vlan)(struct fnic *, u16 vlan); + struct work_struct fip_frame_work; + struct sk_buff_head fip_frame_queue; + struct timer_list fip_timer; + struct list_headvlans; + spinlock_t vlans_lock; + + struct work_struct event_work; + struct list_headevlist; + /*** FIP related data members -- end ***/ + /* copy work queue cache line section */ cacheline_aligned struct vnic_wq_copy wq_copy[FNIC_WQ_COPY_MAX]; /* completion queue cache line section */ @@ -279,6 +303,7 @@ static inline struct fnic *fnic_from_ctlr(struct fcoe_ctlr *fip) } extern struct workqueue_struct *fnic_event_queue; +extern struct workqueue_struct *fnic_fip_queue; extern struct device_attribute *fnic_attrs[]; void fnic_clear_intr_mode(struct fnic *fnic); @@ -290,6 +315,7 @@ int fnic_send(struct fc_lport *, struct fc_frame *); void fnic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf); void fnic_handle_frame(struct work_struct *work); void fnic_handle_link(struct work_struct *work); +void fnic_handle_event(struct work_struct *work); int fnic_rq_cmpl_handler(struct fnic *fnic, int); int fnic_alloc_rq_frame(struct vnic_rq *rq); void fnic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf); @@ -322,6 +348,12 @@ void fnic_handle_link_event(struct fnic *fnic); int fnic_is_abts_pending(struct fnic *, struct scsi_cmnd *); +void fnic_handle_fip_frame(struct work_struct *work); +void fnic_handle_fip_event(struct fnic *fnic); +void fnic_fcoe_reset_vlans(struct fnic *fnic); +void fnic_fcoe_evlist_free(struct fnic *fnic); +extern void fnic_handle_fip_timer(struct fnic *fnic
Re: [PATCH 05/10] fnic: fnic driver may hit BUG_ON on device reset
Just submitted 05, 06, 07 and 08 fnic patches after verifying compilation of each patch independently. Thanks, Hiral On 12/17/12 3:24 AM, James Bottomley james.bottom...@hansenpartnership.com wrote: On Mon, 2012-12-10 at 01:21 -0800, Hiral Patel wrote: The issue was observed when LUN Reset is issued through IOCTL or sg_reset utility. fnic driver issues LUN RESET to firmware. On successful completion of device reset, driver cleans up all the pending IOs that were issued prior to device reset. These pending IOs are expected to be in ABTS_PENDING state. This works fine, when the device reset operation resulted from midlayer, but not when device reset was triggered from IOCTL path as the pending IOs were not in ABTS_PENDING state. execution path hits panic if the pending IO is not in ABTS_PENDING state. Changes: The fix replaces BUG_ON check in fnic_clean_pending_aborts() with marking pending IOs as ABTS_PENDING if they were not in ABTS_PENDING state and skips if they were already in ABTS_PENDING state. An extra check is added to validate the abort status of the commands after a delay of 2 * E_D_TOV using a helper function. The helper function returns 1 if it finds any pending IO in ABTS_PENDING state, belong to the LUN on which device reset was issued else 0. With this, device reset operation returns success only if the helper funciton returns 0, otherwise it returns failure. Other changes: - Removed code in fnic_clean_pending_aborts() that returns failure if it finds io_req NULL, instead of returning failure added code to continue with next io - Added device reset flags for debugging in fnic_terminate_rport_io, fnic_rport_exch_reset, and fnic_clean_pending_aborts Signed-off-by: Narsimhulu Musini nmus...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com This one doesn't compile: drivers/scsi/fnic/fnic_scsi.c: In function Œfnic_clean_pending_aborts¹: drivers/scsi/fnic/fnic_scsi.c:1654:23: error: ŒFNIC_DEV_RST_ISSUED¹ undeclared (first use in this function) drivers/scsi/fnic/fnic_scsi.c:1654:23: note: each undeclared identifier is reported only once for each function it appears in make[3]: *** [drivers/scsi/fnic/fnic_scsi.o] Error 1 And that's because FNIC_DEV_RST_ISSUED isn't #defined until PATCH 06/10 Please redo 05-10 this time making sure they compile in sequence in order to maintain bisectability Thanks, James -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/10] fnic: updated MAINTAINERS list
Updated MAINTAINERS list for fnic driver with appropriate names and email ids. Signed-off-by: Brian Uchino buch...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- MAINTAINERS |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index f935a0c..f6f310d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1871,8 +1871,8 @@ S:Maintained F: include/linux/clk.h CISCO FCOE HBA DRIVER -M: Abhijeet Joglekar abjog...@cisco.com -M: Venkata Siva Vijayendra Bhamidipati vbham...@cisco.com +M: Hiral Patel hiral...@cisco.com +M: Suma Ramars sram...@cisco.com M: Brian Uchino buch...@cisco.com L: linux-scsi@vger.kernel.org S: Supported -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/10] fnic: fix for trusted cos
Modified fnic driver to let hardware insert the COS value. Set bit in descriptor to 0 telling hardware to use its lif COS configurations to insert the COS value in the frames. Signed-off-by: Narsimhulu Musini nmus...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_fcs.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c index 3c53c34..483eb9d 100644 --- a/drivers/scsi/fnic/fnic_fcs.c +++ b/drivers/scsi/fnic/fnic_fcs.c @@ -495,7 +495,8 @@ void fnic_eth_send(struct fcoe_ctlr *fip, struct sk_buff *skb) } fnic_queue_wq_eth_desc(wq, skb, pa, skb-len, - fnic-vlan_hw_insert, fnic-vlan_id, 1); + 0 /* hw inserts cos value */, + fnic-vlan_id, 1); spin_unlock_irqrestore(fnic-wq_lock[0], flags); } @@ -563,7 +564,8 @@ static int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp) } fnic_queue_wq_desc(wq, skb, pa, tot_len, fr_eof(fp), - fnic-vlan_hw_insert, fnic-vlan_id, 1, 1, 1); + 0 /* hw inserts cos value */, + fnic-vlan_id, 1, 1, 1); fnic_send_frame_end: spin_unlock_irqrestore(fnic-wq_lock[0], flags); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 05/10] fnic: fnic driver may hit BUG_ON on device reset
The issue was observed when LUN Reset is issued through IOCTL or sg_reset utility. fnic driver issues LUN RESET to firmware. On successful completion of device reset, driver cleans up all the pending IOs that were issued prior to device reset. These pending IOs are expected to be in ABTS_PENDING state. This works fine, when the device reset operation resulted from midlayer, but not when device reset was triggered from IOCTL path as the pending IOs were not in ABTS_PENDING state. execution path hits panic if the pending IO is not in ABTS_PENDING state. Changes: The fix replaces BUG_ON check in fnic_clean_pending_aborts() with marking pending IOs as ABTS_PENDING if they were not in ABTS_PENDING state and skips if they were already in ABTS_PENDING state. An extra check is added to validate the abort status of the commands after a delay of 2 * E_D_TOV using a helper function. The helper function returns 1 if it finds any pending IO in ABTS_PENDING state, belong to the LUN on which device reset was issued else 0. With this, device reset operation returns success only if the helper funciton returns 0, otherwise it returns failure. Other changes: - Removed code in fnic_clean_pending_aborts() that returns failure if it finds io_req NULL, instead of returning failure added code to continue with next io - Added device reset flags for debugging in fnic_terminate_rport_io, fnic_rport_exch_reset, and fnic_clean_pending_aborts Signed-off-by: Narsimhulu Musini nmus...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h |2 + drivers/scsi/fnic/fnic_scsi.c | 121 ++--- 2 files changed, 116 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 2403c62..9b62fc3 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -303,6 +303,8 @@ const char *fnic_state_to_str(unsigned int state); void fnic_log_q_error(struct fnic *fnic); void fnic_handle_link_event(struct fnic *fnic); +int fnic_is_abts_pending(struct fnic *, struct scsi_cmnd *); + static inline int fnic_chk_state_flags_locked(struct fnic *fnic, u64 __bitwise__ st_flags) { diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index 188bc5f..4b1fdb8 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -1274,7 +1274,8 @@ void fnic_rport_exch_reset(struct fnic *fnic, u32 port_id) spin_unlock_irqrestore(io_lock, flags); } else { spin_lock_irqsave(io_lock, flags); - CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED; + if (CMD_FLAGS(sc) FNIC_DEVICE_RESET) + CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED; spin_unlock_irqrestore(io_lock, flags); } } @@ -1393,7 +1394,8 @@ void fnic_terminate_rport_io(struct fc_rport *rport) spin_unlock_irqrestore(io_lock, flags); } else { spin_lock_irqsave(io_lock, flags); - CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED; + if (CMD_FLAGS(sc) FNIC_DEVICE_RESET) + CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED; spin_unlock_irqrestore(io_lock, flags); } } @@ -1606,7 +1608,7 @@ lr_io_req_end: static int fnic_clean_pending_aborts(struct fnic *fnic, struct scsi_cmnd *lr_sc) { - int tag; + int tag, abt_tag; struct fnic_io_req *io_req; spinlock_t *io_lock; unsigned long flags; @@ -1615,6 +1617,7 @@ static int fnic_clean_pending_aborts(struct fnic *fnic, struct scsi_lun fc_lun; struct scsi_device *lun_dev = lr_sc-device; DECLARE_COMPLETION_ONSTACK(tm_done); + enum fnic_ioreq_state old_ioreq_state; for (tag = 0; tag FNIC_MAX_IO_REQ; tag++) { sc = scsi_host_find_tag(fnic-lport-host, tag); @@ -1643,7 +1646,41 @@ static int fnic_clean_pending_aborts(struct fnic *fnic, Found IO in %s on lun\n, fnic_ioreq_state_to_str(CMD_STATE(sc))); - BUG_ON(CMD_STATE(sc) != FNIC_IOREQ_ABTS_PENDING); + if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) { + spin_unlock_irqrestore(io_lock, flags); + continue; + } + if ((CMD_FLAGS(sc) FNIC_DEVICE_RESET) + (!(CMD_FLAGS(sc) FNIC_DEV_RST_ISSUED))) { + FNIC_SCSI_DBG(KERN_INFO, fnic-lport-host, + %s dev rst not pending sc 0x%p\n, __func__, + sc); + spin_unlock_irqrestore(io_lock, flags); + continue; + } + old_ioreq_state
[PATCH 03/10] fnic:fixing issues in device and firmware reset code
1. Handling overlapped firmware resets This fix serialize multiple firmware resets to avoid situation where fnic device fails to come up for link up event, when firmware resets are issued back to back. If there are overlapped firmware resets are issued, the firmware reset operation checks whether there is any firmware reset in progress, if so it polls for its completion in a loop with 100ms delay. 2. Handling device reset timeout fnic_device_reset code has been modified to handle Device reset timeout: - Issue terminate on device reset timeout. - Introduced flags field (one of the scratch fields in scsi_cmnd). With this, device reset request would have DEVICE_RESET flag set for other routines to determine the type of the request. Also modified fnic_terminate_rport_io, fnic_rport_exch_rset, completion routines to handle SCSI commands with DEVICE_RESET flag. 3. LUN/Device Reset hangs when issued through IOCTL using utilities like sg_reset. Each SCSI command is associated with a valid tag, fnic uses this tag to retrieve associated scsi command on completion. the LUN/Device Reset issued through IOCTL resulting into a SCSI command that is not associated with a valid tag. So fnic fails to retrieve associated scsi command on completion, which causes hang. This fix allocates tag, associates it with the scsi command and frees the tag, when the operation completed. 4. Preventing IOs during firmware reset. Current fnic implementation allows IO submissions during firmware reset. This fix synchronizes IO submissions and firmware reset operations. It ensures that IOs issued to fnic prior to reset will be issued to the firmware before firmware reset. Signed-off-by: Narsimhulu Musini nmus...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h | 42 + drivers/scsi/fnic/fnic_main.c |3 + drivers/scsi/fnic/fnic_scsi.c | 396 + 3 files changed, 410 insertions(+), 31 deletions(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 95a5ba2..2403c62 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -56,6 +56,19 @@ #define FNIC_NO_TAG -1 /* + * Command flags to identify the type of command and for other future + * use. + */ +#define FNIC_NO_FLAGS 0 +#define FNIC_CDB_REQ BIT(1) /* All IOs with a valid CDB */ +#define FNIC_BLOCKING_REQ BIT(2) /* All blocking Requests */ +#define FNIC_DEVICE_RESET BIT(3) /* Device reset request */ +#define FNIC_DEV_RST_PENDING BIT(4) /* Device reset pending */ +#define FNIC_DEV_RST_TIMED_OUT BIT(5) /* Device reset timed out */ +#define FNIC_DEV_RST_TERM_ISSUED BIT(6) /* Device reset terminate */ +#define FNIC_DEV_RST_DONE BIT(7) /* Device reset done */ + +/* * Usage of the scsi_cmnd scratchpad. * These fields are locked by the hashed io_req_lock. */ @@ -64,6 +77,7 @@ #define CMD_ABTS_STATUS(Cmnd) ((Cmnd)-SCp.Message) #define CMD_LR_STATUS(Cmnd)((Cmnd)-SCp.have_data_in) #define CMD_TAG(Cmnd) ((Cmnd)-SCp.sent_command) +#define CMD_FLAGS(Cmnd) ((Cmnd)-SCp.Status) #define FCPIO_INVALID_CODE 0x100 /* hdr_status value unused by firmware */ @@ -71,9 +85,28 @@ #define FNIC_HOST_RESET_TIMEOUT 1 /* mSec */ #define FNIC_RMDEVICE_TIMEOUT1000 /* mSec */ #define FNIC_HOST_RESET_SETTLE_TIME 30 /* Sec */ +#define FNIC_ABT_TERM_DELAY_TIMEOUT 500/* mSec */ #define FNIC_MAX_FCP_TARGET 256 +/** + * state_flags to identify host state along along with fnic's state + **/ +#define __FNIC_FLAGS_FWRESET BIT(0) /* fwreset in progress */ +#define __FNIC_FLAGS_BLOCK_IO BIT(1) /* IOs are blocked */ + +#define FNIC_FLAGS_NONE(0) +#define FNIC_FLAGS_FWRESET (__FNIC_FLAGS_FWRESET | \ + __FNIC_FLAGS_BLOCK_IO) + +#define FNIC_FLAGS_IO_BLOCKED (__FNIC_FLAGS_BLOCK_IO) + +#define fnic_set_state_flags(fnicp, st_flags) \ + __fnic_set_state_flags(fnicp, st_flags, 0) + +#define fnic_clear_state_flags(fnicp, st_flags) \ + __fnic_set_state_flags(fnicp, st_flags, 1) + extern unsigned int fnic_log_level; #define FNIC_MAIN_LOGGING 0x01 @@ -170,6 +203,9 @@ struct fnic { struct completion *remove_wait; /* device remove thread blocks */ + atomic_t in_flight; /* io counter */ + u32 _reserved; /* fill hole */ + u64 __bitwise__ state_flags;/* protected by host lock */ enum fnic_state state; spinlock_t fnic_lock; @@ -267,4 +303,10 @@ const char *fnic_state_to_str(unsigned int state); void fnic_log_q_error(struct fnic *fnic); void fnic_handle_link_event(struct fnic *fnic); +static inline
[PATCH 04/10] fnic: Fix SGEs limit
Driver allows IOs with more SGEs than max SGEs supported by Palo. The current max SGEs supported by the fnic driver is 1024. The current register settings on Palo supports a max of 256 only. Palo would return any IO with more than 256 SGEs with an error indicating INVALID_SGLS. Fnic driver should limit the max supported SGLs in the driver to 256 to avoid this error. Signed-off-by: Sesidhar Baddela sebad...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_io.h |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/fnic/fnic_io.h b/drivers/scsi/fnic/fnic_io.h index f0b8969..3455c34 100644 --- a/drivers/scsi/fnic/fnic_io.h +++ b/drivers/scsi/fnic/fnic_io.h @@ -21,7 +21,7 @@ #include scsi/fc/fc_fcp.h #define FNIC_DFLT_SG_DESC_CNT 32 -#define FNIC_MAX_SG_DESC_CNT1024/* Maximum descriptors per sgl */ +#define FNIC_MAX_SG_DESC_CNT256 /* Maximum descriptors per sgl */ #define FNIC_SG_DESC_ALIGN 16 /* Descriptor address alignment */ struct host_sg_desc { -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 9/9] fnic: FIP configuration mismatch between switch and adapter crashes driver
If switch configured in FIP and kirkwood lake configured in non-fip mode, panics while queueing FIP frame in non-existing fip_frame_queue. Added config check before queueing FIP frame in misconfiguration case to avoid kernel panic. Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_fcs.c |6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c index 0eb8b8c..5ce289f 100644 --- a/drivers/scsi/fnic/fnic_fcs.c +++ b/drivers/scsi/fnic/fnic_fcs.c @@ -603,6 +603,12 @@ static inline int fnic_import_rq_eth_pkt(struct fnic *fnic, struct sk_buff *skb) skb_reset_mac_header(skb); } if (eh-h_proto == htons(ETH_P_FIP)) { + if (!(fnic-config.flags VFCF_FIP_CAPABLE)) { + printk(KERN_ERR Dropped FIP frame, as firmware + uses non-FIP mode, Enable FIP + using UCSM\n); + goto drop; + } skb_queue_tail(fnic-fip_frame_queue, skb); queue_work(fnic_fip_queue, fnic-fip_frame_work); return 1; /* let caller know packet was used */ -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 07/10] fnic: Fnic Trace Utility
Fnic Trace utility is a tracing functionality built directly into fnic driver to trace events. The benefit that trace buffer brings to fnic driver is the ability to see what it happening inside the fnic driver. It also provides the capability to trace every IO event inside fnic driver to debug panics, hangs and potentially IO corruption issues. This feature makes it easy to find problems in fnic driver and it also helps in tracking down strange bugs in a more manageable way. Trace buffer is shared across all fnic instances for this implementation. Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/Makefile |2 + drivers/scsi/fnic/fnic.h |1 + drivers/scsi/fnic/fnic_debugfs.c | 312 ++ drivers/scsi/fnic/fnic_main.c| 14 ++ drivers/scsi/fnic/fnic_scsi.c| 120 +-- drivers/scsi/fnic/fnic_trace.c | 260 +++ drivers/scsi/fnic/fnic_trace.h | 80 ++ 7 files changed, 778 insertions(+), 11 deletions(-) create mode 100644 drivers/scsi/fnic/fnic_debugfs.c create mode 100644 drivers/scsi/fnic/fnic_trace.c create mode 100644 drivers/scsi/fnic/fnic_trace.h diff --git a/drivers/scsi/fnic/Makefile b/drivers/scsi/fnic/Makefile index 37c3440..2cec04e 100644 --- a/drivers/scsi/fnic/Makefile +++ b/drivers/scsi/fnic/Makefile @@ -7,6 +7,8 @@ fnic-y := \ fnic_res.o \ fnic_fcs.o \ fnic_scsi.o \ + fnic_trace.o \ + fnic_debugfc.o \ vnic_cq.o \ vnic_dev.o \ vnic_intr.o \ diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index cba8c0e..e03a3c6 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -26,6 +26,7 @@ #include scsi/libfcoe.h #include fnic_io.h #include fnic_res.h +#include fnic_trace.h #include vnic_dev.h #include vnic_wq.h #include vnic_rq.h diff --git a/drivers/scsi/fnic/fnic_debugfs.c b/drivers/scsi/fnic/fnic_debugfs.c new file mode 100644 index 000..d89fc04 --- /dev/null +++ b/drivers/scsi/fnic/fnic_debugfs.c @@ -0,0 +1,312 @@ +/* + * Copyright 2012 Cisco Systems, Inc. All rights reserved. + * + * This program is free software; you may redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include linux/module.h +#include linux/errno.h +#include linux/debugfs.h +#include fnic.h + +static struct dentry *fnic_trace_debugfs_root; +static struct dentry *fnic_trace_debugfs_file; +static struct dentry *fnic_trace_enable; + +/* + * fnic_trace_ctrl_open - Open the trace_enable file + * @inode: The inode pointer. + * @file: The file pointer to attach the trace enable/disable flag. + * + * Description: + * This routine opens a debugsfs file trace_enable. + * + * Returns: + * This function returns zero if successful. + */ +int fnic_trace_ctrl_open(struct inode *inode, struct file *filp) +{ + filp-private_data = inode-i_private; + return 0; +} + +/* + * fnic_trace_ctrl_read - Read a trace_enable debugfs file + * @filp: The file pointer to read from. + * @ubuf: The buffer to copy the data to. + * @cnt: The number of bytes to read. + * @ppos: The position in the file to start reading from. + * + * Description: + * This routine reads value of variable fnic_tracing_enabled + * and stores into local @buf. It will start reading file at @ppos and + * copy up to @cnt of data to @ubuf from @buf. + * + * Returns: + * This function returns the amount of data that was read. + */ +static ssize_t fnic_trace_ctrl_read(struct file *filp, + char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + char buf[64]; + int len; + len = sprintf(buf, %u\n, fnic_tracing_enabled); + + return simple_read_from_buffer(ubuf, cnt, ppos, buf, len); +} + +/* + * fnic_trace_ctrl_write - Write to trace_enable debugfs file + * @filp: The file pointer to write from. + * @ubuf: The buffer to copy the data from. + * @cnt: The number of bytes to write. + * @ppos: The position in the file to start writing to. + * + * Description: + * This routine writes data from user buffer @ubuf to buffer @buf and + * sets fnic_tracing_enabled value as per user input. + * + * Returns: + * This function returns the amount of data that was written. + */ +static ssize_t fnic_trace_ctrl_write(struct file *filp, + const
[PATCH 06/10] fnic: New debug flags and debug log messages
Added new fnic debug flags for identifying IO state at every stage of IO while debugging and also added more log messages for better debugging capability. Signed-off-by: Sesidhar Baddela sebad...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h | 32 --- drivers/scsi/fnic/fnic_io.h |4 +- drivers/scsi/fnic/fnic_scsi.c | 119 + 3 files changed, 135 insertions(+), 20 deletions(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 9b62fc3..cba8c0e 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -50,6 +50,7 @@ /* * Tag bits used for special requests. */ +#define BIT(nr)(1UL (nr)) #define FNIC_TAG_ABORT BIT(30) /* tag bit indicating abort */ #define FNIC_TAG_DEV_RST BIT(29) /* indicates device reset */ #define FNIC_TAG_MASK (BIT(24) - 1) /* mask for lookup */ @@ -59,14 +60,29 @@ * Command flags to identify the type of command and for other future * use. */ -#define FNIC_NO_FLAGS 0 -#define FNIC_CDB_REQ BIT(1) /* All IOs with a valid CDB */ -#define FNIC_BLOCKING_REQ BIT(2) /* All blocking Requests */ -#define FNIC_DEVICE_RESET BIT(3) /* Device reset request */ -#define FNIC_DEV_RST_PENDING BIT(4) /* Device reset pending */ -#define FNIC_DEV_RST_TIMED_OUT BIT(5) /* Device reset timed out */ -#define FNIC_DEV_RST_TERM_ISSUED BIT(6) /* Device reset terminate */ -#define FNIC_DEV_RST_DONE BIT(7) /* Device reset done */ +#define FNIC_NO_FLAGS 0 +#define FNIC_IO_INITIALIZED BIT(0) +#define FNIC_IO_ISSUED BIT(1) +#define FNIC_IO_DONEBIT(2) +#define FNIC_IO_REQ_NULLBIT(3) +#define FNIC_IO_ABTS_PENDINGBIT(4) +#define FNIC_IO_ABORTED BIT(5) +#define FNIC_IO_ABTS_ISSUED BIT(6) +#define FNIC_IO_TERM_ISSUED BIT(7) +#define FNIC_IO_INTERNAL_TERM_ISSUEDBIT(8) +#define FNIC_IO_ABT_TERM_DONE BIT(9) +#define FNIC_IO_ABT_TERM_REQ_NULL BIT(10) +#define FNIC_IO_ABT_TERM_TIMED_OUT BIT(11) +#define FNIC_DEVICE_RESET BIT(12) /* Device reset request */ +#define FNIC_DEV_RST_ISSUED BIT(13) +#define FNIC_DEV_RST_TIMED_OUT BIT(14) +#define FNIC_DEV_RST_ABTS_ISSUEDBIT(15) +#define FNIC_DEV_RST_TERM_ISSUEDBIT(16) +#define FNIC_DEV_RST_DONE BIT(17) +#define FNIC_DEV_RST_REQ_NULL BIT(18) +#define FNIC_DEV_RST_ABTS_DONE BIT(19) +#define FNIC_DEV_RST_TERM_DONE BIT(20) +#define FNIC_DEV_RST_ABTS_PENDING BIT(21) /* * Usage of the scsi_cmnd scratchpad. diff --git a/drivers/scsi/fnic/fnic_io.h b/drivers/scsi/fnic/fnic_io.h index 3455c34..c35b8f1 100644 --- a/drivers/scsi/fnic/fnic_io.h +++ b/drivers/scsi/fnic/fnic_io.h @@ -45,7 +45,8 @@ enum fnic_sgl_list_type { }; enum fnic_ioreq_state { - FNIC_IOREQ_CMD_PENDING = 0, + FNIC_IOREQ_NOT_INITED = 0, + FNIC_IOREQ_CMD_PENDING, FNIC_IOREQ_ABTS_PENDING, FNIC_IOREQ_ABTS_COMPLETE, FNIC_IOREQ_CMD_COMPLETE, @@ -60,6 +61,7 @@ struct fnic_io_req { u8 sgl_type; /* device DMA descriptor list type */ u8 io_completed:1; /* set to 1 when fw completes IO */ u32 port_id; /* remote port DID */ + unsigned long start_time; /* in jiffies */ struct completion *abts_done; /* completion for abts */ struct completion *dr_done; /* completion for device reset */ }; diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index 4b1fdb8..e1e817f 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -47,6 +47,7 @@ const char *fnic_state_str[] = { }; static const char *fnic_ioreq_state_str[] = { + [FNIC_IOREQ_NOT_INITED] = FNIC_IOREQ_NOT_INITED, [FNIC_IOREQ_CMD_PENDING] = FNIC_IOREQ_CMD_PENDING, [FNIC_IOREQ_ABTS_PENDING] = FNIC_IOREQ_ABTS_PENDING, [FNIC_IOREQ_ABTS_COMPLETE] = FNIC_IOREQ_ABTS_COMPLETE, @@ -348,6 +349,8 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic, if (unlikely(!vnic_wq_copy_desc_avail(wq))) { spin_unlock_irqrestore(fnic-wq_copy_lock[0], intr_flags); + FNIC_SCSI_DBG(KERN_INFO, fnic-lport-host, + fnic_queue_wq_copy_desc failure - no descriptors\n); return SCSI_MLQUEUE_HOST_BUSY; } @@ -419,7 +422,8 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_ * caller disabling them. */ spin_unlock(lp-host-host_lock); - CMD_FLAGS(sc) = FNIC_CDB_REQ; + CMD_STATE(sc) = FNIC_IOREQ_NOT_INITED; + CMD_FLAGS(sc) = FNIC_NO_FLAGS; /* Get a new io_req for this SCSI IO */ io_req
[PATCH 10/10] fnic: Incremented driver version
Incrementing driver versio after bug fixes and new feature commits. Signed-off-by: Brian Uchino buch...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 2adbda4..1f87af7 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -38,7 +38,7 @@ #define DRV_NAME fnic #define DRV_DESCRIPTIONCisco FCoE HBA Driver -#define DRV_VERSION1.5.0.2 +#define DRV_VERSION1.5.0.22 #define PFXDRV_NAME : #define DFX DRV_NAME %d: -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 08/10] fnic: FIP VLAN Discovery Feature Support
FIP VLAN discovery discovers the FCoE VLAN that will be used by all other FIP protocols as well as by the FCoE encapsulation for Fibre Channel payloads on the established virtual link. One of the goals of FC-BB-5 was to be as nonintrusive as possible on initiators and targets, and therefore FIP VLAN discovery occurs in the native VLAN used by the initiator or target to exchange Ethernet traffic. The FIP VLAN discovery protocol is the only FIP protocol running on the native VLAN; all other FIP protocols run on the discovered FCoE VLANs. If an administrator has manually configured FCoE VLANs on ENodes and FCFs, there is no need to use this protocol. FIP and FCoE will run over the configured VLANs. An ENode without FCoE VLANs configuration would use this automated discovery protocol to discover over which VLANs FCoE is running. The ENode sends a FIP VLAN discovery request to a multicast MAC address called All-FCF-MACs, which is a multicast MAC address to which all FCFs listen. All FCFs that can be reached in the native VLAN of the ENode are expected to respond on the same VLAN with a response that lists one or more FCoE VLANs that are available for the ENode's VN_Port login. This protocol has the sole purpose of allowing the ENode to discover all the available FCoE VLANs. Now the ENode may enable a subset of these VLANs for FCoE Running the FIP protocol in these VLANs on a per VLAN basis. And FCoE data transactions also would occur on this VLAN. Hence, Except for FIP VLAN discovery, all other FIP and FCoE traffic runs on the selected FCoE VLAN. Its only the FIP VLAN Discovery protocol that is permitted to run on the Default native VLAN of the system. [ NOTE ] We are working on moving this feature definitions and functionality to libfcoe module. We need this patch to be approved, as Suse is looking forward to merge this feature in SLES 11 SP3 release. Once this patch is approved, we will submit patch which should move vlan discovery feature to libfoce. Signed-off-by: Anantha Prakash T atung...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h| 32 +++ drivers/scsi/fnic/fnic_fcs.c| 557 ++- drivers/scsi/fnic/fnic_fip.h| 69 + drivers/scsi/fnic/fnic_main.c | 51 +++- drivers/scsi/fnic/vnic_dev.c| 10 + drivers/scsi/fnic/vnic_dev.h|2 + drivers/scsi/fnic/vnic_devcmd.h | 70 + 7 files changed, 787 insertions(+), 4 deletions(-) create mode 100644 drivers/scsi/fnic/fnic_fip.h diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index e03a3c6..2adbda4 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -193,6 +193,18 @@ enum fnic_state { struct mempool; +enum fnic_evt { + FNIC_EVT_START_VLAN_DISC = 1, + FNIC_EVT_START_FCF_DISC = 2, + FNIC_EVT_MAX, +}; + +struct fnic_event { + struct list_head list; + struct fnic *fnic; + enum fnic_evt event; +}; + /* Per-instance private data structure */ struct fnic { struct fc_lport *lport; @@ -255,6 +267,18 @@ struct fnic { struct sk_buff_head frame_queue; struct sk_buff_head tx_queue; + /*** FIP related data members -- start ***/ + void (*set_vlan)(struct fnic *, u16 vlan); + struct work_struct fip_frame_work; + struct sk_buff_head fip_frame_queue; + struct timer_list fip_timer; + struct list_headvlans; + spinlock_t vlans_lock; + + struct work_struct event_work; + struct list_headevlist; + /*** FIP related data members -- end ***/ + /* copy work queue cache line section */ cacheline_aligned struct vnic_wq_copy wq_copy[FNIC_WQ_COPY_MAX]; /* completion queue cache line section */ @@ -279,6 +303,7 @@ static inline struct fnic *fnic_from_ctlr(struct fcoe_ctlr *fip) } extern struct workqueue_struct *fnic_event_queue; +extern struct workqueue_struct *fnic_fip_queue; extern struct device_attribute *fnic_attrs[]; void fnic_clear_intr_mode(struct fnic *fnic); @@ -290,6 +315,7 @@ int fnic_send(struct fc_lport *, struct fc_frame *); void fnic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf); void fnic_handle_frame(struct work_struct *work); void fnic_handle_link(struct work_struct *work); +void fnic_handle_event(struct work_struct *work); int fnic_rq_cmpl_handler(struct fnic *fnic, int); int fnic_alloc_rq_frame(struct vnic_rq *rq); void fnic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf); @@ -322,6 +348,12 @@ void fnic_handle_link_event(struct fnic *fnic); int fnic_is_abts_pending(struct fnic *, struct scsi_cmnd *); +void fnic_handle_fip_frame(struct work_struct *work); +void fnic_handle_fip_event(struct fnic *fnic); +void fnic_fcoe_reset_vlans(struct fnic *fnic); +void fnic_fcoe_evlist_free(struct fnic *fnic); +extern void fnic_handle_fip_timer(struct fnic *fnic
[PATCH 09/10] fnic: Kernel panic due to FIP mode misconfiguration
If switch configured in FIP and adapter configured in non-fip mode, driver panics while queueing FIP frame in non-existing fip_frame_queue. Added config check before queueing FIP frame in misconfiguration case to avoid kernel panic. Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_fcs.c |6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c index 3810c0b..d1cc7a4 100644 --- a/drivers/scsi/fnic/fnic_fcs.c +++ b/drivers/scsi/fnic/fnic_fcs.c @@ -602,6 +602,12 @@ static inline int fnic_import_rq_eth_pkt(struct fnic *fnic, struct sk_buff *skb) skb_reset_mac_header(skb); } if (eh-h_proto == htons(ETH_P_FIP)) { + if (!(fnic-config.flags VFCF_FIP_CAPABLE)) { + printk(KERN_ERR Dropped FIP frame, as firmware + uses non-FIP mode, Enable FIP + using UCSM\n); + goto drop; + } skb_queue_tail(fnic-fip_frame_queue, skb); queue_work(fnic_fip_queue, fnic-fip_frame_work); return 1; /* let caller know packet was used */ -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] fnic: fix for trusted cos
Modified fnic driver to let hardware insert the COS value. Set bit in descriptor to 0 telling hardware to use its lif COS configurations to insert the COS value in the frames. Signed-off-by: Narsimhulu Musini nmus...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_fcs.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c index 3c53c34..483eb9d 100644 --- a/drivers/scsi/fnic/fnic_fcs.c +++ b/drivers/scsi/fnic/fnic_fcs.c @@ -495,7 +495,8 @@ void fnic_eth_send(struct fcoe_ctlr *fip, struct sk_buff *skb) } fnic_queue_wq_eth_desc(wq, skb, pa, skb-len, - fnic-vlan_hw_insert, fnic-vlan_id, 1); + 0 /* hw inserts cos value */, + fnic-vlan_id, 1); spin_unlock_irqrestore(fnic-wq_lock[0], flags); } @@ -563,7 +564,8 @@ static int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp) } fnic_queue_wq_desc(wq, skb, pa, tot_len, fr_eof(fp), - fnic-vlan_hw_insert, fnic-vlan_id, 1, 1, 1); + 0 /* hw inserts cos value */, + fnic-vlan_id, 1, 1, 1); fnic_send_frame_end: spin_unlock_irqrestore(fnic-wq_lock[0], flags); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] fnic: Fix SGEs limit
Driver allows IOs with more SGEs than max SGEs supported by Palo. The current max SGEs supported by the fnic driver is 1024. The current register settings on Palo supports a max of 256 only. Palo would return any IO with more than 256 SGEs with an error indicating INVALID_SGLS. Fnic driver should limit the max supported SGLs in the driver to 256 to avoid this error. Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_io.h |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/fnic/fnic_io.h b/drivers/scsi/fnic/fnic_io.h index f0b8969..3455c34 100644 --- a/drivers/scsi/fnic/fnic_io.h +++ b/drivers/scsi/fnic/fnic_io.h @@ -21,7 +21,7 @@ #include scsi/fc/fc_fcp.h #define FNIC_DFLT_SG_DESC_CNT 32 -#define FNIC_MAX_SG_DESC_CNT1024/* Maximum descriptors per sgl */ +#define FNIC_MAX_SG_DESC_CNT256 /* Maximum descriptors per sgl */ #define FNIC_SG_DESC_ALIGN 16 /* Descriptor address alignment */ struct host_sg_desc { -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] fnic:fixing issues in device and firmware reset code
1. Handling overlapped firmware resets This fix serialize multiple firmware resets to avoid situation where fnic device fails to come up for link up event, when firmware resets are issued back to back. If there are overlapped firmware resets are issued, the firmware reset operation checks whether there is any firmware reset in progress, if so it polls for its completion in a loop with 100ms delay. 2. Handling device reset timeout fnic_device_reset code has been modified to handle Device reset timeout: - Issue terminate on device reset timeout. - Introduced flags field (one of the scratch fields in scsi_cmnd). With this, device reset request would have DEVICE_RESET flag set for other routines to determine the type of the request. Also modified fnic_terminate_rport_io, fnic_rport_exch_rset, completion routines to handle SCSI commands with DEVICE_RESET flag. 3. LUN/Device Reset hangs when issued through IOCTL using utilities like sg_reset. Each SCSI command is associated with a valid tag, fnic uses this tag to retrieve associated scsi command on completion. the LUN/Device Reset issued through IOCTL resulting into a SCSI command that is not associated with a valid tag. So fnic fails to retrieve associated scsi command on completion, which causes hang. This fix allocates tag, associates it with the scsi command and frees the tag, when the operation completed. 4. Preventing IOs during firmware reset. Current fnic implementation allows IO submissions during firmware reset. This fix synchronizes IO submissions and firmware reset operations. It ensures that IOs issued to fnic prior to reset will be issued to the firmware before firmware reset. Signed-off-by: Narsimhulu Musini nmus...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h | 42 + drivers/scsi/fnic/fnic_main.c |3 + drivers/scsi/fnic/fnic_scsi.c | 395 + 3 files changed, 409 insertions(+), 31 deletions(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 95a5ba2..2403c62 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -56,6 +56,19 @@ #define FNIC_NO_TAG -1 /* + * Command flags to identify the type of command and for other future + * use. + */ +#define FNIC_NO_FLAGS 0 +#define FNIC_CDB_REQ BIT(1) /* All IOs with a valid CDB */ +#define FNIC_BLOCKING_REQ BIT(2) /* All blocking Requests */ +#define FNIC_DEVICE_RESET BIT(3) /* Device reset request */ +#define FNIC_DEV_RST_PENDING BIT(4) /* Device reset pending */ +#define FNIC_DEV_RST_TIMED_OUT BIT(5) /* Device reset timed out */ +#define FNIC_DEV_RST_TERM_ISSUED BIT(6) /* Device reset terminate */ +#define FNIC_DEV_RST_DONE BIT(7) /* Device reset done */ + +/* * Usage of the scsi_cmnd scratchpad. * These fields are locked by the hashed io_req_lock. */ @@ -64,6 +77,7 @@ #define CMD_ABTS_STATUS(Cmnd) ((Cmnd)-SCp.Message) #define CMD_LR_STATUS(Cmnd)((Cmnd)-SCp.have_data_in) #define CMD_TAG(Cmnd) ((Cmnd)-SCp.sent_command) +#define CMD_FLAGS(Cmnd) ((Cmnd)-SCp.Status) #define FCPIO_INVALID_CODE 0x100 /* hdr_status value unused by firmware */ @@ -71,9 +85,28 @@ #define FNIC_HOST_RESET_TIMEOUT 1 /* mSec */ #define FNIC_RMDEVICE_TIMEOUT1000 /* mSec */ #define FNIC_HOST_RESET_SETTLE_TIME 30 /* Sec */ +#define FNIC_ABT_TERM_DELAY_TIMEOUT 500/* mSec */ #define FNIC_MAX_FCP_TARGET 256 +/** + * state_flags to identify host state along along with fnic's state + **/ +#define __FNIC_FLAGS_FWRESET BIT(0) /* fwreset in progress */ +#define __FNIC_FLAGS_BLOCK_IO BIT(1) /* IOs are blocked */ + +#define FNIC_FLAGS_NONE(0) +#define FNIC_FLAGS_FWRESET (__FNIC_FLAGS_FWRESET | \ + __FNIC_FLAGS_BLOCK_IO) + +#define FNIC_FLAGS_IO_BLOCKED (__FNIC_FLAGS_BLOCK_IO) + +#define fnic_set_state_flags(fnicp, st_flags) \ + __fnic_set_state_flags(fnicp, st_flags, 0) + +#define fnic_clear_state_flags(fnicp, st_flags) \ + __fnic_set_state_flags(fnicp, st_flags, 1) + extern unsigned int fnic_log_level; #define FNIC_MAIN_LOGGING 0x01 @@ -170,6 +203,9 @@ struct fnic { struct completion *remove_wait; /* device remove thread blocks */ + atomic_t in_flight; /* io counter */ + u32 _reserved; /* fill hole */ + u64 __bitwise__ state_flags;/* protected by host lock */ enum fnic_state state; spinlock_t fnic_lock; @@ -267,4 +303,10 @@ const char *fnic_state_to_str(unsigned int state); void fnic_log_q_error(struct fnic *fnic); void fnic_handle_link_event(struct fnic *fnic); +static inline
[PATCH 1/3] fnic: fix for trusted cos
Modified fnic driver to let hardware insert the COS value. Set bit in descriptor to 0 telling hardware to use its lif COS configurations to insert the COS value in the frames. Signed-off-by: Narsimhulu Musini nmus...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_fcs.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c index 3c53c34..483eb9d 100644 --- a/drivers/scsi/fnic/fnic_fcs.c +++ b/drivers/scsi/fnic/fnic_fcs.c @@ -495,7 +495,8 @@ void fnic_eth_send(struct fcoe_ctlr *fip, struct sk_buff *skb) } fnic_queue_wq_eth_desc(wq, skb, pa, skb-len, - fnic-vlan_hw_insert, fnic-vlan_id, 1); + 0 /* hw inserts cos value */, + fnic-vlan_id, 1); spin_unlock_irqrestore(fnic-wq_lock[0], flags); } @@ -563,7 +564,8 @@ static int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp) } fnic_queue_wq_desc(wq, skb, pa, tot_len, fr_eof(fp), - fnic-vlan_hw_insert, fnic-vlan_id, 1, 1, 1); + 0 /* hw inserts cos value */, + fnic-vlan_id, 1, 1, 1); fnic_send_frame_end: spin_unlock_irqrestore(fnic-wq_lock[0], flags); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] fnic: Fix SGEs limit
Driver allows IOs with more SGEs than max SGEs supported by Palo. The current max SGEs supported by the fnic driver is 1024. The current register settings on Palo supports a max of 256 only. Palo would return any IO with more than 256 SGEs with an error indicating INVALID_SGLS. Fnic driver should limit the max supported SGLs in the driver to 256 to avoid this error. Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic_io.h |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/fnic/fnic_io.h b/drivers/scsi/fnic/fnic_io.h index f0b8969..3455c34 100644 --- a/drivers/scsi/fnic/fnic_io.h +++ b/drivers/scsi/fnic/fnic_io.h @@ -21,7 +21,7 @@ #include scsi/fc/fc_fcp.h #define FNIC_DFLT_SG_DESC_CNT 32 -#define FNIC_MAX_SG_DESC_CNT1024/* Maximum descriptors per sgl */ +#define FNIC_MAX_SG_DESC_CNT256 /* Maximum descriptors per sgl */ #define FNIC_SG_DESC_ALIGN 16 /* Descriptor address alignment */ struct host_sg_desc { -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] fnic:fixing issues in device and firmware reset code
1. Handling overlapped firmware resets This fix serialize multiple firmware resets to avoid situation where fnic device fails to come up for link up event, when firmware resets are issued back to back. If there are overlapped firmware resets are issued, the firmware reset operation checks whether there is any firmware reset in progress, if so it polls for its completion in a loop with 100ms delay. 2. Handling device reset timeout fnic_device_reset code has been modified to handle Device reset timeout: - Issue terminate on device reset timeout. - Introduced flags field (one of the scratch fields in scsi_cmnd). With this, device reset request would have DEVICE_RESET flag set for other routines to determine the type of the request. Also modified fnic_terminate_rport_io, fnic_rport_exch_rset, completion routines to handle SCSI commands with DEVICE_RESET flag. 3. LUN/Device Reset hangs when issued through IOCTL using utilities like sg_reset. Each SCSI command is associated with a valid tag, fnic uses this tag to retrieve associated scsi command on completion. the LUN/Device Reset issued through IOCTL resulting into a SCSI command that is not associated with a valid tag. So fnic fails to retrieve associated scsi command on completion, which causes hang. This fix allocates tag, associates it with the scsi command and frees the tag, when the operation completed. 4. Preventing IOs during firmware reset. Current fnic implementation allows IO submissions during firmware reset. This fix synchronizes IO submissions and firmware reset operations. It ensures that IOs issued to fnic prior to reset will be issued to the firmware before firmware reset. Signed-off-by: Narsimhulu Musini nmus...@cisco.com Signed-off-by: Hiral Patel hiral...@cisco.com --- drivers/scsi/fnic/fnic.h | 42 + drivers/scsi/fnic/fnic_main.c |3 + drivers/scsi/fnic/fnic_scsi.c | 395 + 3 files changed, 409 insertions(+), 31 deletions(-) diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index 95a5ba2..2403c62 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -56,6 +56,19 @@ #define FNIC_NO_TAG -1 /* + * Command flags to identify the type of command and for other future + * use. + */ +#define FNIC_NO_FLAGS 0 +#define FNIC_CDB_REQ BIT(1) /* All IOs with a valid CDB */ +#define FNIC_BLOCKING_REQ BIT(2) /* All blocking Requests */ +#define FNIC_DEVICE_RESET BIT(3) /* Device reset request */ +#define FNIC_DEV_RST_PENDING BIT(4) /* Device reset pending */ +#define FNIC_DEV_RST_TIMED_OUT BIT(5) /* Device reset timed out */ +#define FNIC_DEV_RST_TERM_ISSUED BIT(6) /* Device reset terminate */ +#define FNIC_DEV_RST_DONE BIT(7) /* Device reset done */ + +/* * Usage of the scsi_cmnd scratchpad. * These fields are locked by the hashed io_req_lock. */ @@ -64,6 +77,7 @@ #define CMD_ABTS_STATUS(Cmnd) ((Cmnd)-SCp.Message) #define CMD_LR_STATUS(Cmnd)((Cmnd)-SCp.have_data_in) #define CMD_TAG(Cmnd) ((Cmnd)-SCp.sent_command) +#define CMD_FLAGS(Cmnd) ((Cmnd)-SCp.Status) #define FCPIO_INVALID_CODE 0x100 /* hdr_status value unused by firmware */ @@ -71,9 +85,28 @@ #define FNIC_HOST_RESET_TIMEOUT 1 /* mSec */ #define FNIC_RMDEVICE_TIMEOUT1000 /* mSec */ #define FNIC_HOST_RESET_SETTLE_TIME 30 /* Sec */ +#define FNIC_ABT_TERM_DELAY_TIMEOUT 500/* mSec */ #define FNIC_MAX_FCP_TARGET 256 +/** + * state_flags to identify host state along along with fnic's state + **/ +#define __FNIC_FLAGS_FWRESET BIT(0) /* fwreset in progress */ +#define __FNIC_FLAGS_BLOCK_IO BIT(1) /* IOs are blocked */ + +#define FNIC_FLAGS_NONE(0) +#define FNIC_FLAGS_FWRESET (__FNIC_FLAGS_FWRESET | \ + __FNIC_FLAGS_BLOCK_IO) + +#define FNIC_FLAGS_IO_BLOCKED (__FNIC_FLAGS_BLOCK_IO) + +#define fnic_set_state_flags(fnicp, st_flags) \ + __fnic_set_state_flags(fnicp, st_flags, 0) + +#define fnic_clear_state_flags(fnicp, st_flags) \ + __fnic_set_state_flags(fnicp, st_flags, 1) + extern unsigned int fnic_log_level; #define FNIC_MAIN_LOGGING 0x01 @@ -170,6 +203,9 @@ struct fnic { struct completion *remove_wait; /* device remove thread blocks */ + atomic_t in_flight; /* io counter */ + u32 _reserved; /* fill hole */ + u64 __bitwise__ state_flags;/* protected by host lock */ enum fnic_state state; spinlock_t fnic_lock; @@ -267,4 +303,10 @@ const char *fnic_state_to_str(unsigned int state); void fnic_log_q_error(struct fnic *fnic); void fnic_handle_link_event(struct fnic *fnic); +static inline