[PATCH] scsi: iscsi_tcp: use WRITE_ONCE() for shared socket callbacks
From: Runyu Xiao
Date: Thu Jun 11 2026 - 01:42:05 EST
iscsi_sw_tcp_conn_set_callbacks() and
iscsi_sw_tcp_conn_restore_callbacks() replace and restore
sk->sk_data_ready and sk->sk_write_space on a live TCP socket with
plain stores. These callback pointers are shared with generic socket
and TCP paths that may read or invoke them concurrently, so the write
side needs the same WRITE_ONCE() contract that commit 2ef2b20cf4e0
("net: annotate data-races around sk->sk_{data_ready,write_space}")
applied elsewhere.
If another CPU has taken an earlier callback snapshot, the plain
replace and restore leave the same visibility hole as the validated
4022 family. A stale snapshot can then still call
iscsi_sw_tcp_data_ready() or iscsi_sw_tcp_write_space() after the live
socket has already been restored to sock_def_readable() or
sk_stream_write_space(), with sk_user_data cleared.
Use WRITE_ONCE() for the shared sk_data_ready and sk_write_space
stores in both the callback-install and callback-restore paths. This
matches the required socket callback visibility contract while keeping
the existing locking and sk_state_change handling unchanged.
Fixes: 38e1a8f5479d ("[SCSI] iscsi_tcp: hook iscsi_tcp into new libiscsi_tcp module")
Signed-off-by: Runyu Xiao <runyu.xiao@xxxxxxxxxx>
---
drivers/scsi/iscsi_tcp.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 7b4fe0e6afb2..5dabda97043d 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -254,9 +254,9 @@ static void iscsi_sw_tcp_conn_set_callbacks(struct iscsi_conn *conn)
tcp_sw_conn->old_data_ready = sk->sk_data_ready;
tcp_sw_conn->old_state_change = sk->sk_state_change;
tcp_sw_conn->old_write_space = sk->sk_write_space;
- sk->sk_data_ready = iscsi_sw_tcp_data_ready;
+ WRITE_ONCE(sk->sk_data_ready, iscsi_sw_tcp_data_ready);
sk->sk_state_change = iscsi_sw_tcp_state_change;
- sk->sk_write_space = iscsi_sw_tcp_write_space;
+ WRITE_ONCE(sk->sk_write_space, iscsi_sw_tcp_write_space);
write_unlock_bh(&sk->sk_callback_lock);
}
@@ -270,9 +270,9 @@ iscsi_sw_tcp_conn_restore_callbacks(struct iscsi_conn *conn)
/* restore socket callbacks, see also: iscsi_conn_set_callbacks() */
write_lock_bh(&sk->sk_callback_lock);
sk->sk_user_data = NULL;
- sk->sk_data_ready = tcp_sw_conn->old_data_ready;
+ WRITE_ONCE(sk->sk_data_ready, tcp_sw_conn->old_data_ready);
sk->sk_state_change = tcp_sw_conn->old_state_change;
- sk->sk_write_space = tcp_sw_conn->old_write_space;
+ WRITE_ONCE(sk->sk_write_space, tcp_sw_conn->old_write_space);
sk->sk_no_check_tx = 0;
write_unlock_bh(&sk->sk_callback_lock);
}
--
2.34.1