aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/iser
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 /drivers/infiniband/ulp/iser
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 'drivers/infiniband/ulp/iser')
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c18
1 files changed, 8 insertions, 10 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 6c8cd09c58f0..9782190a9ee5 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -134,19 +134,9 @@ iscsi_iser_cmd_init(struct iscsi_cmd_task *ctask)
134{ 134{
135 struct iscsi_iser_conn *iser_conn = ctask->conn->dd_data; 135 struct iscsi_iser_conn *iser_conn = ctask->conn->dd_data;
136 struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; 136 struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
137 struct scsi_cmnd *sc = ctask->sc;
138 137
139 iser_ctask->command_sent = 0; 138 iser_ctask->command_sent = 0;
140 iser_ctask->iser_conn = iser_conn; 139 iser_ctask->iser_conn = iser_conn;
141
142 if (sc->sc_data_direction == DMA_TO_DEVICE) {
143 BUG_ON(sc->request_bufflen == 0);
144
145 debug_scsi("cmd [itt %x total %d imm %d unsol_data %d\n",
146 ctask->itt, sc->request_bufflen, ctask->imm_count,
147 ctask->unsol_count);
148 }
149
150 iser_ctask_rdma_init(iser_ctask); 140 iser_ctask_rdma_init(iser_ctask);
151} 141}
152 142
@@ -219,6 +209,14 @@ iscsi_iser_ctask_xmit(struct iscsi_conn *conn,
219 struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data; 209 struct iscsi_iser_cmd_task *iser_ctask = ctask->dd_data;
220 int error = 0; 210 int error = 0;
221 211
212 if (ctask->sc->sc_data_direction == DMA_TO_DEVICE) {
213 BUG_ON(ctask->sc->request_bufflen == 0);
214
215 debug_scsi("cmd [itt %x total %d imm %d unsol_data %d\n",
216 ctask->itt, ctask->sc->request_bufflen,
217 ctask->imm_count, ctask->unsol_count);
218 }
219
222 debug_scsi("ctask deq [cid %d itt 0x%x]\n", 220 debug_scsi("ctask deq [cid %d itt 0x%x]\n",
223 conn->id, ctask->itt); 221 conn->id, ctask->itt);
224 222