[PATCH v6 4/6] IB/isert: drop the promotion reference when a connection errors out

From: Yehyeong Lee

Date: Tue Nov 03 2026 - 17:40:27 EST


isert_connected_handler() takes a reference when it moves a connection to
ISER_CONN_UP, and the paths that give a promoted connection up drop it
again. isert_connect_error() does not: it drops one reference for any
state. A promoted connection that then gets an error event keeps one
reference for ever, so isert_connect_release() never runs and the
isert_device reference it holds is never returned. isert_remove_one()
waits for that in wait_for_completion(&removal_comp).

A REJ after the RTU reaches this path. cm_rej_handler() accepts
IB_CM_ESTABLISHED while lap_state is IB_CM_LAP_UNINIT, and a passive id
stays in RDMA_CM_CONNECT after ESTABLISHED, so cma_ib_handler() passes the
event on as RDMA_CM_EVENT_REJECTED.

Drop the promotion reference too when the connection being given up was
promoted. A test-only knob delivered that event to eight promoted
connections. On patches 1 to 3 of this series the device delete did not
return within 240 seconds in any of three runs, each printed ten hung task
warnings, and isert_device_put() ran once, twice and twice, the first of
those being the one isert_remove_one() does itself. Three runs with this
patch ran it nine times and the delete returned in 15 seconds.

INFO: task rdma:206 blocked for more than 10 seconds.
Not tainted 7.4.0-rc1-NR3-00004-g11e5479fd20e #123
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:rdma state:D stack:26592 pid:206 tgid:206 ppid:1 task_flags:0x400100 flags:0x00080800
Call Trace:
<TASK>
__schedule+0x180f/0x4bb0
? filter_irq_stacks+0x71/0x90
? __pfx___schedule+0x10/0x10
? kasan_save_track+0x14/0x30
schedule+0x70/0x1f0
schedule_timeout+0x1cd/0x200
? __pfx_schedule_timeout+0x10/0x10
? vprintk_emit+0x200/0x2f0
? __pfx__raw_spin_lock_irq+0x10/0x10
__wait_for_common+0x29e/0x420
? __pfx_schedule_timeout+0x10/0x10
? __pfx___wait_for_common+0x10/0x10
? mutex_lock+0x79/0xd0
? mutex_unlock+0x7b/0xd0
? __pfx_mutex_unlock+0x10/0x10
isert_remove_one+0x529/0x710
? xas_load+0x1a/0x250
? __pfx_isert_remove_one+0x10/0x10
? xa_load+0xbf/0x120
? __pfx_xa_load+0x10/0x10
? __pfx_up_read+0x10/0x10
remove_client_context+0xa4/0xf0
disable_device+0x128/0x240
? __pfx_disable_device+0x10/0x10
? __pfx_mutex_lock+0x10/0x10
__ib_unregister_device+0x226/0x3f0
? __pfx_mutex_unlock+0x10/0x10
ib_unregister_device_and_put+0x50/0x70
nldev_dellink+0x28e/0x3d0
? kernel_text_address+0xa7/0x130
? __pfx_nldev_dellink+0x10/0x10
? __pfx_down_read+0x10/0x10
rdma_nl_rcv_msg+0x29c/0x4e0
? __pfx_rdma_nl_rcv_msg+0x10/0x10
rdma_nl_rcv_skb.constprop.0.isra.0+0x21d/0x370
? __pfx_rdma_nl_rcv_skb.constprop.0.isra.0+0x10/0x10
netlink_unicast+0x68f/0x940
? __pfx_selinux_socket_getpeersec_dgram+0x10/0x10
? __pfx_netlink_unicast+0x10/0x10
netlink_sendmsg+0x810/0xf20
? __pfx_netlink_sendmsg+0x10/0x10
? __pfx__raw_spin_lock_irqsave+0x10/0x10
? selinux_socket_sendmsg+0x8c/0x270
? __sys_sendto+0x337/0x390
__sys_sendto+0x337/0x390
? __pfx___sys_sendto+0x10/0x10
? fdget+0x53/0x3b0
__x64_sys_sendto+0xdb/0x1b0
? fpregs_assert_state_consistent+0x56/0xe0
do_syscall_64+0xdd/0x4a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fe0ecec20d7
RSP: 002b:00007fffe9d34978 EFLAGS: 00000202 ORIG_RAX: 000000000000002c
RAX: ffffffffffffffda RBX: 00005621db1ab390 RCX: 00007fe0ecec20d7
RDX: 0000000000000018 RSI: 00005621db1aa2a0 RDI: 0000000000000004
RBP: 00007fffe9d349b0 R08: 00007fe0ecfb9200 R09: 000000000000000c
R10: 0000000000000000 R11: 0000000000000202 R12: 00007fffe9d34ba0
R13: 00007fffe9d34984 R14: 00007fffe9d34bc0 R15: 00007fffe9d34ba0
</TASK>

Fixes: 954f23722b57 ("iscsi,iser-target: Initiate termination only once")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Yehyeong Lee <yhlee@xxxxxxxxxxxxxxxxxx>
---
drivers/infiniband/ulp/isert/ib_isert.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index 4812dabd939453..712d6165150e3c 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -721,7 +721,7 @@ isert_connect_error(struct rdma_cm_id *cma_id)
{
struct isert_conn *isert_conn = cma_id->qp->qp_context;
struct isert_np *isert_np = cma_id->context;
- bool owned = false, bound = false;
+ bool owned = false, bound = false, promoted = false;

mutex_lock(&isert_conn->mutex);
mutex_lock(&isert_np->mutex);
@@ -730,6 +730,7 @@ isert_connect_error(struct rdma_cm_id *cma_id)
isert_conn->state == ISER_CONN_FULL_FEATURE;
} else {
owned = true;
+ promoted = isert_conn->promoted;
list_del_init(&isert_conn->node);
}
mutex_unlock(&isert_np->mutex);
@@ -748,6 +749,8 @@ isert_connect_error(struct rdma_cm_id *cma_id)
}

ib_drain_qp(isert_conn->qp);
+ if (promoted)
+ isert_put_conn(isert_conn);
isert_put_conn(isert_conn);

return -1;
--
2.43.0