[PATCH v8 6/6] IB/isert: only reinstate a connection that reached full feature phase

From: Yehyeong Lee

Date: Tue Nov 03 2026 - 23:07:41 EST


isert_teardown_conn() and isert_connect_error() ask iscsi to reinstate the
connection whenever it is bound, ISER_CONN_BOUND included. A connection
stays BOUND from isert_accept_np() until isert_get_rx_pdu(); during the
final login response the rx thread is already running but still waits for
its login completion. iscsit_cause_connection_reinstatement() sends it
SIGINT, that wait fails, and iscsi_target_rx_thread() returns without the
connection exit path, so isert_remove_one() waits for ever.

Ask for reinstatement only from ISER_CONN_FULL_FEATURE, read under
isert_conn->mutex. There the rx thread is inside isert_get_rx_pdu() and
returns to the exit path, so the signal still helps. In BOUND terminating
is enough: if the login completes, isert_get_rx_pdu() sees
ISER_CONN_TERMINATING and returns; if it fails,
iscsi_target_login_sess_out() calls isert_wait_conn() and
isert_free_conn().

A test-only delay in that gap, with the device deleted inside it,
reproduced this on all three runs of patches 1 to 5: the rx thread was
signalled and the delete did not return within 240 seconds. Three runs
with this patch signalled nothing and the delete returned in 8 seconds.

INFO: task rdma:194 blocked for more than 10 seconds.
Not tainted 7.4.0-rc1-V7L5-00006-g4f59be58f97a #141
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:rdma state:D stack:26328 pid:194 tgid:194 ppid:1 task_flags:0x400100 flags:0x00080800
Call Trace:
<TASK>
__schedule+0x180f/0x4bb0
? __pfx___schedule+0x10/0x10
? __pfx_complete_signal+0x10/0x10
? irq_work_queue+0x1c/0xb0
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+0x554/0x740
? 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:0x7f1de13200d7
RSP: 002b:00007fff7f1dd9d8 EFLAGS: 00000202 ORIG_RAX: 000000000000002c
RAX: ffffffffffffffda RBX: 0000563429332390 RCX: 00007f1de13200d7
RDX: 0000000000000018 RSI: 00005634293312a0 RDI: 0000000000000004
RBP: 00007fff7f1dda10 R08: 00007f1de1417200 R09: 000000000000000c
R10: 0000000000000000 R11: 0000000000000202 R12: 00007fff7f1ddc00
R13: 00007fff7f1dd9e4 R14: 00007fff7f1ddc20 R15: 00007fff7f1ddc00
</TASK>

Fixes: 6d1fba0c2cc7 ("iser-target: Rework connection termination")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Yehyeong Lee <yhlee@xxxxxxxxxxxxxxxxxx>
---
drivers/infiniband/ulp/isert/ib_isert.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index a9bd2cc786cebb..8989485001fc94 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -681,14 +681,14 @@ static void
isert_teardown_conn(struct isert_conn *isert_conn)
{
struct isert_np *isert_np = isert_conn->np;
- bool owned = false, bound = false;
+ bool owned = false, bound = false, full_feature = false;
bool promoted = false, terminated = false;

mutex_lock(&isert_conn->mutex);
mutex_lock(&isert_np->mutex);
if (list_empty(&isert_conn->node)) {
- bound = isert_conn->state == ISER_CONN_BOUND ||
- isert_conn->state == ISER_CONN_FULL_FEATURE;
+ full_feature = isert_conn->state == ISER_CONN_FULL_FEATURE;
+ bound = full_feature || isert_conn->state == ISER_CONN_BOUND;
} else {
owned = true;
promoted = isert_conn->promoted;
@@ -700,7 +700,9 @@ isert_teardown_conn(struct isert_conn *isert_conn)
terminated = isert_conn_terminate(isert_conn);
} else if (bound) {
isert_conn_terminate(isert_conn);
- iscsit_cause_connection_reinstatement(isert_conn->conn, 0);
+ if (full_feature)
+ iscsit_cause_connection_reinstatement(isert_conn->conn,
+ 0);
}
mutex_unlock(&isert_conn->mutex);

@@ -731,12 +733,13 @@ 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, promoted = false;
+ bool full_feature = false;

mutex_lock(&isert_conn->mutex);
mutex_lock(&isert_np->mutex);
if (list_empty(&isert_conn->node)) {
- bound = isert_conn->state == ISER_CONN_BOUND ||
- isert_conn->state == ISER_CONN_FULL_FEATURE;
+ full_feature = isert_conn->state == ISER_CONN_FULL_FEATURE;
+ bound = full_feature || isert_conn->state == ISER_CONN_BOUND;
} else {
owned = true;
promoted = isert_conn->promoted;
@@ -746,7 +749,9 @@ isert_connect_error(struct rdma_cm_id *cma_id)

if (bound) {
isert_conn_terminate(isert_conn);
- iscsit_cause_connection_reinstatement(isert_conn->conn, 0);
+ if (full_feature)
+ iscsit_cause_connection_reinstatement(isert_conn->conn,
+ 0);
}
mutex_unlock(&isert_conn->mutex);

--
2.43.0