]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
scsi: be2iscsi: Fail the sessions immediately after TPE
authorJitendra Bhivare <jitendra.bhivare@broadcom.com>
Fri, 19 Aug 2016 09:50:19 +0000 (15:20 +0530)
committerDhaval Giani <dhaval.giani@oracle.com>
Wed, 8 Mar 2017 00:55:37 +0000 (19:55 -0500)
Orabug: 25655127

Sessions are no longer valid, so schedule sess_work to fail the sessions
immediately when error is detected. This is done to avoid iSCSI transport
layer to keep sending NOP-Out which driver any ways fail.

Schedule sess_work immediately in case of HBA error. Old sessions are gone
for good and need to be re-established.

iscsi_session_failure needs process context hence this work.

Signed-off-by: Jitendra Bhivare <jitendra.bhivare@broadcom.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Ethan Zhao <ethan.zhao@oracle.com>
Signed-off-by: Dhaval Giani <dhaval.giani@oracle.com>
drivers/scsi/be2iscsi/be_main.c
drivers/scsi/be2iscsi/be_main.h

index ab51051a39f5387ee3bd423409c68b5ba3d9db78..774cba321e506cacdb9e8dcf287c7fc1416d2c48 100644 (file)
@@ -5399,7 +5399,10 @@ static void beiscsi_hw_health_check(unsigned long ptr)
        if (beiscsi_detect_ue(phba)) {
                __beiscsi_log(phba, KERN_ERR,
                              "BM_%d : port in error: %lx\n", phba->state);
-               /* detect TPE if UER supported */
+               /* sessions are no longer valid, so first fail the sessions */
+               queue_work(phba->wq, &phba->sess_work);
+
+               /* detect UER supported */
                if (!test_bit(BEISCSI_HBA_UER_SUPP, &phba->state))
                        return;
                /* modify this timer to check TPE */
@@ -5564,12 +5567,24 @@ static void beiscsi_disable_port(struct beiscsi_hba *phba, int unload)
        hwi_cleanup_port(phba);
 }
 
+static void beiscsi_sess_work(struct work_struct *work)
+{
+       struct beiscsi_hba *phba;
+
+       phba = container_of(work, struct beiscsi_hba, sess_work);
+       /*
+        * This work gets scheduled only in case of HBA error.
+        * Old sessions are gone so need to be re-established.
+        * iscsi_session_failure needs process context hence this work.
+        */
+       iscsi_host_for_each_session(phba->shost, beiscsi_session_fail);
+}
+
 static void beiscsi_recover_port(struct work_struct *work)
 {
        struct beiscsi_hba *phba;
 
        phba = container_of(work, struct beiscsi_hba, recover_port.work);
-       iscsi_host_for_each_session(phba->shost, beiscsi_session_fail);
        beiscsi_disable_port(phba, 0);
        beiscsi_enable_port(phba);
 }
@@ -5589,6 +5604,8 @@ static pci_ers_result_t beiscsi_eeh_err_detected(struct pci_dev *pdev,
        del_timer_sync(&phba->hw_check);
        cancel_delayed_work_sync(&phba->recover_port);
 
+       /* sessions are no longer valid, so first fail the sessions */
+       iscsi_host_for_each_session(phba->shost, beiscsi_session_fail);
        beiscsi_disable_port(phba, 0);
 
        if (state == pci_channel_io_perm_failure) {
@@ -5838,6 +5855,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
        schedule_delayed_work(&phba->eqd_update,
                              msecs_to_jiffies(BEISCSI_EQD_UPDATE_INTERVAL));
 
+       INIT_WORK(&phba->sess_work, beiscsi_sess_work);
        INIT_DELAYED_WORK(&phba->recover_port, beiscsi_recover_port);
        /**
         * Start UE detection here. UE before this will cause stall in probe
@@ -5848,7 +5866,6 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
        phba->hw_check.data = (unsigned long)phba;
        mod_timer(&phba->hw_check,
                  jiffies + msecs_to_jiffies(BEISCSI_UE_DETECT_INTERVAL));
-
        beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
                    "\n\n\n BM_%d : SUCCESS - DRIVER LOADED\n\n\n");
        return 0;
@@ -5893,6 +5910,7 @@ static void beiscsi_remove(struct pci_dev *pcidev)
        /* first stop UE detection before unloading */
        del_timer_sync(&phba->hw_check);
        cancel_delayed_work_sync(&phba->recover_port);
+       cancel_work_sync(&phba->sess_work);
 
        beiscsi_iface_destroy_default(phba);
        iscsi_host_remove(phba->shost);
index 69115b62df5f7563230b2082bc416b5dd12479a0..7ef8af13110cee676116009973df00cee4341f9b 100644 (file)
@@ -418,6 +418,7 @@ struct beiscsi_hba {
 #define BEISCSI_UE_DETECT_INTERVAL     1000
        u32 ue2rp;
        struct delayed_work recover_port;
+       struct work_struct sess_work;
 
        bool mac_addr_set;
        u8 mac_address[ETH_ALEN];