aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libiscsi.c
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2009-08-20 16:11:03 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-09-05 10:42:48 -0400
commit70b31c152dc49ef70bd2b34ad53ccbd9bb4116d4 (patch)
tree9d3c857ed4604b7843a0bec05e85afb095228082 /drivers/scsi/libiscsi.c
parentd1af8a328755f51c9b76157a8692e56520d3fd94 (diff)
[SCSI] libiscsi, iscsi_tcp: check suspend bit before each call to xmit_task
If we had multiple tasks on the cmd or requeue lists, and iscsi_tcp returns a error, the write_space function can still run and queue iscsi_data_xmit. If it was a legetimate problem and iscsi_conn_failure was run but we raced and iscsi_data_xmit was run first it could miss the suspend bit checks, and start trying to send data again and hit another timeout. A similar problem is present when using cxgb3i. This has libiscsi check the suspend bit before calling the xmit task callout, so we at least do not try sending multiple tasks (one could be sent). Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r--drivers/scsi/libiscsi.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 1d7a8b7e8a75..a7ee4bb40708 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1280,6 +1280,9 @@ static int iscsi_xmit_task(struct iscsi_conn *conn)
1280 struct iscsi_task *task = conn->task; 1280 struct iscsi_task *task = conn->task;
1281 int rc; 1281 int rc;
1282 1282
1283 if (test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx))
1284 return -ENODATA;
1285
1283 __iscsi_get_task(task); 1286 __iscsi_get_task(task);
1284 spin_unlock_bh(&conn->session->lock); 1287 spin_unlock_bh(&conn->session->lock);
1285 rc = conn->session->tt->xmit_task(task); 1288 rc = conn->session->tt->xmit_task(task);
@@ -1329,7 +1332,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
1329 int rc = 0; 1332 int rc = 0;
1330 1333
1331 spin_lock_bh(&conn->session->lock); 1334 spin_lock_bh(&conn->session->lock);
1332 if (unlikely(conn->suspend_tx)) { 1335 if (test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx)) {
1333 ISCSI_DBG_SESSION(conn->session, "Tx suspended!\n"); 1336 ISCSI_DBG_SESSION(conn->session, "Tx suspended!\n");
1334 spin_unlock_bh(&conn->session->lock); 1337 spin_unlock_bh(&conn->session->lock);
1335 return -ENODATA; 1338 return -ENODATA;
@@ -1338,7 +1341,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
1338 if (conn->task) { 1341 if (conn->task) {
1339 rc = iscsi_xmit_task(conn); 1342 rc = iscsi_xmit_task(conn);
1340 if (rc) 1343 if (rc)
1341 goto again; 1344 goto done;
1342 } 1345 }
1343 1346
1344 /* 1347 /*
@@ -1358,7 +1361,7 @@ check_mgmt:
1358 } 1361 }
1359 rc = iscsi_xmit_task(conn); 1362 rc = iscsi_xmit_task(conn);
1360 if (rc) 1363 if (rc)
1361 goto again; 1364 goto done;
1362 } 1365 }
1363 1366
1364 /* process pending command queue */ 1367 /* process pending command queue */
@@ -1379,14 +1382,14 @@ check_mgmt:
1379 list_add_tail(&conn->task->running, 1382 list_add_tail(&conn->task->running,
1380 &conn->cmdqueue); 1383 &conn->cmdqueue);
1381 conn->task = NULL; 1384 conn->task = NULL;
1382 goto again; 1385 goto done;
1383 } else 1386 } else
1384 fail_scsi_task(conn->task, DID_ABORT); 1387 fail_scsi_task(conn->task, DID_ABORT);
1385 continue; 1388 continue;
1386 } 1389 }
1387 rc = iscsi_xmit_task(conn); 1390 rc = iscsi_xmit_task(conn);
1388 if (rc) 1391 if (rc)
1389 goto again; 1392 goto done;
1390 /* 1393 /*
1391 * we could continuously get new task requests so 1394 * we could continuously get new task requests so
1392 * we need to check the mgmt queue for nops that need to 1395 * we need to check the mgmt queue for nops that need to
@@ -1412,16 +1415,14 @@ check_mgmt:
1412 conn->task->state = ISCSI_TASK_RUNNING; 1415 conn->task->state = ISCSI_TASK_RUNNING;
1413 rc = iscsi_xmit_task(conn); 1416 rc = iscsi_xmit_task(conn);
1414 if (rc) 1417 if (rc)
1415 goto again; 1418 goto done;
1416 if (!list_empty(&conn->mgmtqueue)) 1419 if (!list_empty(&conn->mgmtqueue))
1417 goto check_mgmt; 1420 goto check_mgmt;
1418 } 1421 }
1419 spin_unlock_bh(&conn->session->lock); 1422 spin_unlock_bh(&conn->session->lock);
1420 return -ENODATA; 1423 return -ENODATA;
1421 1424
1422again: 1425done:
1423 if (unlikely(conn->suspend_tx))
1424 rc = -ENODATA;
1425 spin_unlock_bh(&conn->session->lock); 1426 spin_unlock_bh(&conn->session->lock);
1426 return rc; 1427 return rc;
1427} 1428}