Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f41d4721 authored by Mike Christie's avatar Mike Christie Committed by James Bottomley
Browse files

[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: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 1227633a
Loading
Loading
Loading
Loading
+14 −23
Original line number Diff line number Diff line
@@ -505,6 +505,7 @@ static void iscsi_free_task(struct iscsi_task *task)
	struct iscsi_conn *conn = task->conn;
	struct iscsi_session *session = conn->session;
	struct scsi_cmnd *sc = task->sc;
	int oldstate = task->state;

	ISCSI_DBG_SESSION(session, "freeing task itt 0x%x state %d sc %p\n",
			  task->itt, task->state, task->sc);
@@ -525,10 +526,10 @@ static void iscsi_free_task(struct iscsi_task *task)
		/* SCSI eh reuses commands to verify us */
		sc->SCp.ptr = NULL;
		/*
		 * queue command may call this to free the task, but
		 * not have setup the sc callback
		 * queue command may call this to free the task, so
		 * it will decide how to return sc to scsi-ml.
		 */
		if (sc->scsi_done)
		if (oldstate != ISCSI_TASK_REQUEUE_SCSIQ)
			sc->scsi_done(sc);
	}
}
@@ -572,7 +573,8 @@ static void iscsi_complete_task(struct iscsi_task *task, int state)
			  task->itt, task->state, task->sc);
	if (task->state == ISCSI_TASK_COMPLETED ||
	    task->state == ISCSI_TASK_ABRT_TMF ||
	    task->state == ISCSI_TASK_ABRT_SESS_RECOV)
	    task->state == ISCSI_TASK_ABRT_SESS_RECOV ||
	    task->state == ISCSI_TASK_REQUEUE_SCSIQ)
		return;
	WARN_ON_ONCE(task->state == ISCSI_TASK_FREE);
	task->state = state;
@@ -1600,27 +1602,23 @@ enum {
	FAILURE_SESSION_NOT_READY,
};

static int iscsi_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc)
{
	struct iscsi_cls_session *cls_session;
	struct Scsi_Host *host;
	struct iscsi_host *ihost;
	int reason = 0;
	struct iscsi_session *session;
	struct iscsi_conn *conn;
	struct iscsi_task *task = NULL;

	sc->scsi_done = done;
	sc->result = 0;
	sc->SCp.ptr = NULL;

	host = sc->device->host;
	ihost = shost_priv(host);
	spin_unlock(host->host_lock);

	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) {
@@ -1706,25 +1704,21 @@ static int iscsi_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi
	}

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

prepd_reject:
	sc->scsi_done = NULL;
	iscsi_complete_task(task, ISCSI_TASK_COMPLETED);
	iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ);
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);
	return SCSI_MLQUEUE_TARGET_BUSY;

prepd_fault:
	sc->scsi_done = NULL;
	iscsi_complete_task(task, ISCSI_TASK_COMPLETED);
	iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ);
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))
@@ -1733,12 +1727,9 @@ static int iscsi_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi
		scsi_out(sc)->resid = scsi_out(sc)->length;
		scsi_in(sc)->resid = scsi_in(sc)->length;
	}
	done(sc);
	spin_lock(host->host_lock);
	sc->scsi_done(sc);
	return 0;
}

DEF_SCSI_QCMD(iscsi_queuecommand)
EXPORT_SYMBOL_GPL(iscsi_queuecommand);

int iscsi_change_queue_depth(struct scsi_device *sdev, int depth, int reason)
+2 −1
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ enum {
	ISCSI_TASK_RUNNING,
	ISCSI_TASK_ABRT_TMF,		/* aborted due to TMF */
	ISCSI_TASK_ABRT_SESS_RECOV,	/* aborted due to session recovery */
	ISCSI_TASK_REQUEUE_SCSIQ,	/* qcmd requeueing to scsi-ml */
};

struct iscsi_r2t_info {
@@ -341,7 +342,7 @@ extern int iscsi_eh_abort(struct scsi_cmnd *sc);
extern int iscsi_eh_recover_target(struct scsi_cmnd *sc);
extern int iscsi_eh_session_reset(struct scsi_cmnd *sc);
extern int iscsi_eh_device_reset(struct scsi_cmnd *sc);
extern int iscsi_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *sc);
extern int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc);

/*
 * iSCSI host helpers.