scsi: qla2xxx: Relogin during fabric disturbance
authorQuinn Tran <qutran@marvell.com>
Tue, 26 Oct 2021 11:54:00 +0000 (04:54 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 27 Oct 2021 03:51:59 +0000 (23:51 -0400)
For RSCN of type "Area, Domain, or Fabric", which indicate a portion or
entire fabric was disturbed, current driver does not set the scan_need flag
to indicate a session was affected by the disturbance. This in turn can
lead to I/O timeout and delay of relogin. Hence initiate relogin in the
event of fabric disturbance.

Link: https://lore.kernel.org/r/20211026115412.27691-2-njavali@marvell.com
Fixes: 1560bafdff9e ("scsi: qla2xxx: Use complete switch scan for RSCN events")
Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: Quinn Tran <qutran@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qla2xxx/qla_init.c

index 908a72ebf7c2aa96cd29d18a2bc71d013303df2c..2438191d0ad62d964ea5a6e9d586f2df82ad951e 100644 (file)
@@ -1786,16 +1786,52 @@ void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
        fc_port_t *fcport;
        unsigned long flags;
 
-       fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1);
-       if (fcport) {
-               if (fcport->flags & FCF_FCP2_DEVICE) {
-                       ql_dbg(ql_dbg_disc, vha, 0x2115,
-                              "Delaying session delete for FCP2 portid=%06x %8phC ",
-                              fcport->d_id.b24, fcport->port_name);
-                       return;
+       switch (ea->id.b.rsvd_1) {
+       case RSCN_PORT_ADDR:
+               fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1);
+               if (fcport) {
+                       if (fcport->flags & FCF_FCP2_DEVICE) {
+                               ql_dbg(ql_dbg_disc, vha, 0x2115,
+                                      "Delaying session delete for FCP2 portid=%06x %8phC ",
+                                       fcport->d_id.b24, fcport->port_name);
+                               return;
+                       }
+                       fcport->scan_needed = 1;
+                       fcport->rscn_gen++;
+               }
+               break;
+       case RSCN_AREA_ADDR:
+               list_for_each_entry(fcport, &vha->vp_fcports, list) {
+                       if (fcport->flags & FCF_FCP2_DEVICE)
+                               continue;
+
+                       if ((ea->id.b24 & 0xffff00) == (fcport->d_id.b24 & 0xffff00)) {
+                               fcport->scan_needed = 1;
+                               fcport->rscn_gen++;
+                       }
                }
-               fcport->scan_needed = 1;
-               fcport->rscn_gen++;
+               break;
+       case RSCN_DOM_ADDR:
+               list_for_each_entry(fcport, &vha->vp_fcports, list) {
+                       if (fcport->flags & FCF_FCP2_DEVICE)
+                               continue;
+
+                       if ((ea->id.b24 & 0xff0000) == (fcport->d_id.b24 & 0xff0000)) {
+                               fcport->scan_needed = 1;
+                               fcport->rscn_gen++;
+                       }
+               }
+               break;
+       case RSCN_FAB_ADDR:
+       default:
+               list_for_each_entry(fcport, &vha->vp_fcports, list) {
+                       if (fcport->flags & FCF_FCP2_DEVICE)
+                               continue;
+
+                       fcport->scan_needed = 1;
+                       fcport->rscn_gen++;
+               }
+               break;
        }
 
        spin_lock_irqsave(&vha->work_lock, flags);