Both the TX (iscsi_queuecommand, iscsi_xmit_task, iscsi_conn_send_pdu)
and the RX (iscsi_complete_pdu and iser/tcp as well) code flows compete
on the session lock. Since the RX flow runs in softirq/bh/tasklet context,
if it cuts the TX flow on the same cpu, a deadlock may happen. To prevent
that, make iscsi_queuecommand use the _bh form of spin lock/unlock in
the same manner done by iscsi_xmit_task and iscsi_conn_send_pdu

Signed-off-by: Or Gerlitz <ogerl...@voltaire.com>

---

Mike, I am debugging some enhancement to iser and came a cross this.
I really don't see why it haven't hit anyone in the past, any idea?


Index: linux-2.6.32-rc5/drivers/scsi/libiscsi.c
===================================================================
--- linux-2.6.32-rc5.orig/drivers/scsi/libiscsi.c
+++ linux-2.6.32-rc5/drivers/scsi/libiscsi.c
@@ -1524,7 +1524,7 @@ int iscsi_queuecommand(struct scsi_cmnd

        cls_session = starget_to_session(scsi_target(sc->device));
        session = cls_session->dd_data;
-       spin_lock(&session->lock);
+       spin_lock_bh(&session->lock);

        reason = iscsi_session_chkready(cls_session);
        if (reason) {
@@ -1610,7 +1610,7 @@ int iscsi_queuecommand(struct scsi_cmnd
        }

        session->queued_cmdsn++;
-       spin_unlock(&session->lock);
+       spin_unlock_bh(&session->lock);
        spin_lock(host->host_lock);
        return 0;

@@ -1618,7 +1618,7 @@ prepd_reject:
        sc->scsi_done = NULL;
        iscsi_complete_task(task, ISCSI_TASK_COMPLETED);
 reject:
-       spin_unlock(&session->lock);
+       spin_unlock_bh(&session->lock);
        ISCSI_DBG_SESSION(session, "cmd 0x%x rejected (%d)\n",
                          sc->cmnd[0], reason);
        spin_lock(host->host_lock);
@@ -1628,7 +1628,7 @@ prepd_fault:
        sc->scsi_done = NULL;
        iscsi_complete_task(task, ISCSI_TASK_COMPLETED);
 fault:
-       spin_unlock(&session->lock);
+       spin_unlock_bh(&session->lock);
        ISCSI_DBG_SESSION(session, "iscsi: cmd 0x%x is not queued (%d)\n",
                          sc->cmnd[0], reason);
        if (!scsi_bidi_cmnd(sc))
@@ -1638,7 +1638,7 @@ fault:
                scsi_in(sc)->resid = scsi_in(sc)->length;
        }
        done(sc);
-       spin_lock(host->host_lock);
+       spin_lock_bh(host->host_lock);
        return 0;
 }
 EXPORT_SYMBOL_GPL(iscsi_queuecommand);

--

You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To post to this group, send email to open-is...@googlegroups.com.
To unsubscribe from this group, send email to 
open-iscsi+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/open-iscsi?hl=en.


Reply via email to