Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ebbe442

Browse files
author
Nicholas Bellinger
committed
iser-target: Fix command leak for tx_desc->comp_llnode_batch
This patch addresses a number of active I/O shutdown issues related to isert_cmd descriptors being leaked that are part of a completion interrupt coalescing batch. This includes adding logic in isert_cq_tx_comp_err() to drain any associated tx_desc->comp_llnode_batch, as well as isert_cq_drain_comp_llist() to drain any associated isert_conn->conn_comp_llist. Also, set tx_desc->llnode_active in isert_init_send_wr() in order to determine when work requests need to be skipped in isert_cq_tx_work() exception path code. Finally, update isert_init_send_wr() to only allow interrupt coalescing when ISER_CONN_UP. Acked-by: Sagi Grimberg <[email protected]> Cc: Or Gerlitz <[email protected]> Cc: <[email protected]> #3.13+ Signed-off-by: Nicholas Bellinger <[email protected]>
1 parent 9bb4ca6 commit ebbe442

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

drivers/infiniband/ulp/isert/ib_isert.c

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,6 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
497497
kref_init(&isert_conn->conn_kref);
498498
kref_get(&isert_conn->conn_kref);
499499
mutex_init(&isert_conn->conn_mutex);
500-
mutex_init(&isert_conn->conn_comp_mutex);
501500
spin_lock_init(&isert_conn->conn_lock);
502501

503502
cma_id->context = isert_conn;
@@ -888,16 +887,17 @@ isert_init_send_wr(struct isert_conn *isert_conn, struct isert_cmd *isert_cmd,
888887
* Coalesce send completion interrupts by only setting IB_SEND_SIGNALED
889888
* bit for every ISERT_COMP_BATCH_COUNT number of ib_post_send() calls.
890889
*/
891-
mutex_lock(&isert_conn->conn_comp_mutex);
892-
if (coalesce &&
890+
mutex_lock(&isert_conn->conn_mutex);
891+
if (coalesce && isert_conn->state == ISER_CONN_UP &&
893892
++isert_conn->conn_comp_batch < ISERT_COMP_BATCH_COUNT) {
893+
tx_desc->llnode_active = true;
894894
llist_add(&tx_desc->comp_llnode, &isert_conn->conn_comp_llist);
895-
mutex_unlock(&isert_conn->conn_comp_mutex);
895+
mutex_unlock(&isert_conn->conn_mutex);
896896
return;
897897
}
898898
isert_conn->conn_comp_batch = 0;
899899
tx_desc->comp_llnode_batch = llist_del_all(&isert_conn->conn_comp_llist);
900-
mutex_unlock(&isert_conn->conn_comp_mutex);
900+
mutex_unlock(&isert_conn->conn_mutex);
901901

902902
send_wr->send_flags = IB_SEND_SIGNALED;
903903
}
@@ -1692,11 +1692,46 @@ isert_send_completion(struct iser_tx_desc *tx_desc,
16921692
__isert_send_completion(tx_desc, isert_conn);
16931693
}
16941694

1695+
static void
1696+
isert_cq_drain_comp_llist(struct isert_conn *isert_conn, struct ib_device *ib_dev)
1697+
{
1698+
struct llist_node *llnode;
1699+
struct isert_rdma_wr *wr;
1700+
struct iser_tx_desc *t;
1701+
1702+
mutex_lock(&isert_conn->conn_mutex);
1703+
llnode = llist_del_all(&isert_conn->conn_comp_llist);
1704+
isert_conn->conn_comp_batch = 0;
1705+
mutex_unlock(&isert_conn->conn_mutex);
1706+
1707+
while (llnode) {
1708+
t = llist_entry(llnode, struct iser_tx_desc, comp_llnode);
1709+
llnode = llist_next(llnode);
1710+
wr = &t->isert_cmd->rdma_wr;
1711+
1712+
atomic_sub(wr->send_wr_num + 1, &isert_conn->post_send_buf_count);
1713+
isert_completion_put(t, t->isert_cmd, ib_dev);
1714+
}
1715+
}
1716+
16951717
static void
16961718
isert_cq_tx_comp_err(struct iser_tx_desc *tx_desc, struct isert_conn *isert_conn)
16971719
{
16981720
struct ib_device *ib_dev = isert_conn->conn_cm_id->device;
16991721
struct isert_cmd *isert_cmd = tx_desc->isert_cmd;
1722+
struct llist_node *llnode = tx_desc->comp_llnode_batch;
1723+
struct isert_rdma_wr *wr;
1724+
struct iser_tx_desc *t;
1725+
1726+
while (llnode) {
1727+
t = llist_entry(llnode, struct iser_tx_desc, comp_llnode);
1728+
llnode = llist_next(llnode);
1729+
wr = &t->isert_cmd->rdma_wr;
1730+
1731+
atomic_sub(wr->send_wr_num + 1, &isert_conn->post_send_buf_count);
1732+
isert_completion_put(t, t->isert_cmd, ib_dev);
1733+
}
1734+
tx_desc->comp_llnode_batch = NULL;
17001735

17011736
if (!isert_cmd)
17021737
isert_unmap_tx_desc(tx_desc, ib_dev);
@@ -1713,6 +1748,8 @@ isert_cq_rx_comp_err(struct isert_conn *isert_conn)
17131748
if (isert_conn->post_recv_buf_count)
17141749
return;
17151750

1751+
isert_cq_drain_comp_llist(isert_conn, ib_dev);
1752+
17161753
if (conn->sess) {
17171754
target_sess_cmd_list_set_waiting(conn->sess->se_sess);
17181755
target_wait_for_sess_cmds(conn->sess->se_sess);
@@ -1752,6 +1789,9 @@ isert_cq_tx_work(struct work_struct *work)
17521789
pr_debug("TX wc.vendor_err: 0x%08x\n", wc.vendor_err);
17531790

17541791
if (wc.wr_id != ISER_FASTREG_LI_WRID) {
1792+
if (tx_desc->llnode_active)
1793+
continue;
1794+
17551795
atomic_dec(&isert_conn->post_send_buf_count);
17561796
isert_cq_tx_comp_err(tx_desc, isert_conn);
17571797
}

drivers/infiniband/ulp/isert/ib_isert.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ struct iser_tx_desc {
4646
struct isert_cmd *isert_cmd;
4747
struct llist_node *comp_llnode_batch;
4848
struct llist_node comp_llnode;
49+
bool llnode_active;
4950
struct ib_send_wr send_wr;
5051
} __packed;
5152

@@ -127,7 +128,6 @@ struct isert_conn {
127128
#define ISERT_COMP_BATCH_COUNT 8
128129
int conn_comp_batch;
129130
struct llist_head conn_comp_llist;
130-
struct mutex conn_comp_mutex;
131131
};
132132

133133
#define ISERT_MAX_CQ 64

0 commit comments

Comments
 (0)