]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
scsi: qla2xxx: Fix Relogin being triggered too fast
authorQuinn Tran <quinn.tran@cavium.com>
Mon, 4 Dec 2017 22:45:06 +0000 (14:45 -0800)
committerThadeu Lima de Souza Cascardo <cascardo@canonical.com>
Thu, 15 Mar 2018 21:29:14 +0000 (18:29 -0300)
BugLink: http://bugs.launchpad.net/bugs/1756100
commit 4005a995668b8fd58f4cf1460dd4cf63efa18363 upstream.

Current driver design schedules relogin process via DPC thread every 1
second. In a large fabric, this DPC thread tries to schedule too many
jobs and might get overloaded. As a result of this processing of DPC
thread, it can schedule relogin earlier than 1 second.

Fixes: 726b85487067d ("qla2xxx: Add framework for async fabric discovery")
Cc: <stable@vger.kernel.org> # 4.10+
Signed-off-by: Quinn Tran <quinn.tran@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_mid.c
drivers/scsi/qla2xxx/qla_os.c

index d9b4a0651a0fe362c1979be0eca3b886d5056ae7..93ff92e2363f34992c86731c6477798a713aa64b 100644 (file)
@@ -4110,6 +4110,7 @@ typedef struct scsi_qla_host {
 #define LOOP_READY     5
 #define LOOP_DEAD      6
 
+       unsigned long   relogin_jif;
        unsigned long   dpc_flags;
 #define RESET_MARKER_NEEDED    0       /* Send marker to ISP. */
 #define RESET_ACTIVE           1
index bd9f14bf7ac2e72624a6ab14b5b88c8558623bf7..618ca272d01aa2ce1c4215b5aa175250f5e8d9c9 100644 (file)
@@ -343,15 +343,21 @@ qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
                    "FCPort update end.\n");
        }
 
-       if ((test_and_clear_bit(RELOGIN_NEEDED, &vha->dpc_flags)) &&
-               !test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags) &&
-               atomic_read(&vha->loop_state) != LOOP_DOWN) {
-
-               ql_dbg(ql_dbg_dpc, vha, 0x4018,
-                   "Relogin needed scheduled.\n");
-               qla2x00_relogin(vha);
-               ql_dbg(ql_dbg_dpc, vha, 0x4019,
-                   "Relogin needed end.\n");
+       if (test_bit(RELOGIN_NEEDED, &vha->dpc_flags) &&
+           !test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags) &&
+           atomic_read(&vha->loop_state) != LOOP_DOWN) {
+
+               if (!vha->relogin_jif ||
+                   time_after_eq(jiffies, vha->relogin_jif)) {
+                       vha->relogin_jif = jiffies + HZ;
+                       clear_bit(RELOGIN_NEEDED, &vha->dpc_flags);
+
+                       ql_dbg(ql_dbg_dpc, vha, 0x4018,
+                           "Relogin needed scheduled.\n");
+                       qla2x00_relogin(vha);
+                       ql_dbg(ql_dbg_dpc, vha, 0x4019,
+                           "Relogin needed end.\n");
+               }
        }
 
        if (test_and_clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags) &&
index 7d68ebc7c3761bef318f58a0722a519f6dcec9b4..62117f3acc5d270da1195dc7084634cb36cb0150 100644 (file)
@@ -4907,7 +4907,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
         */
                if (atomic_read(&fcport->state) != FCS_ONLINE &&
                    fcport->login_retry && !(fcport->flags & FCF_ASYNC_SENT)) {
-                       fcport->login_retry--;
+
                        if (fcport->flags & FCF_FABRIC_DEVICE) {
                                ql_dbg(ql_dbg_disc, fcport->vha, 0x2108,
                                    "%s %8phC DS %d LS %d\n", __func__,
@@ -4918,6 +4918,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
                                ea.fcport = fcport;
                                qla2x00_fcport_event_handler(vha, &ea);
                        } else {
+                               fcport->login_retry--;
                                status = qla2x00_local_device_login(vha,
                                                                fcport);
                                if (status == QLA_SUCCESS) {
@@ -5900,16 +5901,21 @@ qla2x00_do_dpc(void *data)
                }
 
                /* Retry each device up to login retry count */
-               if ((test_and_clear_bit(RELOGIN_NEEDED,
-                                               &base_vha->dpc_flags)) &&
+               if (test_bit(RELOGIN_NEEDED, &base_vha->dpc_flags) &&
                    !test_bit(LOOP_RESYNC_NEEDED, &base_vha->dpc_flags) &&
                    atomic_read(&base_vha->loop_state) != LOOP_DOWN) {
 
-                       ql_dbg(ql_dbg_dpc, base_vha, 0x400d,
-                           "Relogin scheduled.\n");
-                       qla2x00_relogin(base_vha);
-                       ql_dbg(ql_dbg_dpc, base_vha, 0x400e,
-                           "Relogin end.\n");
+                       if (!base_vha->relogin_jif ||
+                           time_after_eq(jiffies, base_vha->relogin_jif)) {
+                               base_vha->relogin_jif = jiffies + HZ;
+                               clear_bit(RELOGIN_NEEDED, &base_vha->dpc_flags);
+
+                               ql_dbg(ql_dbg_dpc, base_vha, 0x400d,
+                                   "Relogin scheduled.\n");
+                               qla2x00_relogin(base_vha);
+                               ql_dbg(ql_dbg_dpc, base_vha, 0x400e,
+                                   "Relogin end.\n");
+                       }
                }
 loop_resync_check:
                if (test_and_clear_bit(LOOP_RESYNC_NEEDED,