@@ -103,6 +103,7 @@ static void __iscsi_update_cmdsn(struct iscsi_session *session,
if (iscsi_sna_lt(max_cmdsn, exp_cmdsn - 1))
return;
+ spin_lock_bh(&session->back_cmdsn_lock);
if (exp_cmdsn != session->exp_cmdsn &&
!iscsi_sna_lt(exp_cmdsn, session->exp_cmdsn))
session->exp_cmdsn = exp_cmdsn;
@@ -110,6 +111,7 @@ static void __iscsi_update_cmdsn(struct iscsi_session *session,
if (max_cmdsn != session->max_cmdsn &&
!iscsi_sna_lt(max_cmdsn, session->max_cmdsn))
session->max_cmdsn = max_cmdsn;
+ spin_unlock_bh(&session->back_cmdsn_lock);
}
void iscsi_update_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr)
@@ -3067,6 +3069,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost,
spin_lock_init(&session->mgmt_lock);
spin_lock_init(&session->frwd_lock);
spin_lock_init(&session->back_lock);
+ spin_lock_init(&session->back_cmdsn_lock);
/* initialize mgmt task pool */
if (iscsi_pool_init(&session->mgmt_pool, ISCSI_MGMT_CMDS_MAX,
@@ -3470,9 +3473,9 @@ int iscsi_conn_bind(struct iscsi_cls_session *cls_session,
* The target could have reduced it's window size between logins, so
* we have to reset max/exp cmdsn so we can see the new values.
*/
- spin_lock_bh(&session->back_lock);
+ spin_lock_bh(&session->back_cmdsn_lock);
session->max_cmdsn = session->exp_cmdsn = session->cmdsn + 1;
- spin_unlock_bh(&session->back_lock);
+ spin_unlock_bh(&session->back_cmdsn_lock);
/*
* Unblock xmitworker(), Login Phase will pass through.
*/
@@ -559,9 +559,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
tcp_conn = conn->dd_data;
rhdr = (struct iscsi_r2t_rsp *)tcp_conn->in.hdr;
/* fill-in new R2T associated with the task */
- spin_lock(&session->back_lock);
iscsi_update_cmdsn(session, (struct iscsi_nopin *)rhdr);
- spin_unlock(&session->back_lock);
if (tcp_conn->in.datalen) {
iscsi_conn_printk(KERN_ERR, conn,
@@ -296,10 +296,12 @@ struct iscsi_session {
struct mutex eh_mutex;
/* iSCSI session-wide sequencing */
- uint32_t cmdsn;
+ /* Protects exp and max cmdsn */
+ spinlock_t back_cmdsn_lock;
uint32_t exp_cmdsn;
uint32_t max_cmdsn;
+ uint32_t cmdsn;
/* This tracks the reqs queued into the initiator */
uint32_t queued_cmdsn;
@@ -356,8 +358,7 @@ struct iscsi_session {
* cmdsn, suspend_bit, *
* leadconn, _stage, *
* tmf_state and queues */
- spinlock_t back_lock; /* protects cmdsn_exp and *
- * cmdsn_max */
+ spinlock_t back_lock;
/*
* frwd_lock must be held when transitioning states, but not needed
* if just checking the state in the scsi-ml or iscsi callouts.
This patch adds a lock for the max/exp_cmdsn handling. The next patch will then cleanup the back_lock uses. Signed-off-by: Mike Christie <michael.christie@oracle.com> --- drivers/scsi/libiscsi.c | 7 +++++-- drivers/scsi/libiscsi_tcp.c | 2 -- include/scsi/libiscsi.h | 7 ++++--- 3 files changed, 9 insertions(+), 7 deletions(-)