aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2006-07-24 16:47:15 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-07-28 12:47:40 -0400
commitb6c395ed0387c824ddf125d3b74b576a2575c149 (patch)
tree76ca5cd982063335088384622e5033401bbc5057 /drivers
parentd82967c70658a408ea6cae5dc989ba8b2c0999e1 (diff)
[SCSI] iscsi bugfixes: fix r2t handling
The iscsi tcp code can pluck multiple rt2s from the tasks's r2tqueue in the xmit code. This can result in the task being queued on the xmit queue but gettting completed at the same time. This patch fixes the above bug by making the fifo a list so we always remove the entry on the list del. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/iscsi_tcp.c45
-rw-r--r--drivers/scsi/libiscsi.c90
2 files changed, 59 insertions, 76 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 88dafdf45c47..ab324d984b8d 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -185,11 +185,19 @@ iscsi_hdr_extract(struct iscsi_tcp_conn *tcp_conn)
185 * must be called with session lock 185 * must be called with session lock
186 */ 186 */
187static void 187static void
188__iscsi_ctask_cleanup(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) 188iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
189{ 189{
190 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 190 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
191 struct iscsi_r2t_info *r2t;
191 struct scsi_cmnd *sc; 192 struct scsi_cmnd *sc;
192 193
194 /* flush ctask's r2t queues */
195 while (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) {
196 __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
197 sizeof(void*));
198 debug_scsi("iscsi_tcp_cleanup_ctask pending r2t dropped\n");
199 }
200
193 sc = ctask->sc; 201 sc = ctask->sc;
194 if (unlikely(!sc)) 202 if (unlikely(!sc))
195 return; 203 return;
@@ -374,6 +382,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
374 spin_unlock(&session->lock); 382 spin_unlock(&session->lock);
375 return 0; 383 return 0;
376 } 384 }
385
377 rc = __kfifo_get(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); 386 rc = __kfifo_get(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*));
378 BUG_ON(!rc); 387 BUG_ON(!rc);
379 388
@@ -399,7 +408,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
399 tcp_ctask->exp_r2tsn = r2tsn + 1; 408 tcp_ctask->exp_r2tsn = r2tsn + 1;
400 tcp_ctask->xmstate |= XMSTATE_SOL_HDR; 409 tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
401 __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)); 410 __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*));
402 __kfifo_put(conn->xmitqueue, (void*)&ctask, sizeof(void*)); 411 list_move_tail(&ctask->running, &conn->xmitqueue);
403 412
404 scsi_queue_work(session->host, &conn->xmitwork); 413 scsi_queue_work(session->host, &conn->xmitwork);
405 conn->r2t_pdus_cnt++; 414 conn->r2t_pdus_cnt++;
@@ -484,7 +493,7 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn)
484 goto copy_hdr; 493 goto copy_hdr;
485 494
486 spin_lock(&session->lock); 495 spin_lock(&session->lock);
487 __iscsi_ctask_cleanup(conn, tcp_conn->in.ctask); 496 iscsi_tcp_cleanup_ctask(conn, tcp_conn->in.ctask);
488 rc = __iscsi_complete_pdu(conn, hdr, NULL, 0); 497 rc = __iscsi_complete_pdu(conn, hdr, NULL, 0);
489 spin_unlock(&session->lock); 498 spin_unlock(&session->lock);
490 break; 499 break;
@@ -745,10 +754,11 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
745done: 754done:
746 /* check for non-exceptional status */ 755 /* check for non-exceptional status */
747 if (tcp_conn->in.hdr->flags & ISCSI_FLAG_DATA_STATUS) { 756 if (tcp_conn->in.hdr->flags & ISCSI_FLAG_DATA_STATUS) {
748 debug_scsi("done [sc %lx res %d itt 0x%x]\n", 757 debug_scsi("done [sc %lx res %d itt 0x%x flags 0x%x]\n",
749 (long)sc, sc->result, ctask->itt); 758 (long)sc, sc->result, ctask->itt,
759 tcp_conn->in.hdr->flags);
750 spin_lock(&conn->session->lock); 760 spin_lock(&conn->session->lock);
751 __iscsi_ctask_cleanup(conn, ctask); 761 iscsi_tcp_cleanup_ctask(conn, ctask);
752 __iscsi_complete_pdu(conn, tcp_conn->in.hdr, NULL, 0); 762 __iscsi_complete_pdu(conn, tcp_conn->in.hdr, NULL, 0);
753 spin_unlock(&conn->session->lock); 763 spin_unlock(&conn->session->lock);
754 } 764 }
@@ -769,7 +779,7 @@ iscsi_data_recv(struct iscsi_conn *conn)
769 break; 779 break;
770 case ISCSI_OP_SCSI_CMD_RSP: 780 case ISCSI_OP_SCSI_CMD_RSP:
771 spin_lock(&conn->session->lock); 781 spin_lock(&conn->session->lock);
772 __iscsi_ctask_cleanup(conn, tcp_conn->in.ctask); 782 iscsi_tcp_cleanup_ctask(conn, tcp_conn->in.ctask);
773 spin_unlock(&conn->session->lock); 783 spin_unlock(&conn->session->lock);
774 case ISCSI_OP_TEXT_RSP: 784 case ISCSI_OP_TEXT_RSP:
775 case ISCSI_OP_LOGIN_RSP: 785 case ISCSI_OP_LOGIN_RSP:
@@ -1308,7 +1318,7 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask)
1308 ctask->imm_count - 1318 ctask->imm_count -
1309 ctask->unsol_count; 1319 ctask->unsol_count;
1310 1320
1311 debug_scsi("cmd [itt %x total %d imm %d imm_data %d " 1321 debug_scsi("cmd [itt 0x%x total %d imm %d imm_data %d "
1312 "r2t_data %d]\n", 1322 "r2t_data %d]\n",
1313 ctask->itt, ctask->total_length, ctask->imm_count, 1323 ctask->itt, ctask->total_length, ctask->imm_count,
1314 ctask->unsol_count, tcp_ctask->r2t_data_count); 1324 ctask->unsol_count, tcp_ctask->r2t_data_count);
@@ -1636,7 +1646,7 @@ handle_xmstate_sol_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1636 } 1646 }
1637solicit_again: 1647solicit_again:
1638 /* 1648 /*
1639 * send Data-Out whitnin this R2T sequence. 1649 * send Data-Out within this R2T sequence.
1640 */ 1650 */
1641 if (!r2t->data_count) 1651 if (!r2t->data_count)
1642 goto data_out_done; 1652 goto data_out_done;
@@ -1731,7 +1741,7 @@ handle_xmstate_w_pad(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1731 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1741 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1732 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 1742 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1733 struct iscsi_data_task *dtask = tcp_ctask->dtask; 1743 struct iscsi_data_task *dtask = tcp_ctask->dtask;
1734 int sent, rc; 1744 int sent = 0, rc;
1735 1745
1736 tcp_ctask->xmstate &= ~XMSTATE_W_PAD; 1746 tcp_ctask->xmstate &= ~XMSTATE_W_PAD;
1737 iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad, 1747 iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad,
@@ -2002,20 +2012,6 @@ iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session,
2002} 2012}
2003 2013
2004static void 2014static void
2005iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
2006{
2007 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
2008 struct iscsi_r2t_info *r2t;
2009
2010 /* flush ctask's r2t queues */
2011 while (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)))
2012 __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
2013 sizeof(void*));
2014
2015 __iscsi_ctask_cleanup(conn, ctask);
2016}
2017
2018static void
2019iscsi_tcp_suspend_conn_rx(struct iscsi_conn *conn) 2015iscsi_tcp_suspend_conn_rx(struct iscsi_conn *conn)
2020{ 2016{
2021 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 2017 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
@@ -2057,6 +2053,7 @@ iscsi_tcp_mgmt_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask,
2057 iscsi_buf_init_iov(&tcp_mtask->headbuf, (char*)mtask->hdr, 2053 iscsi_buf_init_iov(&tcp_mtask->headbuf, (char*)mtask->hdr,
2058 sizeof(struct iscsi_hdr)); 2054 sizeof(struct iscsi_hdr));
2059 tcp_mtask->xmstate = XMSTATE_IMM_HDR; 2055 tcp_mtask->xmstate = XMSTATE_IMM_HDR;
2056 tcp_mtask->sent = 0;
2060 2057
2061 if (mtask->data_count) 2058 if (mtask->data_count)
2062 iscsi_buf_init_iov(&tcp_mtask->sendbuf, (char*)mtask->data, 2059 iscsi_buf_init_iov(&tcp_mtask->sendbuf, (char*)mtask->data,
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 7e6e031cc41b..1a8cd20f484f 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -189,6 +189,7 @@ static void iscsi_complete_command(struct iscsi_session *session,
189{ 189{
190 struct scsi_cmnd *sc = ctask->sc; 190 struct scsi_cmnd *sc = ctask->sc;
191 191
192 ctask->state = ISCSI_TASK_COMPLETED;
192 ctask->sc = NULL; 193 ctask->sc = NULL;
193 list_del_init(&ctask->running); 194 list_del_init(&ctask->running);
194 __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*)); 195 __kfifo_put(session->cmdpool.queue, (void*)&ctask, sizeof(void*));
@@ -568,20 +569,24 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
568 } 569 }
569 570
570 /* process command queue */ 571 /* process command queue */
571 while (__kfifo_get(conn->xmitqueue, (void*)&conn->ctask, 572 spin_lock_bh(&conn->session->lock);
572 sizeof(void*))) { 573 while (!list_empty(&conn->xmitqueue)) {
573 /* 574 /*
574 * iscsi tcp may readd the task to the xmitqueue to send 575 * iscsi tcp may readd the task to the xmitqueue to send
575 * write data 576 * write data
576 */ 577 */
577 spin_lock_bh(&conn->session->lock); 578 conn->ctask = list_entry(conn->xmitqueue.next,
578 if (list_empty(&conn->ctask->running)) 579 struct iscsi_cmd_task, running);
579 list_add_tail(&conn->ctask->running, &conn->run_list); 580 conn->ctask->state = ISCSI_TASK_RUNNING;
581 list_move_tail(conn->xmitqueue.next, &conn->run_list);
580 spin_unlock_bh(&conn->session->lock); 582 spin_unlock_bh(&conn->session->lock);
583
581 rc = tt->xmit_cmd_task(conn, conn->ctask); 584 rc = tt->xmit_cmd_task(conn, conn->ctask);
582 if (rc) 585 if (rc)
583 goto again; 586 goto again;
587 spin_lock_bh(&conn->session->lock);
584 } 588 }
589 spin_unlock_bh(&conn->session->lock);
585 /* done with this ctask */ 590 /* done with this ctask */
586 conn->ctask = NULL; 591 conn->ctask = NULL;
587 592
@@ -691,6 +696,7 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
691 sc->SCp.phase = session->age; 696 sc->SCp.phase = session->age;
692 sc->SCp.ptr = (char *)ctask; 697 sc->SCp.ptr = (char *)ctask;
693 698
699 ctask->state = ISCSI_TASK_PENDING;
694 ctask->mtask = NULL; 700 ctask->mtask = NULL;
695 ctask->conn = conn; 701 ctask->conn = conn;
696 ctask->sc = sc; 702 ctask->sc = sc;
@@ -700,7 +706,7 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
700 706
701 session->tt->init_cmd_task(ctask); 707 session->tt->init_cmd_task(ctask);
702 708
703 __kfifo_put(conn->xmitqueue, (void*)&ctask, sizeof(void*)); 709 list_add_tail(&ctask->running, &conn->xmitqueue);
704 debug_scsi( 710 debug_scsi(
705 "ctask enq [%s cid %d sc %lx itt 0x%x len %d cmdsn %d win %d]\n", 711 "ctask enq [%s cid %d sc %lx itt 0x%x len %d cmdsn %d win %d]\n",
706 sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read", 712 sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read",
@@ -977,31 +983,27 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc,
977/* 983/*
978 * xmit mutex and session lock must be held 984 * xmit mutex and session lock must be held
979 */ 985 */
980#define iscsi_remove_task(tasktype) \ 986static struct iscsi_mgmt_task *
981static struct iscsi_##tasktype * \ 987iscsi_remove_mgmt_task(struct kfifo *fifo, uint32_t itt)
982iscsi_remove_##tasktype(struct kfifo *fifo, uint32_t itt) \ 988{
983{ \ 989 int i, nr_tasks = __kfifo_len(fifo) / sizeof(void*);
984 int i, nr_tasks = __kfifo_len(fifo) / sizeof(void*); \ 990 struct iscsi_mgmt_task *task;
985 struct iscsi_##tasktype *task; \ 991
986 \ 992 debug_scsi("searching %d tasks\n", nr_tasks);
987 debug_scsi("searching %d tasks\n", nr_tasks); \ 993
988 \ 994 for (i = 0; i < nr_tasks; i++) {
989 for (i = 0; i < nr_tasks; i++) { \ 995 __kfifo_get(fifo, (void*)&task, sizeof(void*));
990 __kfifo_get(fifo, (void*)&task, sizeof(void*)); \ 996 debug_scsi("check task %u\n", task->itt);
991 debug_scsi("check task %u\n", task->itt); \ 997
992 \ 998 if (task->itt == itt) {
993 if (task->itt == itt) { \ 999 debug_scsi("matched task\n");
994 debug_scsi("matched task\n"); \ 1000 return task;
995 return task; \ 1001 }
996 } \
997 \
998 __kfifo_put(fifo, (void*)&task, sizeof(void*)); \
999 } \
1000 return NULL; \
1001}
1002 1002
1003iscsi_remove_task(mgmt_task); 1003 __kfifo_put(fifo, (void*)&task, sizeof(void*));
1004iscsi_remove_task(cmd_task); 1004 }
1005 return NULL;
1006}
1005 1007
1006static int iscsi_ctask_mtask_cleanup(struct iscsi_cmd_task *ctask) 1008static int iscsi_ctask_mtask_cleanup(struct iscsi_cmd_task *ctask)
1007{ 1009{
@@ -1043,7 +1045,6 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
1043 struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)sc->SCp.ptr; 1045 struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)sc->SCp.ptr;
1044 struct iscsi_conn *conn = ctask->conn; 1046 struct iscsi_conn *conn = ctask->conn;
1045 struct iscsi_session *session = conn->session; 1047 struct iscsi_session *session = conn->session;
1046 struct iscsi_cmd_task *pending_ctask;
1047 int rc; 1048 int rc;
1048 1049
1049 conn->eh_abort_cnt++; 1050 conn->eh_abort_cnt++;
@@ -1071,17 +1072,8 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
1071 goto failed; 1072 goto failed;
1072 } 1073 }
1073 1074
1074 /* check for the easy pending cmd abort */ 1075 if (ctask->state == ISCSI_TASK_PENDING)
1075 pending_ctask = iscsi_remove_cmd_task(conn->xmitqueue, ctask->itt); 1076 goto success;
1076 if (pending_ctask) {
1077 /* iscsi_tcp queues write transfers on the xmitqueue */
1078 if (list_empty(&pending_ctask->running)) {
1079 debug_scsi("found pending task\n");
1080 goto success;
1081 } else
1082 __kfifo_put(conn->xmitqueue, (void*)&pending_ctask,
1083 sizeof(void*));
1084 }
1085 1077
1086 conn->tmabort_state = TMABORT_INITIAL; 1078 conn->tmabort_state = TMABORT_INITIAL;
1087 1079
@@ -1263,6 +1255,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit,
1263 if (cmd_task_size) 1255 if (cmd_task_size)
1264 ctask->dd_data = &ctask[1]; 1256 ctask->dd_data = &ctask[1];
1265 ctask->itt = cmd_i; 1257 ctask->itt = cmd_i;
1258 INIT_LIST_HEAD(&ctask->running);
1266 } 1259 }
1267 1260
1268 spin_lock_init(&session->lock); 1261 spin_lock_init(&session->lock);
@@ -1282,6 +1275,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit,
1282 if (mgmt_task_size) 1275 if (mgmt_task_size)
1283 mtask->dd_data = &mtask[1]; 1276 mtask->dd_data = &mtask[1];
1284 mtask->itt = ISCSI_MGMT_ITT_OFFSET + cmd_i; 1277 mtask->itt = ISCSI_MGMT_ITT_OFFSET + cmd_i;
1278 INIT_LIST_HEAD(&mtask->running);
1285 } 1279 }
1286 1280
1287 if (scsi_add_host(shost, NULL)) 1281 if (scsi_add_host(shost, NULL))
@@ -1361,12 +1355,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
1361 conn->tmabort_state = TMABORT_INITIAL; 1355 conn->tmabort_state = TMABORT_INITIAL;
1362 INIT_LIST_HEAD(&conn->run_list); 1356 INIT_LIST_HEAD(&conn->run_list);
1363 INIT_LIST_HEAD(&conn->mgmt_run_list); 1357 INIT_LIST_HEAD(&conn->mgmt_run_list);
1364 1358 INIT_LIST_HEAD(&conn->xmitqueue);
1365 /* initialize general xmit PDU commands queue */
1366 conn->xmitqueue = kfifo_alloc(session->cmds_max * sizeof(void*),
1367 GFP_KERNEL, NULL);
1368 if (conn->xmitqueue == ERR_PTR(-ENOMEM))
1369 goto xmitqueue_alloc_fail;
1370 1359
1371 /* initialize general immediate & non-immediate PDU commands queue */ 1360 /* initialize general immediate & non-immediate PDU commands queue */
1372 conn->immqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*), 1361 conn->immqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*),
@@ -1410,8 +1399,6 @@ login_mtask_alloc_fail:
1410mgmtqueue_alloc_fail: 1399mgmtqueue_alloc_fail:
1411 kfifo_free(conn->immqueue); 1400 kfifo_free(conn->immqueue);
1412immqueue_alloc_fail: 1401immqueue_alloc_fail:
1413 kfifo_free(conn->xmitqueue);
1414xmitqueue_alloc_fail:
1415 iscsi_destroy_conn(cls_conn); 1402 iscsi_destroy_conn(cls_conn);
1416 return NULL; 1403 return NULL;
1417} 1404}
@@ -1489,7 +1476,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
1489 session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1; 1476 session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1;
1490 spin_unlock_bh(&session->lock); 1477 spin_unlock_bh(&session->lock);
1491 1478
1492 kfifo_free(conn->xmitqueue);
1493 kfifo_free(conn->immqueue); 1479 kfifo_free(conn->immqueue);
1494 kfifo_free(conn->mgmtqueue); 1480 kfifo_free(conn->mgmtqueue);
1495 1481
@@ -1572,7 +1558,7 @@ static void fail_all_commands(struct iscsi_conn *conn)
1572 struct iscsi_cmd_task *ctask, *tmp; 1558 struct iscsi_cmd_task *ctask, *tmp;
1573 1559
1574 /* flush pending */ 1560 /* flush pending */
1575 while (__kfifo_get(conn->xmitqueue, (void*)&ctask, sizeof(void*))) { 1561 list_for_each_entry_safe(ctask, tmp, &conn->xmitqueue, running) {
1576 debug_scsi("failing pending sc %p itt 0x%x\n", ctask->sc, 1562 debug_scsi("failing pending sc %p itt 0x%x\n", ctask->sc,
1577 ctask->itt); 1563 ctask->itt);
1578 fail_command(conn, ctask, DID_BUS_BUSY << 16); 1564 fail_command(conn, ctask, DID_BUS_BUSY << 16);