aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2014-03-30 18:50:03 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-05-13 07:59:40 -0400
commitd306606e58d53a9d8cd78fefacbe9a50b3aa9fcd (patch)
tree4ff53131f6e1b06540a6f0415bb99a6810a68157
parent50c648e394a0968f19d448b70bec82da88219963 (diff)
iser-target: Add missing se_cmd put for WRITE_PENDING in tx_comp_err
commit 03e7848a64ed535a30f5d7fc6dede2d5a6a2534b upstream. This patch fixes a bug where outstanding RDMA_READs with WRITE_PENDING status require an extra target_put_sess_cmd() in isert_put_cmd() code when called from isert_cq_tx_comp_err() + isert_cq_drain_comp_llist() context during session shutdown. The extra kref PUT is required so that transport_generic_free_cmd() invokes the last target_put_sess_cmd() -> target_release_cmd_kref(), which will complete(&se_cmd->cmd_wait_comp) the outstanding se_cmd descriptor with WRITE_PENDING status, and awake the completion in target_wait_for_sess_cmds() to invoke TFO->release_cmd(). The bug was manifesting itself in target_wait_for_sess_cmds() where a se_cmd descriptor with WRITE_PENDING status would end up sleeping indefinately. Acked-by: Sagi Grimberg <sagig@mellanox.com> Cc: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/infiniband/ulp/isert/ib_isert.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index 588a5eca63d8..ce6c603a3cc9 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -1201,7 +1201,7 @@ isert_unmap_cmd(struct isert_cmd *isert_cmd, struct isert_conn *isert_conn)
1201} 1201}
1202 1202
1203static void 1203static void
1204isert_put_cmd(struct isert_cmd *isert_cmd) 1204isert_put_cmd(struct isert_cmd *isert_cmd, bool comp_err)
1205{ 1205{
1206 struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd; 1206 struct iscsi_cmd *cmd = &isert_cmd->iscsi_cmd;
1207 struct isert_conn *isert_conn = isert_cmd->conn; 1207 struct isert_conn *isert_conn = isert_cmd->conn;
@@ -1216,8 +1216,21 @@ isert_put_cmd(struct isert_cmd *isert_cmd)
1216 list_del_init(&cmd->i_conn_node); 1216 list_del_init(&cmd->i_conn_node);
1217 spin_unlock_bh(&conn->cmd_lock); 1217 spin_unlock_bh(&conn->cmd_lock);
1218 1218
1219 if (cmd->data_direction == DMA_TO_DEVICE) 1219 if (cmd->data_direction == DMA_TO_DEVICE) {
1220 iscsit_stop_dataout_timer(cmd); 1220 iscsit_stop_dataout_timer(cmd);
1221 /*
1222 * Check for special case during comp_err where
1223 * WRITE_PENDING has been handed off from core,
1224 * but requires an extra target_put_sess_cmd()
1225 * before transport_generic_free_cmd() below.
1226 */
1227 if (comp_err &&
1228 cmd->se_cmd.t_state == TRANSPORT_WRITE_PENDING) {
1229 struct se_cmd *se_cmd = &cmd->se_cmd;
1230
1231 target_put_sess_cmd(se_cmd->se_sess, se_cmd);
1232 }
1233 }
1221 1234
1222 isert_unmap_cmd(isert_cmd, isert_conn); 1235 isert_unmap_cmd(isert_cmd, isert_conn);
1223 transport_generic_free_cmd(&cmd->se_cmd, 0); 1236 transport_generic_free_cmd(&cmd->se_cmd, 0);
@@ -1271,7 +1284,7 @@ isert_unmap_tx_desc(struct iser_tx_desc *tx_desc, struct ib_device *ib_dev)
1271 1284
1272static void 1285static void
1273isert_completion_put(struct iser_tx_desc *tx_desc, struct isert_cmd *isert_cmd, 1286isert_completion_put(struct iser_tx_desc *tx_desc, struct isert_cmd *isert_cmd,
1274 struct ib_device *ib_dev) 1287 struct ib_device *ib_dev, bool comp_err)
1275{ 1288{
1276 if (isert_cmd->sense_buf_dma != 0) { 1289 if (isert_cmd->sense_buf_dma != 0) {
1277 pr_debug("Calling ib_dma_unmap_single for isert_cmd->sense_buf_dma\n"); 1290 pr_debug("Calling ib_dma_unmap_single for isert_cmd->sense_buf_dma\n");
@@ -1281,7 +1294,7 @@ isert_completion_put(struct iser_tx_desc *tx_desc, struct isert_cmd *isert_cmd,
1281 } 1294 }
1282 1295
1283 isert_unmap_tx_desc(tx_desc, ib_dev); 1296 isert_unmap_tx_desc(tx_desc, ib_dev);
1284 isert_put_cmd(isert_cmd); 1297 isert_put_cmd(isert_cmd, comp_err);
1285} 1298}
1286 1299
1287static void 1300static void
@@ -1336,14 +1349,14 @@ isert_do_control_comp(struct work_struct *work)
1336 iscsit_tmr_post_handler(cmd, cmd->conn); 1349 iscsit_tmr_post_handler(cmd, cmd->conn);
1337 1350
1338 cmd->i_state = ISTATE_SENT_STATUS; 1351 cmd->i_state = ISTATE_SENT_STATUS;
1339 isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev); 1352 isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev, false);
1340 break; 1353 break;
1341 case ISTATE_SEND_REJECT: 1354 case ISTATE_SEND_REJECT:
1342 pr_debug("Got isert_do_control_comp ISTATE_SEND_REJECT: >>>\n"); 1355 pr_debug("Got isert_do_control_comp ISTATE_SEND_REJECT: >>>\n");
1343 atomic_dec(&isert_conn->post_send_buf_count); 1356 atomic_dec(&isert_conn->post_send_buf_count);
1344 1357
1345 cmd->i_state = ISTATE_SENT_STATUS; 1358 cmd->i_state = ISTATE_SENT_STATUS;
1346 isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev); 1359 isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev, false);
1347 break; 1360 break;
1348 case ISTATE_SEND_LOGOUTRSP: 1361 case ISTATE_SEND_LOGOUTRSP:
1349 pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n"); 1362 pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n");
@@ -1382,7 +1395,7 @@ isert_response_completion(struct iser_tx_desc *tx_desc,
1382 atomic_sub(wr->send_wr_num + 1, &isert_conn->post_send_buf_count); 1395 atomic_sub(wr->send_wr_num + 1, &isert_conn->post_send_buf_count);
1383 1396
1384 cmd->i_state = ISTATE_SENT_STATUS; 1397 cmd->i_state = ISTATE_SENT_STATUS;
1385 isert_completion_put(tx_desc, isert_cmd, ib_dev); 1398 isert_completion_put(tx_desc, isert_cmd, ib_dev, false);
1386} 1399}
1387 1400
1388static void 1401static void
@@ -1436,7 +1449,7 @@ isert_cq_tx_comp_err(struct iser_tx_desc *tx_desc, struct isert_conn *isert_conn
1436 if (!isert_cmd) 1449 if (!isert_cmd)
1437 isert_unmap_tx_desc(tx_desc, ib_dev); 1450 isert_unmap_tx_desc(tx_desc, ib_dev);
1438 else 1451 else
1439 isert_completion_put(tx_desc, isert_cmd, ib_dev); 1452 isert_completion_put(tx_desc, isert_cmd, ib_dev, true);
1440} 1453}
1441 1454
1442static void 1455static void