--- libiscsi.c    2018-03-31 19:10:43.000000000 +0300
+++ /tmp/libiscsi.c    2018-05-10 00:57:49.216851035 +0300
@@ -1684,6 +1684,7 @@ int iscsi_queuecommand(struct Scsi_Host
     reason = iscsi_session_chkready(cls_session);
     if (reason) {
         sc->result = reason;
+        spin_unlock_bh(&session->frwd_lock);
         goto fault;
     }

@@ -1716,6 +1717,7 @@ int iscsi_queuecommand(struct Scsi_Host
             reason = FAILURE_SESSION_FREED;
             sc->result = DID_NO_CONNECT << 16;
         }
+        spin_unlock_bh(&session->frwd_lock);
         goto fault;
     }

@@ -1723,23 +1725,27 @@ int iscsi_queuecommand(struct Scsi_Host
     if (!conn) {
         reason = FAILURE_SESSION_FREED;
         sc->result = DID_NO_CONNECT << 16;
+        spin_unlock_bh(&session->frwd_lock);
         goto fault;
     }

     if (test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx)) {
         reason = FAILURE_SESSION_IN_RECOVERY;
         sc->result = DID_REQUEUE << 16;
+        spin_unlock_bh(&session->frwd_lock);
         goto fault;
     }

     if (iscsi_check_cmdsn_window_closed(conn)) {
         reason = FAILURE_WINDOW_CLOSED;
+        spin_unlock_bh(&session->frwd_lock);
         goto reject;
     }

     task = iscsi_alloc_task(conn, sc);
     if (!task) {
         reason = FAILURE_OOM;
+        spin_unlock_bh(&session->frwd_lock);
         goto reject;
     }

@@ -1748,15 +1754,18 @@ int iscsi_queuecommand(struct Scsi_Host
         if (reason) {
             if (reason == -ENOMEM ||  reason == -EACCES) {
                 reason = FAILURE_OOM;
+                spin_unlock_bh(&session->frwd_lock);
                 goto prepd_reject;
             } else {
                 sc->result = DID_ABORT << 16;
+                spin_unlock_bh(&session->frwd_lock);
                 goto prepd_fault;
             }
         }
         if (session->tt->xmit_task(task)) {
             session->cmdsn--;
             reason = FAILURE_SESSION_NOT_READY;
+            spin_unlock_bh(&session->frwd_lock);
             goto prepd_reject;
         }
     } else {
@@ -1771,17 +1780,19 @@ int iscsi_queuecommand(struct Scsi_Host
     return 0;

 prepd_reject:
+    spin_lock_bh(&session->back_lock);
     iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ);
+    spin_unlock_bh(&session->back_lock);
 reject:
-    spin_unlock_bh(&session->frwd_lock);
     ISCSI_DBG_SESSION(session, "cmd 0x%x rejected (%d)\n",
               sc->cmnd[0], reason);
     return SCSI_MLQUEUE_TARGET_BUSY;

 prepd_fault:
+    spin_lock_bh(&session->back_lock);
     iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ);
+    spin_unlock_bh(&session->back_lock);
 fault:
-    spin_unlock_bh(&session->frwd_lock);
     ISCSI_DBG_SESSION(session, "iscsi: cmd 0x%x is not queued (%d)\n",
               sc->cmnd[0], reason);
     if (!scsi_bidi_cmnd(sc))
@@ -3149,7 +3160,11 @@ static void iscsi_start_session_recovery
      */
     spin_lock_bh(&session->frwd_lock);
     fail_scsi_tasks(conn, -1, DID_TRANSPORT_DISRUPTED);
+    spin_unlock_bh(&session->frwd_lock);
+    spin_lock_bh(&session->back_lock);
     fail_mgmt_tasks(session, conn);
+    spin_unlock_bh(&session->back_lock);
+    spin_lock_bh(&session->frwd_lock);
     memset(&conn->tmhdr, 0, sizeof(conn->tmhdr));
     spin_unlock_bh(&session->frwd_lock);
     mutex_unlock(&session->eh_mutex);
