Skip to content

Commit 03e7848

Browse files
author
Nicholas Bellinger
committed
iser-target: Add missing se_cmd put for WRITE_PENDING in tx_comp_err
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 <[email protected]> Cc: Or Gerlitz <[email protected]> Cc: <[email protected]> #3.10+ Signed-off-by: Nicholas Bellinger <[email protected]>
1 parent 131e6ab commit 03e7848

File tree

1 file changed

+26
-11
lines changed

1 file changed

+26
-11
lines changed

drivers/infiniband/ulp/isert/ib_isert.c

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,7 +1580,7 @@ isert_unreg_rdma(struct isert_cmd *isert_cmd, struct isert_conn *isert_conn)
15801580
}
15811581

15821582
static void
1583-
isert_put_cmd(struct isert_cmd *isert_cmd)
1583+
isert_put_cmd(struct isert_cmd *isert_cmd, bool comp_err)
15841584
{
15851585
struct iscsi_cmd *cmd = isert_cmd->iscsi_cmd;
15861586
struct isert_conn *isert_conn = isert_cmd->conn;
@@ -1596,8 +1596,21 @@ isert_put_cmd(struct isert_cmd *isert_cmd)
15961596
list_del_init(&cmd->i_conn_node);
15971597
spin_unlock_bh(&conn->cmd_lock);
15981598

1599-
if (cmd->data_direction == DMA_TO_DEVICE)
1599+
if (cmd->data_direction == DMA_TO_DEVICE) {
16001600
iscsit_stop_dataout_timer(cmd);
1601+
/*
1602+
* Check for special case during comp_err where
1603+
* WRITE_PENDING has been handed off from core,
1604+
* but requires an extra target_put_sess_cmd()
1605+
* before transport_generic_free_cmd() below.
1606+
*/
1607+
if (comp_err &&
1608+
cmd->se_cmd.t_state == TRANSPORT_WRITE_PENDING) {
1609+
struct se_cmd *se_cmd = &cmd->se_cmd;
1610+
1611+
target_put_sess_cmd(se_cmd->se_sess, se_cmd);
1612+
}
1613+
}
16011614

16021615
device->unreg_rdma_mem(isert_cmd, isert_conn);
16031616
transport_generic_free_cmd(&cmd->se_cmd, 0);
@@ -1652,7 +1665,7 @@ isert_unmap_tx_desc(struct iser_tx_desc *tx_desc, struct ib_device *ib_dev)
16521665

16531666
static void
16541667
isert_completion_put(struct iser_tx_desc *tx_desc, struct isert_cmd *isert_cmd,
1655-
struct ib_device *ib_dev)
1668+
struct ib_device *ib_dev, bool comp_err)
16561669
{
16571670
if (isert_cmd->pdu_buf_dma != 0) {
16581671
pr_debug("Calling ib_dma_unmap_single for isert_cmd->pdu_buf_dma\n");
@@ -1662,7 +1675,7 @@ isert_completion_put(struct iser_tx_desc *tx_desc, struct isert_cmd *isert_cmd,
16621675
}
16631676

16641677
isert_unmap_tx_desc(tx_desc, ib_dev);
1665-
isert_put_cmd(isert_cmd);
1678+
isert_put_cmd(isert_cmd, comp_err);
16661679
}
16671680

16681681
static int
@@ -1787,14 +1800,14 @@ isert_do_control_comp(struct work_struct *work)
17871800
iscsit_tmr_post_handler(cmd, cmd->conn);
17881801

17891802
cmd->i_state = ISTATE_SENT_STATUS;
1790-
isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev);
1803+
isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev, false);
17911804
break;
17921805
case ISTATE_SEND_REJECT:
17931806
pr_debug("Got isert_do_control_comp ISTATE_SEND_REJECT: >>>\n");
17941807
atomic_dec(&isert_conn->post_send_buf_count);
17951808

17961809
cmd->i_state = ISTATE_SENT_STATUS;
1797-
isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev);
1810+
isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev, false);
17981811
break;
17991812
case ISTATE_SEND_LOGOUTRSP:
18001813
pr_debug("Calling iscsit_logout_post_handler >>>>>>>>>>>>>>\n");
@@ -1808,7 +1821,7 @@ isert_do_control_comp(struct work_struct *work)
18081821
case ISTATE_SEND_TEXTRSP:
18091822
atomic_dec(&isert_conn->post_send_buf_count);
18101823
cmd->i_state = ISTATE_SENT_STATUS;
1811-
isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev);
1824+
isert_completion_put(&isert_cmd->tx_desc, isert_cmd, ib_dev, false);
18121825
break;
18131826
default:
18141827
pr_err("Unknown do_control_comp i_state %d\n", cmd->i_state);
@@ -1850,7 +1863,7 @@ isert_response_completion(struct iser_tx_desc *tx_desc,
18501863
atomic_dec(&isert_conn->post_send_buf_count);
18511864

18521865
cmd->i_state = ISTATE_SENT_STATUS;
1853-
isert_completion_put(tx_desc, isert_cmd, ib_dev);
1866+
isert_completion_put(tx_desc, isert_cmd, ib_dev, false);
18541867
}
18551868

18561869
static void
@@ -1943,7 +1956,8 @@ isert_cq_drain_comp_llist(struct isert_conn *isert_conn, struct ib_device *ib_de
19431956
&isert_conn->post_send_buf_count);
19441957
else
19451958
atomic_dec(&isert_conn->post_send_buf_count);
1946-
isert_completion_put(t, t->isert_cmd, ib_dev);
1959+
1960+
isert_completion_put(t, t->isert_cmd, ib_dev, true);
19471961
}
19481962
}
19491963

@@ -1973,14 +1987,15 @@ isert_cq_tx_comp_err(struct iser_tx_desc *tx_desc, struct isert_conn *isert_conn
19731987
&isert_conn->post_send_buf_count);
19741988
else
19751989
atomic_dec(&isert_conn->post_send_buf_count);
1976-
isert_completion_put(t, t->isert_cmd, ib_dev);
1990+
1991+
isert_completion_put(t, t->isert_cmd, ib_dev, true);
19771992
}
19781993
tx_desc->comp_llnode_batch = NULL;
19791994

19801995
if (!isert_cmd)
19811996
isert_unmap_tx_desc(tx_desc, ib_dev);
19821997
else
1983-
isert_completion_put(tx_desc, isert_cmd, ib_dev);
1998+
isert_completion_put(tx_desc, isert_cmd, ib_dev, true);
19841999
}
19852000

19862001
static void

0 commit comments

Comments
 (0)