]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
[SCSI] qla2xxx: Don't process RSCNs for a vport on the same physical adapter.
authorChad Dupuis <chad.dupuis@qlogic.com>
Fri, 8 Feb 2013 06:58:01 +0000 (01:58 -0500)
committerJames Bottomley <JBottomley@Parallels.com>
Fri, 22 Feb 2013 14:31:24 +0000 (14:31 +0000)
Currently,the driver is processes RSCNs for each new NPIV ports that is created.
Processing the RSCN includes a name server query to see what has changed at the
name server side.  The name server query is performed by the physical port and
each virtual port on the physical adapter (since the RSCN is passed to each
virtual port for processing).  As the number of virtual ports being created
increases, this causes a lot of traffic and busies the firmware.

Processing the RSCN for a virtual port we already have a priori knowledge of is
not necessary so check the 24-bit fabric ID of the RSCN entry and skip
processing it if the RSCN is for a virtual port we already know about.

Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_isr.c

index 617771ba6cbc468c3a23c60d0330e77abe92431b..02f11de0ff0133aea3eed1eecad4c604cca0c662 100644 (file)
@@ -446,6 +446,7 @@ extern uint8_t *qla25xx_read_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
     uint32_t);
 extern int qla25xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
     uint32_t);
+extern int qla2x00_is_a_vp_did(scsi_qla_host_t *, uint32_t);
 
 extern int qla2x00_beacon_on(struct scsi_qla_host *);
 extern int qla2x00_beacon_off(struct scsi_qla_host *);
index 891b8f1c03e905c8105c465f00b752465f409fe4..a1e584842b85420046b8f64e7b67de89d79f5163 100644 (file)
@@ -3368,8 +3368,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
        int             first_dev, last_dev;
        port_id_t       wrap = {}, nxt_d_id;
        struct qla_hw_data *ha = vha->hw;
-       struct scsi_qla_host *vp, *base_vha = pci_get_drvdata(ha->pdev);
-       struct scsi_qla_host *tvp;
+       struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
 
        rval = QLA_SUCCESS;
 
@@ -3482,22 +3481,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
                        continue;
 
                /* Bypass virtual ports of the same host. */
-               found = 0;
-               if (ha->num_vhosts) {
-                       unsigned long flags;
-
-                       spin_lock_irqsave(&ha->vport_slock, flags);
-                       list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
-                               if (new_fcport->d_id.b24 == vp->d_id.b24) {
-                                       found = 1;
-                                       break;
-                               }
-                       }
-                       spin_unlock_irqrestore(&ha->vport_slock, flags);
-
-                       if (found)
-                               continue;
-               }
+               if (qla2x00_is_a_vp_did(vha, new_fcport->d_id.b24))
+                       continue;
 
                /* Bypass if same domain and area of adapter. */
                if (((new_fcport->d_id.b24 & 0xffff00) ==
index fa738cddd4d53237889592f1590dc660b508c815..d62fd1a78fa830fe269b9ad3a9c30cc0935753f1 100644 (file)
@@ -495,6 +495,31 @@ qla83xx_handle_8200_aen(scsi_qla_host_t *vha, uint16_t *mb)
        }
 }
 
+int
+qla2x00_is_a_vp_did(scsi_qla_host_t *vha, uint32_t rscn_entry)
+{
+       struct qla_hw_data *ha = vha->hw;
+       scsi_qla_host_t *vp;
+       uint32_t vp_did;
+       unsigned long flags;
+       int ret = 0;
+
+       if (!ha->num_vhosts)
+               return ret;
+
+       spin_lock_irqsave(&ha->vport_slock, flags);
+       list_for_each_entry(vp, &ha->vp_list, list) {
+               vp_did = vp->d_id.b24;
+               if (vp_did == rscn_entry) {
+                       ret = 1;
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(&ha->vport_slock, flags);
+
+       return ret;
+}
+
 /**
  * qla2x00_async_event() - Process aynchronous events.
  * @ha: SCSI driver HA context
@@ -901,6 +926,10 @@ skip_rio:
                /* Ignore reserved bits from RSCN-payload. */
                rscn_entry = ((mb[1] & 0x3ff) << 16) | mb[2];
 
+               /* Skip RSCNs for virtual ports on the same physical port */
+               if (qla2x00_is_a_vp_did(vha, rscn_entry))
+                       break;
+
                atomic_set(&vha->loop_down_timer, 0);
                vha->flags.management_server_logged_in = 0;