scsi: be2iscsi: Take iscsi_task ref in abort handler
authorJitendra Bhivare <jitendra.bhivare@broadcom.com>
Tue, 13 Dec 2016 10:25:56 +0000 (15:55 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 5 Jan 2017 05:21:12 +0000 (00:21 -0500)
Hold the reference of iscsi_task till invalidation completes.
This prevents use of ICD when invalidation of that ICD is being processed.

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>
drivers/scsi/be2iscsi/be_main.c

index 7feecc0b49034d656a90c26c68b5fa09a6f39250..260842a1f14ee56e251800d5a6d1c915c186584b 100644 (file)
@@ -218,47 +218,40 @@ static int beiscsi_slave_configure(struct scsi_device *sdev)
 
 static int beiscsi_eh_abort(struct scsi_cmnd *sc)
 {
+       struct iscsi_task *abrt_task = (struct iscsi_task *)sc->SCp.ptr;
        struct iscsi_cls_session *cls_session;
-       struct iscsi_task *aborted_task = (struct iscsi_task *)sc->SCp.ptr;
-       struct beiscsi_io_task *aborted_io_task;
-       struct iscsi_conn *conn;
+       struct beiscsi_io_task *abrt_io_task;
        struct beiscsi_conn *beiscsi_conn;
-       struct beiscsi_hba *phba;
        struct iscsi_session *session;
        struct invldt_cmd_tbl inv_tbl;
-       unsigned int cid;
+       struct beiscsi_hba *phba;
+       struct iscsi_conn *conn;
        int rc;
 
        cls_session = starget_to_session(scsi_target(sc->device));
        session = cls_session->dd_data;
 
-       spin_lock_bh(&session->frwd_lock);
-       if (!aborted_task || !aborted_task->sc) {
-               /* we raced */
-               spin_unlock_bh(&session->frwd_lock);
-               return SUCCESS;
-       }
-
-       aborted_io_task = aborted_task->dd_data;
-       if (!aborted_io_task->scsi_cmnd) {
-               /* raced or invalid command */
-               spin_unlock_bh(&session->frwd_lock);
+       /* check if we raced, task just got cleaned up under us */
+       spin_lock_bh(&session->back_lock);
+       if (!abrt_task || !abrt_task->sc) {
+               spin_unlock_bh(&session->back_lock);
                return SUCCESS;
        }
-       spin_unlock_bh(&session->frwd_lock);
-
-       conn = aborted_task->conn;
+       /* get a task ref till FW processes the req for the ICD used */
+       __iscsi_get_task(abrt_task);
+       abrt_io_task = abrt_task->dd_data;
+       conn = abrt_task->conn;
        beiscsi_conn = conn->dd_data;
        phba = beiscsi_conn->phba;
-       /* Invalidate WRB Posted for this Task */
+       /* mark WRB invalid which have been not processed by FW yet */
        AMAP_SET_BITS(struct amap_iscsi_wrb, invld,
-                     aborted_io_task->pwrb_handle->pwrb,
-                     1);
-       /* invalidate iocb */
-       cid = beiscsi_conn->beiscsi_conn_cid;
-       inv_tbl.cid = cid;
-       inv_tbl.icd = aborted_io_task->psgl_handle->sgl_index;
+                     abrt_io_task->pwrb_handle->pwrb, 1);
+       inv_tbl.cid = beiscsi_conn->beiscsi_conn_cid;
+       inv_tbl.icd = abrt_io_task->psgl_handle->sgl_index;
+       spin_unlock_bh(&session->back_lock);
+
        rc = beiscsi_mgmt_invalidate_icds(phba, &inv_tbl, 1);
+       iscsi_put_task(abrt_task);
        if (rc) {
                beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_EH,
                            "BM_%d : sc %p invalidation failed %d\n",