aboutsummaryrefslogtreecommitdiffstats
path: root/include/scsi
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2007-05-30 13:57:18 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-06-02 15:34:14 -0400
commit77a23c21aaa723f6b0ffc4a701be8c8e5a32346d (patch)
tree5b51b8299a8deede4c91dffde032899ab76e331a /include/scsi
parent218432c68085d6c2b04df57daaf105d2ffa2aa61 (diff)
[SCSI] libiscsi: fix iscsi cmdsn allocation
The cmdsn allocation and pdu transmit code can race, and we can end up sending a pdu with cmdsn 10 before a pdu with 5. The target will then fail the connection/session. This patch fixes the problem by delaying the cmdsn allocation until we are about to send the pdu. This also removes the xmitmutex. We were using the connection xmitmutex during error handling to handle races with mtask and ctask cleanup and completion. For ctasks we now have nice refcounting and for the mtask, if we hit the case where the mtask timesout and it is floating around somewhere in the driver, we end up dropping the session. And to handle session level cleanup, we use the xmit suspend bit along with scsi_flush_queue and the session lock to make sure that the xmit thread is not possibly transmitting a task while we are trying to kill it. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Cc: Roland Dreier <rdreier@cisco.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'include/scsi')
-rw-r--r--include/scsi/libiscsi.h11
-rw-r--r--include/scsi/scsi_transport_iscsi.h3
2 files changed, 3 insertions, 11 deletions
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 61bc8f75b267..8d48cf8f2e3f 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -90,6 +90,7 @@ enum {
90 ISCSI_TASK_COMPLETED, 90 ISCSI_TASK_COMPLETED,
91 ISCSI_TASK_PENDING, 91 ISCSI_TASK_PENDING,
92 ISCSI_TASK_RUNNING, 92 ISCSI_TASK_RUNNING,
93 ISCSI_TASK_ABORTING,
93}; 94};
94 95
95struct iscsi_cmd_task { 96struct iscsi_cmd_task {
@@ -150,18 +151,11 @@ struct iscsi_conn {
150 struct iscsi_cmd_task *ctask; /* xmit ctask in progress */ 151 struct iscsi_cmd_task *ctask; /* xmit ctask in progress */
151 152
152 /* xmit */ 153 /* xmit */
153 struct kfifo *immqueue; /* immediate xmit queue */
154 struct kfifo *mgmtqueue; /* mgmt (control) xmit queue */ 154 struct kfifo *mgmtqueue; /* mgmt (control) xmit queue */
155 struct list_head mgmt_run_list; /* list of control tasks */ 155 struct list_head mgmt_run_list; /* list of control tasks */
156 struct list_head xmitqueue; /* data-path cmd queue */ 156 struct list_head xmitqueue; /* data-path cmd queue */
157 struct list_head run_list; /* list of cmds in progress */ 157 struct list_head run_list; /* list of cmds in progress */
158 struct work_struct xmitwork; /* per-conn. xmit workqueue */ 158 struct work_struct xmitwork; /* per-conn. xmit workqueue */
159 /*
160 * serializes connection xmit, access to kfifos:
161 * xmitqueue, immqueue, mgmtqueue
162 */
163 struct mutex xmitmutex;
164
165 unsigned long suspend_tx; /* suspend Tx */ 159 unsigned long suspend_tx; /* suspend Tx */
166 unsigned long suspend_rx; /* suspend Rx */ 160 unsigned long suspend_rx; /* suspend Rx */
167 161
@@ -303,8 +297,7 @@ extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
303/* 297/*
304 * pdu and task processing 298 * pdu and task processing
305 */ 299 */
306extern int iscsi_check_assign_cmdsn(struct iscsi_session *, 300extern void iscsi_update_cmdsn(struct iscsi_session *, struct iscsi_nopin *);
307 struct iscsi_nopin *);
308extern void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *, 301extern void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *,
309 struct iscsi_data *hdr); 302 struct iscsi_data *hdr);
310extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *, 303extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *,
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index 1ac450b06909..abc4068621d8 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -117,8 +117,7 @@ struct iscsi_transport {
117 struct iscsi_stats *stats); 117 struct iscsi_stats *stats);
118 void (*init_cmd_task) (struct iscsi_cmd_task *ctask); 118 void (*init_cmd_task) (struct iscsi_cmd_task *ctask);
119 void (*init_mgmt_task) (struct iscsi_conn *conn, 119 void (*init_mgmt_task) (struct iscsi_conn *conn,
120 struct iscsi_mgmt_task *mtask, 120 struct iscsi_mgmt_task *mtask);
121 char *data, uint32_t data_size);
122 int (*xmit_cmd_task) (struct iscsi_conn *conn, 121 int (*xmit_cmd_task) (struct iscsi_conn *conn,
123 struct iscsi_cmd_task *ctask); 122 struct iscsi_cmd_task *ctask);
124 void (*cleanup_cmd_task) (struct iscsi_conn *conn, 123 void (*cleanup_cmd_task) (struct iscsi_conn *conn,