scsi: fnic: Avoid looping in TRANS ETH on unload
authorKaran Tilak Kumar <kartilak@cisco.com>
Sat, 21 Nov 2020 01:21:45 +0000 (17:21 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 24 Nov 2020 03:32:50 +0000 (22:32 -0500)
Avoid looping in fnic_scsi_abort_io() before sending fw reset when fnic is
in TRANS ETH state and when we have not received any link events.

Link: https://lore.kernel.org/r/20201121012145.18522-1-kartilak@cisco.com
Reviewed-by: Arulprabhu Ponnusamy <arulponn@cisco.com>
Co-developed-by: Satish Kharat <satishkh@cisco.com>
Signed-off-by: Satish Kharat <satishkh@cisco.com>
Signed-off-by: Karan Tilak Kumar <kartilak@cisco.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/fnic/fnic.h
drivers/scsi/fnic/fnic_fcs.c
drivers/scsi/fnic/fnic_main.c
drivers/scsi/fnic/fnic_scsi.c

index ed00b60..6dc8c91 100644 (file)
@@ -39,7 +39,7 @@
 
 #define DRV_NAME               "fnic"
 #define DRV_DESCRIPTION                "Cisco FCoE HBA Driver"
-#define DRV_VERSION            "1.6.0.49"
+#define DRV_VERSION            "1.6.0.50"
 #define PFX                    DRV_NAME ": "
 #define DFX                     DRV_NAME "%d: "
 
@@ -245,6 +245,7 @@ struct fnic {
        u32 vlan_hw_insert:1;           /* let hw insert the tag */
        u32 in_remove:1;                /* fnic device in removal */
        u32 stop_rx_link_events:1;      /* stop proc. rx frames, link events */
+       u32 link_events:1;              /* set when we get any link event*/
 
        struct completion *remove_wait; /* device remove thread blocks */
 
index 3fc3a72..3337d66 100644 (file)
@@ -56,6 +56,8 @@ void fnic_handle_link(struct work_struct *work)
 
        spin_lock_irqsave(&fnic->fnic_lock, flags);
 
+       fnic->link_events = 1;      /* less work to just set everytime*/
+
        if (fnic->stop_rx_link_events) {
                spin_unlock_irqrestore(&fnic->fnic_lock, flags);
                return;
index 5f8a7ef..cad2967 100644 (file)
@@ -580,6 +580,8 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        fnic->lport = lp;
        fnic->ctlr.lp = lp;
 
+       fnic->link_events = 0;
+
        snprintf(fnic->name, sizeof(fnic->name) - 1, "%s%d", DRV_NAME,
                 host->host_no);
 
index d1f7b84..16e66f5 100644 (file)
@@ -2673,7 +2673,8 @@ void fnic_scsi_abort_io(struct fc_lport *lp)
        /* Issue firmware reset for fnic, wait for reset to complete */
 retry_fw_reset:
        spin_lock_irqsave(&fnic->fnic_lock, flags);
-       if (unlikely(fnic->state == FNIC_IN_FC_TRANS_ETH_MODE)) {
+       if (unlikely(fnic->state == FNIC_IN_FC_TRANS_ETH_MODE) &&
+                    fnic->link_events) {
                /* fw reset is in progress, poll for its completion */
                spin_unlock_irqrestore(&fnic->fnic_lock, flags);
                schedule_timeout(msecs_to_jiffies(100));