From: Rishikesh Jethwani <rjethwani@purestorage.com>
To: "David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@kernel.org>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>
Cc: Simon Horman <horms@kernel.org>, Breno Leitao <leitao@debian.org>,
Junseo Lim <zirajs7@gmail.com>,
Runyu Xiao <runyu.xiao@seu.edu.cn>,
Jiayuan Chen <jiayuan.chen@shopee.com>,
Christian Brauner <brauner@kernel.org>,
Sagi Grimberg <sagi@grimberg.me>, Hannes Reinecke <hare@suse.de>,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
Rishikesh Jethwani <rjethwani@purestorage.com>
Subject: [PATCH net] kcm: defer receive parsing when the lower socket's read_sock may sleep
Date: Mon, 12 Oct 2026 21:39:20 -0600 [thread overview]
Message-ID: <20261013033920.2069285-1-rjethwani@purestorage.com> (raw)
psock_data_ready() is the lower socket's data_ready callback and can
run in softirq context, under read_lock_bh(&sk->sk_callback_lock). It calls
strp_data_ready(), which, when the socket is not owned by a user,
invokes sock->ops->read_sock() inline to pull records out of the
receive queue. For a plain TCP socket that is tcp_read_sock(), which
does not block.
A ULP may install a different read_sock. kTLS installs
tls_sw_read_sock(), which can sleep: it waits for an asynchronous
AEAD to complete via crypto_wait_req(), flushes the socket backlog
through __sk_flush_backlog(), allocates with sk->sk_allocation, and,
on reader contention in tls_rx_reader_acquire(), enters
sk_wait_event()'s socket release/reacquire path despite the zero
timeout. It passes nonblock, so it does not wait for data, but these
paths can require sleepable context, which softirq and a BH read lock
do not provide. Attaching a kTLS socket to a KCM multiplexor can
therefore sleep in atomic context.
With CONFIG_DEBUG_ATOMIC_SLEEP, a loopback TCP connection using software
kTLS RX, with the receiving socket attached to a KCM mux, reports:
BUG: sleeping function called from invalid context at include/linux/sched/mm.h:321
in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 189, name: ksoftirqd/34
Call Trace:
__might_resched
kmem_cache_alloc_node_noprof
__alloc_skb
alloc_skb_with_frags
tls_rx_one_record
tls_sw_read_sock
strp_read_sock
strp_data_ready
psock_data_ready [kcm]
Keep the inline fast path for tcp_read_sock() and hand any other
read_sock to the parser work via strp_check_rcv(). The work runs
do_strp_work() under lock_sock(), where a sleeping read_sock is fine.
sk->sk_socket can be NULL here while the lower socket is being
released; strp_read_sock() already treats that as a reason not to
read, so take the deferred path in that case as well.
Tested with the reproducer above on a 6.18 kernel: without this change
the splat is reported on every run; with it, nothing is reported.
Fixes: 662fbcec32f4 ("net/tls: implement ->read_sock()")
Assisted-by: LLM
Signed-off-by: Rishikesh Jethwani <rjethwani@purestorage.com>
---
net/kcm/kcmsock.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c
index 71af69d442f2..381a8f0b792e 100644
--- a/net/kcm/kcmsock.c
+++ b/net/kcm/kcmsock.c
@@ -30,6 +30,7 @@
#include <net/kcm.h>
#include <net/netns/generic.h>
#include <net/sock.h>
+#include <net/tcp.h>
#include <uapi/linux/kcm.h>
#include <trace/events/sock.h>
@@ -358,8 +359,19 @@ static void psock_data_ready(struct sock *sk)
read_lock_bh(&sk->sk_callback_lock);
psock = (struct kcm_psock *)sk->sk_user_data;
- if (likely(psock))
- strp_data_ready(&psock->strp);
+ if (likely(psock)) {
+ struct socket *sock = sk->sk_socket;
+
+ /* strp_data_ready() calls sock->ops->read_sock() inline from
+ * this softirq callback. A ULP's read_sock, such as kTLS's
+ * tls_sw_read_sock(), may sleep, so hand anything other than
+ * TCP's own to the parser work, which runs under lock_sock().
+ */
+ if (likely(sock && sock->ops->read_sock == tcp_read_sock))
+ strp_data_ready(&psock->strp);
+ else
+ strp_check_rcv(&psock->strp);
+ }
read_unlock_bh(&sk->sk_callback_lock);
}
base-commit: 8e2fbe0e75d38690d551456658194c632933cb57
--
2.50.1
next reply other threads:[~2026-10-13 3:40 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-13 3:39 Rishikesh Jethwani [this message]
2026-10-14 4:03 ` [PATCH net] kcm: defer receive parsing when the lower socket's read_sock may sleep netdev-bot+sashiko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261013033920.2069285-1-rjethwani@purestorage.com \
--to=rjethwani@purestorage.com \
--cc=brauner@kernel.org \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=hare@suse.de \
--cc=horms@kernel.org \
--cc=jiayuan.chen@shopee.com \
--cc=kuba@kernel.org \
--cc=leitao@debian.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=runyu.xiao@seu.edu.cn \
--cc=sagi@grimberg.me \
--cc=zirajs7@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox