Commit 661134ad authored by Mike Christie's avatar Mike Christie Committed by James Bottomley

[SCSI] libiscsi, bnx2i: make bound ep check common

bnx2i currently has a check for if a ep is properly bound, so if
iscsi_queuecommand/xmit_task is called while there is no ep
we will not queue IO.

be2iscsi sends IO from queuecommand/xmit_task like how bnx2i does
and needs a similar test. This patch has us just use the suspend_bit
test for this.

When ep_poll has succeeed iscsid will call conn_bind, the LLD will
then call iscsi_conn_bind which will clear the suspend bit.
When ep_disconnect is called (or if there is a conn error) we set
the suspend bit. For the ep_disconnect case I am adding a helper
in this patch that will take the session lock to make sure
iscsi_queuecommand/xmit_task is not running and it will set
the suspend bit.
Signed-off-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJayamohan Kallickal <jayamohank@serverengines.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 4c0ba5d2
...@@ -1571,6 +1571,12 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) ...@@ -1571,6 +1571,12 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
goto fault; goto fault;
} }
if (test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx)) {
reason = FAILURE_SESSION_IN_RECOVERY;
sc->result = DID_REQUEUE;
goto fault;
}
if (iscsi_check_cmdsn_window_closed(conn)) { if (iscsi_check_cmdsn_window_closed(conn)) {
reason = FAILURE_WINDOW_CLOSED; reason = FAILURE_WINDOW_CLOSED;
goto reject; goto reject;
...@@ -1810,6 +1816,33 @@ static void fail_scsi_tasks(struct iscsi_conn *conn, unsigned lun, ...@@ -1810,6 +1816,33 @@ static void fail_scsi_tasks(struct iscsi_conn *conn, unsigned lun,
} }
} }
/**
* iscsi_suspend_queue - suspend iscsi_queuecommand
* @conn: iscsi conn to stop queueing IO on
*
* This grabs the session lock to make sure no one is in
* xmit_task/queuecommand, and then sets suspend to prevent
* new commands from being queued. This only needs to be called
* by offload drivers that need to sync a path like ep disconnect
* with the iscsi_queuecommand/xmit_task. To start IO again libiscsi
* will call iscsi_start_tx and iscsi_unblock_session when in FFP.
*/
void iscsi_suspend_queue(struct iscsi_conn *conn)
{
spin_lock_bh(&conn->session->lock);
set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
spin_unlock_bh(&conn->session->lock);
}
EXPORT_SYMBOL_GPL(iscsi_suspend_queue);
/**
* iscsi_suspend_tx - suspend iscsi_data_xmit
* @conn: iscsi conn tp stop processing IO on.
*
* This function sets the suspend bit to prevent iscsi_data_xmit
* from sending new IO, and if work is queued on the xmit thread
* it will wait for it to be completed.
*/
void iscsi_suspend_tx(struct iscsi_conn *conn) void iscsi_suspend_tx(struct iscsi_conn *conn)
{ {
struct Scsi_Host *shost = conn->session->host; struct Scsi_Host *shost = conn->session->host;
......
...@@ -390,6 +390,7 @@ extern void iscsi_session_failure(struct iscsi_session *session, ...@@ -390,6 +390,7 @@ extern void iscsi_session_failure(struct iscsi_session *session,
extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
enum iscsi_param param, char *buf); enum iscsi_param param, char *buf);
extern void iscsi_suspend_tx(struct iscsi_conn *conn); extern void iscsi_suspend_tx(struct iscsi_conn *conn);
extern void iscsi_suspend_queue(struct iscsi_conn *conn);
extern void iscsi_conn_queue_work(struct iscsi_conn *conn); extern void iscsi_conn_queue_work(struct iscsi_conn *conn);
#define iscsi_conn_printk(prefix, _c, fmt, a...) \ #define iscsi_conn_printk(prefix, _c, fmt, a...) \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment