aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2010-12-31 03:22:21 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-12-31 10:52:44 -0500
commitf41d472179a0d7c8e8160c85180ab1124947068e (patch)
tree51f3397de8fc8acf3c27d08c2e39e2eb39bacc75
parent1227633a441363642cdbaf38c4241d071e917095 (diff)
[SCSI] libiscsi: do not take host lock in queuecommand
iscsi_tcp, ib_iser, cxgb*, be2iscsi and bnx2i do not use the host lock and do not take the session lock against a irq, so this patch drops the DEF_SCSI_QCMD use. Instead we just take the session lock and disable bhs. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/libiscsi.c37
-rw-r--r--include/scsi/libiscsi.h3
2 files changed, 16 insertions, 24 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 3eddab0774e4..1def8e101249 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -505,6 +505,7 @@ static void iscsi_free_task(struct iscsi_task *task)
505 struct iscsi_conn *conn = task->conn; 505 struct iscsi_conn *conn = task->conn;
506 struct iscsi_session *session = conn->session; 506 struct iscsi_session *session = conn->session;
507 struct scsi_cmnd *sc = task->sc; 507 struct scsi_cmnd *sc = task->sc;
508 int oldstate = task->state;
508 509
509 ISCSI_DBG_SESSION(session, "freeing task itt 0x%x state %d sc %p\n", 510 ISCSI_DBG_SESSION(session, "freeing task itt 0x%x state %d sc %p\n",
510 task->itt, task->state, task->sc); 511 task->itt, task->state, task->sc);
@@ -525,10 +526,10 @@ static void iscsi_free_task(struct iscsi_task *task)
525 /* SCSI eh reuses commands to verify us */ 526 /* SCSI eh reuses commands to verify us */
526 sc->SCp.ptr = NULL; 527 sc->SCp.ptr = NULL;
527 /* 528 /*
528 * queue command may call this to free the task, but 529 * queue command may call this to free the task, so
529 * not have setup the sc callback 530 * it will decide how to return sc to scsi-ml.
530 */ 531 */
531 if (sc->scsi_done) 532 if (oldstate != ISCSI_TASK_REQUEUE_SCSIQ)
532 sc->scsi_done(sc); 533 sc->scsi_done(sc);
533 } 534 }
534} 535}
@@ -572,7 +573,8 @@ static void iscsi_complete_task(struct iscsi_task *task, int state)
572 task->itt, task->state, task->sc); 573 task->itt, task->state, task->sc);
573 if (task->state == ISCSI_TASK_COMPLETED || 574 if (task->state == ISCSI_TASK_COMPLETED ||
574 task->state == ISCSI_TASK_ABRT_TMF || 575 task->state == ISCSI_TASK_ABRT_TMF ||
575 task->state == ISCSI_TASK_ABRT_SESS_RECOV) 576 task->state == ISCSI_TASK_ABRT_SESS_RECOV ||
577 task->state == ISCSI_TASK_REQUEUE_SCSIQ)
576 return; 578 return;
577 WARN_ON_ONCE(task->state == ISCSI_TASK_FREE); 579 WARN_ON_ONCE(task->state == ISCSI_TASK_FREE);
578 task->state = state; 580 task->state = state;
@@ -1600,27 +1602,23 @@ enum {
1600 FAILURE_SESSION_NOT_READY, 1602 FAILURE_SESSION_NOT_READY,
1601}; 1603};
1602 1604
1603static int iscsi_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) 1605int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc)
1604{ 1606{
1605 struct iscsi_cls_session *cls_session; 1607 struct iscsi_cls_session *cls_session;
1606 struct Scsi_Host *host;
1607 struct iscsi_host *ihost; 1608 struct iscsi_host *ihost;
1608 int reason = 0; 1609 int reason = 0;
1609 struct iscsi_session *session; 1610 struct iscsi_session *session;
1610 struct iscsi_conn *conn; 1611 struct iscsi_conn *conn;
1611 struct iscsi_task *task = NULL; 1612 struct iscsi_task *task = NULL;
1612 1613
1613 sc->scsi_done = done;
1614 sc->result = 0; 1614 sc->result = 0;
1615 sc->SCp.ptr = NULL; 1615 sc->SCp.ptr = NULL;
1616 1616
1617 host = sc->device->host;
1618 ihost = shost_priv(host); 1617 ihost = shost_priv(host);
1619 spin_unlock(host->host_lock);
1620 1618
1621 cls_session = starget_to_session(scsi_target(sc->device)); 1619 cls_session = starget_to_session(scsi_target(sc->device));
1622 session = cls_session->dd_data; 1620 session = cls_session->dd_data;
1623 spin_lock(&session->lock); 1621 spin_lock_bh(&session->lock);
1624 1622
1625 reason = iscsi_session_chkready(cls_session); 1623 reason = iscsi_session_chkready(cls_session);
1626 if (reason) { 1624 if (reason) {
@@ -1706,25 +1704,21 @@ static int iscsi_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi
1706 } 1704 }
1707 1705
1708 session->queued_cmdsn++; 1706 session->queued_cmdsn++;
1709 spin_unlock(&session->lock); 1707 spin_unlock_bh(&session->lock);
1710 spin_lock(host->host_lock);
1711 return 0; 1708 return 0;
1712 1709
1713prepd_reject: 1710prepd_reject:
1714 sc->scsi_done = NULL; 1711 iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ);
1715 iscsi_complete_task(task, ISCSI_TASK_COMPLETED);
1716reject: 1712reject:
1717 spin_unlock(&session->lock); 1713 spin_unlock_bh(&session->lock);
1718 ISCSI_DBG_SESSION(session, "cmd 0x%x rejected (%d)\n", 1714 ISCSI_DBG_SESSION(session, "cmd 0x%x rejected (%d)\n",
1719 sc->cmnd[0], reason); 1715 sc->cmnd[0], reason);
1720 spin_lock(host->host_lock);
1721 return SCSI_MLQUEUE_TARGET_BUSY; 1716 return SCSI_MLQUEUE_TARGET_BUSY;
1722 1717
1723prepd_fault: 1718prepd_fault:
1724 sc->scsi_done = NULL; 1719 iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ);
1725 iscsi_complete_task(task, ISCSI_TASK_COMPLETED);
1726fault: 1720fault:
1727 spin_unlock(&session->lock); 1721 spin_unlock_bh(&session->lock);
1728 ISCSI_DBG_SESSION(session, "iscsi: cmd 0x%x is not queued (%d)\n", 1722 ISCSI_DBG_SESSION(session, "iscsi: cmd 0x%x is not queued (%d)\n",
1729 sc->cmnd[0], reason); 1723 sc->cmnd[0], reason);
1730 if (!scsi_bidi_cmnd(sc)) 1724 if (!scsi_bidi_cmnd(sc))
@@ -1733,12 +1727,9 @@ fault:
1733 scsi_out(sc)->resid = scsi_out(sc)->length; 1727 scsi_out(sc)->resid = scsi_out(sc)->length;
1734 scsi_in(sc)->resid = scsi_in(sc)->length; 1728 scsi_in(sc)->resid = scsi_in(sc)->length;
1735 } 1729 }
1736 done(sc); 1730 sc->scsi_done(sc);
1737 spin_lock(host->host_lock);
1738 return 0; 1731 return 0;
1739} 1732}
1740
1741DEF_SCSI_QCMD(iscsi_queuecommand)
1742EXPORT_SYMBOL_GPL(iscsi_queuecommand); 1733EXPORT_SYMBOL_GPL(iscsi_queuecommand);
1743 1734
1744int iscsi_change_queue_depth(struct scsi_device *sdev, int depth, int reason) 1735int iscsi_change_queue_depth(struct scsi_device *sdev, int depth, int reason)
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 68e951d79f0b..748382b32b52 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -89,6 +89,7 @@ enum {
89 ISCSI_TASK_RUNNING, 89 ISCSI_TASK_RUNNING,
90 ISCSI_TASK_ABRT_TMF, /* aborted due to TMF */ 90 ISCSI_TASK_ABRT_TMF, /* aborted due to TMF */
91 ISCSI_TASK_ABRT_SESS_RECOV, /* aborted due to session recovery */ 91 ISCSI_TASK_ABRT_SESS_RECOV, /* aborted due to session recovery */
92 ISCSI_TASK_REQUEUE_SCSIQ, /* qcmd requeueing to scsi-ml */
92}; 93};
93 94
94struct iscsi_r2t_info { 95struct iscsi_r2t_info {
@@ -341,7 +342,7 @@ extern int iscsi_eh_abort(struct scsi_cmnd *sc);
341extern int iscsi_eh_recover_target(struct scsi_cmnd *sc); 342extern int iscsi_eh_recover_target(struct scsi_cmnd *sc);
342extern int iscsi_eh_session_reset(struct scsi_cmnd *sc); 343extern int iscsi_eh_session_reset(struct scsi_cmnd *sc);
343extern int iscsi_eh_device_reset(struct scsi_cmnd *sc); 344extern int iscsi_eh_device_reset(struct scsi_cmnd *sc);
344extern int iscsi_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *sc); 345extern int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc);
345 346
346/* 347/*
347 * iSCSI host helpers. 348 * iSCSI host helpers.