* [PATCH 7.2 00/10] 7.2.15-rc1 review
@ 2026-10-30 12:15 Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 01/10] ksmbd: wait for negotiation before receiving another PDU Greg Kroah-Hartman
` (13 more replies)
0 siblings, 14 replies; 18+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-30 12:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, linux-kernel, torvalds, akpm, linux,
shuah, patches, lkft-triage, pavel, jonathanh, f.fainelli,
sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr
This is the start of the stable review cycle for the 7.2.15 release.
There are 10 patches in this series, all will be posted as a response
to this one. If anyone has any issues with these being applied, please
let me know.
Responses should be made by Sun, 01 Nov 2026 12:12:50 +0000.
Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v7.x/stable-review/patch-7.2.15-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-7.2.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Linux 7.2.15-rc1
Christian Brauner <brauner@kernel.org>
fork: don't create io threads once PF_POSTCOREDUMP is set
Christian Brauner <brauner@kernel.org>
fork: move the coredump and exec checks into create_io_thread()
Christian Brauner <brauner@kernel.org>
exec: cancel io_uring requests before de_thread()
André Draszik <andre.draszik@linaro.org>
kbuild: link-vmlinux.sh: improve detection of third pass requirement
Ridham Khurana <khurana.ridham222@gmail.com>
platform: cznic: turris-omnia-mcu: Add missing MODULE_DEVICE_TABLE()
Daniel Schaefer <dhs@frame.work>
iio: hid-sensor: als: scale each channel individually
Stefan Metzmacher <metze@samba.org>
smb: smbdirect: don't hand out already failed sockets in smbdirect_socket_accept()
Stefan Metzmacher <metze@samba.org>
smb: smbdirect: release failed pending sockets of a listener
Stefan Metzmacher <metze@samba.org>
smb: smbdirect: don't wait for RDMA_CM_EVENT_DISCONNECTED in smbdirect_socket_destroy_sync()
Namjae Jeon <linkinjeon@kernel.org>
ksmbd: wait for negotiation before receiving another PDU
-------------
Diffstat:
Makefile | 4 +-
drivers/iio/light/hid-sensor-als.c | 22 +--
drivers/platform/cznic/turris-omnia-mcu-base.c | 1 +
fs/exec.c | 11 +-
fs/smb/server/server.c | 5 +
fs/smb/smbdirect/accept.c | 227 ++++++++++++++++++-------
fs/smb/smbdirect/connection.c | 12 +-
fs/smb/smbdirect/internal.h | 2 +
fs/smb/smbdirect/listen.c | 137 +++++++++++++--
fs/smb/smbdirect/socket.c | 113 ++++++++++--
fs/smb/smbdirect/socket.h | 42 +++++
kernel/fork.c | 4 +
scripts/link-vmlinux.sh | 20 ++-
13 files changed, 489 insertions(+), 111 deletions(-)
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 7.2 01/10] ksmbd: wait for negotiation before receiving another PDU
2026-10-30 12:15 [PATCH 7.2 00/10] 7.2.15-rc1 review Greg Kroah-Hartman
@ 2026-10-30 12:15 ` Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 02/10] smb: smbdirect: dont wait for RDMA_CM_EVENT_DISCONNECTED in smbdirect_socket_destroy_sync() Greg Kroah-Hartman
` (12 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-30 12:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, ihopenre-eng, Namjae Jeon,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit 68f410faedaf6ee74d81e574733c50ebcc1bd8ed ]
The receive thread queues a request and can read the next PDU before
the negotiation worker finishes. While need_neg is set, the next PDU
can cause ksmbd_init_smb_server() to replace conn->ops. A pipelined
SMB2 request can therefore make the worker handle an earlier, shorter
SMB1 request with SMB2 operations and read beyond its buffer.
An SMB1 multi-protocol negotiate may be followed by an SMB2 NEGOTIATE
that changes conn->ops again. Wait for work queued while the connection
is new or needs negotiation to complete before reading another PDU.
This keeps the operations stable for both stages of negotiation without
changing when need_neg is cleared.
Fixes: dc8289f91238 ("ksmbd: fix slab-out-of-bounds in init_smb2_rsp_hdr")
Reported-by: ihopenre-eng <ihopenre@gmail.com>
Reviewed-by: ihopenre-eng <ihopenre@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/server.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/fs/smb/server/server.c b/fs/smb/server/server.c
index e113b23d96f94..e36e82b94a047 100644
--- a/fs/smb/server/server.c
+++ b/fs/smb/server/server.c
@@ -371,6 +371,7 @@ static void handle_ksmbd_work(struct work_struct *wk)
static int queue_ksmbd_work(struct ksmbd_conn *conn)
{
struct ksmbd_work *work;
+ bool wait_for_neg = ksmbd_conn_new(conn) || ksmbd_conn_need_negotiate(conn);
int err;
err = ksmbd_init_smb_server(conn);
@@ -393,6 +394,10 @@ static int queue_ksmbd_work(struct ksmbd_conn *conn)
conn->last_active = jiffies;
INIT_WORK(&work->work, handle_ksmbd_work);
ksmbd_queue_work(work);
+ /* Negotiation can change conn->ops, finish it before reading another PDU. */
+ if (wait_for_neg)
+ wait_event(conn->req_running_q,
+ atomic_read(&conn->req_running) == 0);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 7.2 02/10] smb: smbdirect: dont wait for RDMA_CM_EVENT_DISCONNECTED in smbdirect_socket_destroy_sync()
2026-10-30 12:15 [PATCH 7.2 00/10] 7.2.15-rc1 review Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 01/10] ksmbd: wait for negotiation before receiving another PDU Greg Kroah-Hartman
@ 2026-10-30 12:15 ` Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 03/10] smb: smbdirect: release failed pending sockets of a listener Greg Kroah-Hartman
` (11 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-30 12:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Paulo Alcantara,
Tom Talpey, linux-cifs, samba-technical, linux-rdma,
Stefan Metzmacher, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Metzmacher <metze@samba.org>
[ Upstream commit 4ca76b89917ad5b317e07ae4f0edc16f7c2a1248 ]
smbdirect_socket_destroy_sync() waited for RDMA_CM_EVENT_DISCONNECTED
after smbdirect_socket_cleanup_work() called rdma_disconnect(). That
can take very long, e.g. if the peer just disappeared, until the
rdma cm gives up, or forever if the event already happened, but the
status was overwritten afterwards.
This is not needed: smbdirect_socket_destroy() drains the qp under
rdma_lock_handler(), destroys it and calls rdma_destroy_id(), which
only waits for a currently running event handler and makes sure no
further events are delivered. The rest of the disconnect protocol
(DREQ/DREP and timewait for IB, abrupt close for iWarp) is handled
by the rdma core asynchronously. drivers/nvme/host/rdma.c also just
calls rdma_disconnect() and ib_drain_qp() before rdma_destroy_id().
So smbdirect_socket_destroy() now also accepts
SMBDIRECT_SOCKET_DISCONNECTING and changes the status to
SMBDIRECT_SOCKET_DISCONNECTED itself under rdma_lock_handler().
We could still get RDMA_CM_EVENT_DISCONNECTED in the small
windows between rdma_unlock_handler() and rdma_destroy_id(),
but in that case smbdirect_connection_rdma_event_handler()
is basically a no-op.
Fixes: 422a2436697d ("smb: smbdirect: introduce smbdirect_socket_destroy[_sync]()")
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: Paulo Alcantara <pc@manguebit.org>
Cc: Tom Talpey <tom@talpey.com>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Cc: linux-rdma@vger.kernel.org
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/smbdirect/connection.c | 12 ++++----
fs/smb/smbdirect/socket.c | 56 ++++++++++++++++++++++++++++-------
2 files changed, 52 insertions(+), 16 deletions(-)
diff --git a/fs/smb/smbdirect/connection.c b/fs/smb/smbdirect/connection.c
index fe99537207176..32327f96a03ab 100644
--- a/fs/smb/smbdirect/connection.c
+++ b/fs/smb/smbdirect/connection.c
@@ -83,9 +83,9 @@ static int smbdirect_connection_rdma_event_handler(struct rdma_cm_id *id,
* smbdirect_socket_schedule_cleanup[_status]() =>
* smbdirect_socket_cleanup_work().
*
- * As otherwise we'd set SMBDIRECT_SOCKET_DISCONNECTING,
- * but never ever get RDMA_CM_EVENT_DISCONNECTED and
- * never reach SMBDIRECT_SOCKET_DISCONNECTED.
+ * As otherwise we'd set SMBDIRECT_SOCKET_DISCONNECTING
+ * and call rdma_disconnect(), but never ever get
+ * RDMA_CM_EVENT_DISCONNECTED.
*/
if (event->event == RDMA_CM_EVENT_DEVICE_REMOVAL)
smbdirect_socket_schedule_cleanup_status(sc,
@@ -113,9 +113,9 @@ static int smbdirect_connection_rdma_event_handler(struct rdma_cm_id *id,
* smbdirect_socket_schedule_cleanup_status() =>
* smbdirect_socket_cleanup_work().
*
- * As otherwise we'd set SMBDIRECT_SOCKET_DISCONNECTING,
- * but never ever get RDMA_CM_EVENT_DISCONNECTED and
- * never reach SMBDIRECT_SOCKET_DISCONNECTED.
+ * As otherwise we'd set SMBDIRECT_SOCKET_DISCONNECTING
+ * and call rdma_disconnect(), but never ever get
+ * RDMA_CM_EVENT_DISCONNECTED.
*
* This is also a normal disconnect so
* SMBDIRECT_LOG_INFO should be good enough
diff --git a/fs/smb/smbdirect/socket.c b/fs/smb/smbdirect/socket.c
index bb02df6158b97..c36cb7cc0088b 100644
--- a/fs/smb/smbdirect/socket.c
+++ b/fs/smb/smbdirect/socket.c
@@ -511,7 +511,13 @@ static void smbdirect_socket_destroy(struct smbdirect_socket *sc)
if (sc->status == SMBDIRECT_SOCKET_DESTROYED)
return;
- WARN_ONCE(sc->status != SMBDIRECT_SOCKET_DISCONNECTED,
+ /*
+ * smbdirect_socket_destroy_sync() doesn't wait
+ * for RDMA_CM_EVENT_DISCONNECTED, so we may still
+ * be in SMBDIRECT_SOCKET_DISCONNECTING
+ * (or already reached SMBDIRECT_SOCKET_DISCONNECTED)
+ */
+ WARN_ONCE(sc->status < SMBDIRECT_SOCKET_DISCONNECTING,
"status=%s first_error=%1pe",
smbdirect_socket_status_string(sc->status),
SMBDIRECT_DEBUG_ERR_PTR(sc->first_error));
@@ -542,6 +548,32 @@ static void smbdirect_socket_destroy(struct smbdirect_socket *sc)
if (sc->rdma.cm_id)
rdma_lock_handler(sc->rdma.cm_id);
+ /*
+ * We hold the handler lock, so the rdma event
+ * handlers can't change the status anymore.
+ *
+ * If RDMA_CM_EVENT_DISCONNECTED didn't arrive yet,
+ * we just stop waiting for it here.
+ *
+ * We already disabled disconnect_work above
+ * and before we call rdma_unlock_handler below
+ * we call smbdirect_connection_destroy_qp which
+ * sets sc->ib.qp = NULL.
+ *
+ * Between rdma_unlock_handler() and
+ * rdma_destroy_id() below there's a small
+ * windows where RDMA_CM_EVENT_DISCONNECTED
+ * could still arrive.
+ *
+ * But smbdirect_connection_rdma_event_handler
+ * will be a noop when calling smbdirect_socket_schedule_cleanup*
+ * ib_drain_qp() also won't be called.
+ */
+ if (sc->status < SMBDIRECT_SOCKET_DISCONNECTED) {
+ sc->status = SMBDIRECT_SOCKET_DISCONNECTED;
+ smbdirect_socket_wake_up_all(sc);
+ }
+
if (sc->ib.qp) {
smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO,
"drain qp\n");
@@ -679,17 +711,21 @@ void smbdirect_socket_destroy_sync(struct smbdirect_socket *sc)
"destroying rdma session\n");
if (sc->status < SMBDIRECT_SOCKET_DISCONNECTING)
smbdirect_socket_cleanup_work(&sc->disconnect_work);
- if (sc->status < SMBDIRECT_SOCKET_DISCONNECTED) {
- smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO,
- "wait for transport being disconnected\n");
- wait_event(sc->status_wait, sc->status == SMBDIRECT_SOCKET_DISCONNECTED);
- smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO,
- "waited for transport being disconnected\n");
- }
/*
- * Once we reached SMBDIRECT_SOCKET_DISCONNECTED,
- * we should call smbdirect_socket_destroy()
+ * We don't wait for RDMA_CM_EVENT_DISCONNECTED,
+ * rdma_disconnect() was already called by
+ * smbdirect_socket_cleanup_work() if needed
+ * and smbdirect_socket_destroy() drains the qp,
+ * destroys it and calls rdma_destroy_id(), which
+ * only waits for a currently running event handler
+ * and makes sure no further events are delivered.
+ * The rest of the disconnect protocol is handled
+ * by the rdma core asynchronously.
+ *
+ * Waiting for RDMA_CM_EVENT_DISCONNECTED could
+ * take very long or forever, e.g. if the peer
+ * just disappeared.
*/
smbdirect_socket_destroy(sc);
smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO,
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 7.2 03/10] smb: smbdirect: release failed pending sockets of a listener
2026-10-30 12:15 [PATCH 7.2 00/10] 7.2.15-rc1 review Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 01/10] ksmbd: wait for negotiation before receiving another PDU Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 02/10] smb: smbdirect: dont wait for RDMA_CM_EVENT_DISCONNECTED in smbdirect_socket_destroy_sync() Greg Kroah-Hartman
@ 2026-10-30 12:15 ` Greg Kroah-Hartman
2026-10-30 12:42 ` 이성현
2026-10-30 12:15 ` [PATCH 7.2 04/10] smb: smbdirect: dont hand out already failed sockets in smbdirect_socket_accept() Greg Kroah-Hartman
` (10 subsequent siblings)
13 siblings, 1 reply; 18+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-30 12:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lee Seong Hyeon, Sashiko,
Namjae Jeon, Paulo Alcantara, Tom Talpey, linux-cifs,
samba-technical, Stefan Metzmacher, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Metzmacher <metze@samba.org>
[ Upstream commit 328c7e307e8411899e2f90beae83da9e4c45d700 ]
A child of a listener only left the listen.pending or listen.ready
list via smbdirect_socket_accept() or when the listener was
destroyed. So every connection that failed before it was accepted
(negotiate timeout, peer disconnect, invalid negotiate request, ...)
stayed on the list and counted against the backlog until the listener
was destroyed. After about backlog (10 for ksmbd) such connections
smbdirect_listen_connect_request() rejected every new connection with
-EBUSY, so an unauthenticated peer was able to permanently stop
ksmbd from accepting SMB-Direct connections.
Now a failed child moves itself to a new listen.orphaned list at the
end of smbdirect_socket_cleanup_work(), after the disconnect was
started, and queues listen.purge_orphaned_work, which releases it
with smbdirect_socket_release(), without holding the listener's
rdma_lock_handler() lock, in the same way smbdirect_socket_destroy()
does for the remaining children. Orphaned sockets still count against
the backlog until they are released.
sc->accept.listener is now only changed under listener->listen.lock
and whoever clears it is responsible for releasing the socket:
smbdirect_socket_accept(), purge_orphaned_work or the destroy of the
listener.
In order to make that work:
- a struct smbdirect_socket that is a listener is now freed via
kfree_rcu(), so that a child can dereference sc->accept.listener
under rcu_read_lock(), even if the listener is released concurrently.
- smbdirect_listen_connect_request() adds nsc to the listen.pending
list and sets nsc->accept.listener before it calls
smbdirect_accept_connect_request(), and always returns 0 so the
rdma_cm core keeps the connection id and nsc owns it. On a non-zero
return it schedules nsc's teardown with
smbdirect_socket_schedule_cleanup(), which orphans it off the
listener so that purge_orphaned_work releases it; nsc destroys its
own connection id with rdma_destroy_id() in that teardown. The
teardown has to be deferred because the rdma_cm core holds nsc's
id_priv->handler_mutex across the handler, so nsc->rdma.cm_id must
not be destroyed synchronously from here. That same handler_mutex
(and the listener's) also guarantees nsc can't go away under us,
so setting the listener before the call is safe and lets a failure
orphan nsc.
- smbdirect_accept_negotiate_recv_work() no longer moves a socket to
the ready list if it already failed or no longer belongs to the
listener. Every accepting socket has a listener, so if
sc->accept.listener is already cleared, it no longer sends a
negotiate response, as the socket is about to be released.
- smbdirect_socket_destroy() of the listener disables
purge_orphaned_work and also releases the orphaned sockets.
Fixes: dc691b91ad16 ("smb: smbdirect: introduce smbdirect_socket_{listen,accept}()")
Reported-by: Lee Seong Hyeon <ihopenre@gmail.com>
Closes: https://lore.kernel.org/linux-cifs/CANTrAmxL5sWU8Sn29JAGZvSq5PBB2OA+VKA0MHsZJMesagtfzA@mail.gmail.com/
Reported-by: Sashiko <sashiko-bot+sashiko@kernel.org>
Closes: https://sashiko.dev/#/patchset/cover.1791224972.git.metze%40samba.org
Closes: https://sashiko.dev/#/patchset/cover.1791229120.git.metze%40samba.org
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: Paulo Alcantara <pc@manguebit.org>
Cc: Tom Talpey <tom@talpey.com>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/smbdirect/accept.c | 141 +++++++++++++++++++++++-------------
fs/smb/smbdirect/internal.h | 2 +
fs/smb/smbdirect/listen.c | 137 ++++++++++++++++++++++++++++++++---
fs/smb/smbdirect/socket.c | 57 ++++++++++++++-
fs/smb/smbdirect/socket.h | 42 +++++++++++
5 files changed, 314 insertions(+), 65 deletions(-)
diff --git a/fs/smb/smbdirect/accept.c b/fs/smb/smbdirect/accept.c
index 039c9bfbd8acd..66db978bd8f73 100644
--- a/fs/smb/smbdirect/accept.c
+++ b/fs/smb/smbdirect/accept.c
@@ -19,15 +19,33 @@ int smbdirect_accept_connect_request(struct smbdirect_socket *sc,
const struct rdma_conn_param *param)
{
struct smbdirect_socket_parameters *sp = &sc->parameters;
- struct smbdirect_recv_io *recv_io;
+ struct smbdirect_recv_io *recv_io = NULL;
u8 peer_initiator_depth;
u8 peer_responder_resources;
struct rdma_conn_param conn_param;
__be32 ird_ord_hdr[2];
int ret;
- if (SMBDIRECT_CHECK_STATUS_WARN(sc, SMBDIRECT_SOCKET_CREATED))
- return -EINVAL;
+ /*
+ * Install the real event handler (and the event we expect next)
+ * before anything that can fail. On an early error the caller
+ * (smbdirect_listen_connect_request()) only schedules our deferred
+ * cleanup and returns 0 to the rdma_cm core, which keeps the cm_id, so
+ * the cm_id must already carry smbdirect_accept_rdma_event_handler():
+ * it turns any unexpected event (e.g. RDMA_CM_EVENT_DEVICE_REMOVAL)
+ * into a clean smbdirect_socket_schedule_cleanup(). Otherwise the
+ * placeholder smbdirect_socket_rdma_event_handler() installed by
+ * smbdirect_socket_init_accepting() stays in place and returns -ESTALE,
+ * which makes the rdma_cm core destroy the cm_id behind the back of our
+ * pending teardown.
+ */
+ sc->rdma.expected_event = RDMA_CM_EVENT_ESTABLISHED;
+ sc->rdma.cm_id->event_handler = smbdirect_accept_rdma_event_handler;
+
+ if (SMBDIRECT_CHECK_STATUS_WARN(sc, SMBDIRECT_SOCKET_CREATED)) {
+ ret = -EINVAL;
+ goto cleanup;
+ }
/*
* First set what the we as server are able to support
@@ -47,7 +65,7 @@ int smbdirect_accept_connect_request(struct smbdirect_socket *sc,
smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR,
"smbdirect_accept_init_params() failed %1pe\n",
SMBDIRECT_DEBUG_ERR_PTR(ret));
- goto init_params_failed;
+ goto cleanup;
}
ret = smbdirect_connection_create_qp(sc);
@@ -55,7 +73,7 @@ int smbdirect_accept_connect_request(struct smbdirect_socket *sc,
smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR,
"smbdirect_connection_create_qp() failed %1pe\n",
SMBDIRECT_DEBUG_ERR_PTR(ret));
- goto create_qp_failed;
+ goto cleanup;
}
ret = smbdirect_connection_create_mem_pools(sc);
@@ -63,7 +81,7 @@ int smbdirect_accept_connect_request(struct smbdirect_socket *sc,
smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR,
"smbdirect_connection_create_mem_pools() failed %1pe\n",
SMBDIRECT_DEBUG_ERR_PTR(ret));
- goto create_mem_failed;
+ goto cleanup;
}
recv_io = smbdirect_connection_get_recv_io(sc);
@@ -72,7 +90,7 @@ int smbdirect_accept_connect_request(struct smbdirect_socket *sc,
smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR,
"smbdirect_connection_get_recv_io() failed %1pe\n",
SMBDIRECT_DEBUG_ERR_PTR(ret));
- goto get_recv_io_failed;
+ goto cleanup;
}
recv_io->cqe.done = smbdirect_accept_negotiate_recv_done;
@@ -86,7 +104,7 @@ int smbdirect_accept_connect_request(struct smbdirect_socket *sc,
smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR,
"smbdirect_connection_post_recv_io() failed %1pe\n",
SMBDIRECT_DEBUG_ERR_PTR(ret));
- goto post_recv_io_failed;
+ goto cleanup;
}
/*
* From here recv_io is known to the RDMA QP and needs ib_drain_qp and
@@ -122,14 +140,12 @@ int smbdirect_accept_connect_request(struct smbdirect_socket *sc,
/* explicitly set above */
WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RDMA_CONNECT_NEEDED);
sc->status = SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING;
- sc->rdma.expected_event = RDMA_CM_EVENT_ESTABLISHED;
- sc->rdma.cm_id->event_handler = smbdirect_accept_rdma_event_handler;
ret = rdma_accept(sc->rdma.cm_id, &conn_param);
if (ret) {
smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR,
"rdma_accept() failed %1pe\n",
SMBDIRECT_DEBUG_ERR_PTR(ret));
- goto rdma_accept_failed;
+ goto cleanup;
}
/*
@@ -143,31 +159,25 @@ int smbdirect_accept_connect_request(struct smbdirect_socket *sc,
return 0;
-rdma_accept_failed:
+cleanup:
/*
- * The recv_io posted above is now owned by the QP (recv_io was set to
- * NULL after a successful post). smbdirect_connection_destroy_qp()
- * calls ib_drain_qp(), whose completion
- * (smbdirect_accept_negotiate_recv_done) returns the recv_io to the
- * free list via smbdirect_connection_put_recv_io(). It therefore MUST
- * run BEFORE smbdirect_connection_destroy_mem_pools(): otherwise the
- * posted recv_io is still outstanding when kmem_cache_destroy() runs
- * ("Slab cache still has objects") and is later freed into an
- * already-destroyed mempool (mempool_free_bulk NULL-ptr-deref).
+ * No RDMA state is torn down here, and in particular sc is not
+ * released: the caller (smbdirect_listen_connect_request()) owns that
+ * decision and schedules sc's teardown via
+ * smbdirect_socket_schedule_cleanup() on a non-zero return. All of the
+ * RDMA state - the QP, the memory pools and the cm_id itself - is then
+ * torn down asynchronously by smbdirect_socket_cleanup_work() ->
+ * smbdirect_socket_release() -> smbdirect_socket_destroy(), which
+ * drains the QP (returning any posted recv_io to the pool) before
+ * destroying the memory pools and destroys the cm_id with
+ * rdma_destroy_id(), all in the correct order.
+ *
+ * The only resource not reachable by that teardown is a recv_io that
+ * was taken from the pool but not yet posted to the QP (recv_io is set
+ * to NULL after a successful post), so hand it back here.
*/
- smbdirect_connection_destroy_qp(sc);
- smbdirect_connection_destroy_mem_pools(sc);
- return ret;
-post_recv_io_failed:
- /* post failed: recv_io was not accepted by the QP, still in hand */
if (recv_io)
smbdirect_connection_put_recv_io(recv_io);
-get_recv_io_failed:
- smbdirect_connection_destroy_mem_pools(sc);
-create_mem_failed:
- smbdirect_connection_destroy_qp(sc);
-create_qp_failed:
-init_params_failed:
return ret;
}
@@ -301,6 +311,7 @@ static void smbdirect_accept_negotiate_recv_work(struct work_struct *work)
struct smbdirect_socket *sc =
container_of(work, struct smbdirect_socket, connect.work);
struct smbdirect_socket_parameters *sp = &sc->parameters;
+ struct smbdirect_socket *lsc;
struct smbdirect_recv_io *recv_io;
struct smbdirect_negotiate_req *nreq;
unsigned long flags;
@@ -463,29 +474,55 @@ static void smbdirect_accept_negotiate_recv_work(struct work_struct *work)
*/
sp->max_fragmented_send_size = max_fragmented_size;
- if (sc->accept.listener) {
- struct smbdirect_socket *lsc = sc->accept.listener;
- unsigned long flags;
+ /*
+ * Every accepting socket was created by
+ * smbdirect_listen_connect_request() and has a
+ * listener. If it's already cleared, the listener
+ * (or its purge_orphaned_work) is responsible for
+ * releasing us, so we must not send a negotiate
+ * response.
+ *
+ * The memory of the listener is freed via kfree_rcu(),
+ * see smbdirect_listen_orphan_socket().
+ */
+ rcu_read_lock();
+ lsc = READ_ONCE(sc->accept.listener);
+ if (!lsc) {
+ rcu_read_unlock();
+ return;
+ }
- spin_lock_irqsave(&lsc->listen.lock, flags);
- list_del(&sc->accept.list);
- list_add_tail(&sc->accept.list, &lsc->listen.ready);
+ spin_lock_irqsave(&lsc->listen.lock, flags);
+ /*
+ * The listener (or its purge_orphaned_work)
+ * may have cleared sc->accept.listener in the
+ * meantime and is responsible for releasing us.
+ *
+ * If we already failed, we're either
+ * already on the orphaned list or
+ * smbdirect_socket_cleanup_work() will
+ * move us there.
+ *
+ * In both cases we must not move us
+ * to the ready list.
+ */
+ if (sc->accept.listener == lsc && !READ_ONCE(sc->first_error)) {
+ list_move_tail(&sc->accept.list, &lsc->listen.ready);
wake_up(&lsc->listen.wait_queue);
- spin_unlock_irqrestore(&lsc->listen.lock, flags);
-
- /*
- * smbdirect_socket_accept() will call
- * smbdirect_accept_negotiate_finish(nsc, 0);
- *
- * So that we don't send the negotiation
- * response that grants credits to the peer
- * before the socket is accepted by the
- * application.
- */
- return;
}
+ spin_unlock_irqrestore(&lsc->listen.lock, flags);
+ rcu_read_unlock();
- ntstatus = le32_to_cpu(STATUS_SUCCESS);
+ /*
+ * smbdirect_socket_accept() will call
+ * smbdirect_accept_negotiate_finish(nsc, 0);
+ *
+ * So that we don't send the negotiation
+ * response that grants credits to the peer
+ * before the socket is accepted by the
+ * application.
+ */
+ return;
not_supported:
smbdirect_accept_negotiate_finish(sc, ntstatus);
@@ -838,7 +875,7 @@ struct smbdirect_socket *smbdirect_socket_accept(struct smbdirect_socket *lsc,
struct smbdirect_socket,
accept.list);
if (nsc) {
- nsc->accept.listener = NULL;
+ WRITE_ONCE(nsc->accept.listener, NULL);
list_del_init_careful(&nsc->accept.list);
arg->is_empty = list_empty_careful(&lsc->listen.ready);
}
diff --git a/fs/smb/smbdirect/internal.h b/fs/smb/smbdirect/internal.h
index e9959e6dc13ae..69d0c9f899dec 100644
--- a/fs/smb/smbdirect/internal.h
+++ b/fs/smb/smbdirect/internal.h
@@ -74,6 +74,8 @@ void __smbdirect_socket_schedule_cleanup(struct smbdirect_socket *sc,
void smbdirect_socket_destroy_sync(struct smbdirect_socket *sc);
+void smbdirect_listen_orphan_socket(struct smbdirect_socket *sc);
+
int smbdirect_socket_wait_for_credits(struct smbdirect_socket *sc,
enum smbdirect_socket_status expected_status,
int unexpected_errno,
diff --git a/fs/smb/smbdirect/listen.c b/fs/smb/smbdirect/listen.c
index 2f78bcaedbf82..3c91f00d95ce4 100644
--- a/fs/smb/smbdirect/listen.c
+++ b/fs/smb/smbdirect/listen.c
@@ -10,6 +10,78 @@
static int smbdirect_listen_rdma_event_handler(struct rdma_cm_id *id,
struct rdma_cm_event *event);
+/*
+ * This is called by a socket that failed while it
+ * is still on the pending or ready list of its
+ * listener, typically at the end of
+ * smbdirect_socket_cleanup_work(), when the
+ * disconnect was already started.
+ *
+ * It moves itself to the orphaned list and
+ * lets smbdirect_listen_purge_orphaned_work()
+ * release it. Otherwise it would stay on the
+ * pending or ready list until the listener is
+ * destroyed and fill up the backlog, so that
+ * no new connections would be accepted.
+ *
+ * It's fine to call this more than once.
+ */
+void smbdirect_listen_orphan_socket(struct smbdirect_socket *sc)
+{
+ struct smbdirect_socket *lsc;
+ unsigned long flags;
+
+ /*
+ * The memory of the listener is freed via
+ * kfree_rcu(), so it's safe to dereference it
+ * under rcu_read_lock(), even if sc->accept.listener
+ * is cleared and the listener is released concurrently.
+ */
+ rcu_read_lock();
+ lsc = READ_ONCE(sc->accept.listener);
+ if (!lsc) {
+ rcu_read_unlock();
+ return;
+ }
+
+ spin_lock_irqsave(&lsc->listen.lock, flags);
+ if (sc->accept.listener == lsc) {
+ list_move_tail(&sc->accept.list, &lsc->listen.orphaned);
+ queue_work(lsc->workqueues.cleanup, &lsc->listen.purge_orphaned_work);
+ }
+ spin_unlock_irqrestore(&lsc->listen.lock, flags);
+ rcu_read_unlock();
+}
+
+static void smbdirect_listen_purge_orphaned_work(struct work_struct *work)
+{
+ struct smbdirect_socket *lsc =
+ container_of(work, struct smbdirect_socket, listen.purge_orphaned_work);
+ struct smbdirect_socket *psc, *tsc;
+ LIST_HEAD(orphaned_list);
+ unsigned long flags;
+
+ /*
+ * Clearing accept.listener under listen.lock
+ * makes us responsible for releasing them.
+ */
+ spin_lock_irqsave(&lsc->listen.lock, flags);
+ list_splice_tail_init(&lsc->listen.orphaned, &orphaned_list);
+ list_for_each_entry(psc, &orphaned_list, accept.list)
+ WRITE_ONCE(psc->accept.listener, NULL);
+ spin_unlock_irqrestore(&lsc->listen.lock, flags);
+
+ /*
+ * We don't hold the listener's rdma_lock_handler()
+ * lock here, see smbdirect_socket_destroy()
+ * for why that's important.
+ */
+ list_for_each_entry_safe(psc, tsc, &orphaned_list, accept.list) {
+ list_del_init(&psc->accept.list);
+ smbdirect_socket_release(psc);
+ }
+}
+
int smbdirect_socket_listen(struct smbdirect_socket *sc, int backlog)
{
int ret;
@@ -47,6 +119,9 @@ int smbdirect_socket_listen(struct smbdirect_socket *sc, int backlog)
sc->rdma.cm_id->event_handler = smbdirect_listen_rdma_event_handler;
rdma_unlock_handler(sc->rdma.cm_id);
+ INIT_WORK(&sc->listen.purge_orphaned_work,
+ smbdirect_listen_purge_orphaned_work);
+
ret = rdma_listen(sc->rdma.cm_id, backlog);
if (ret) {
sc->first_error = ret;
@@ -214,6 +289,7 @@ static int smbdirect_listen_connect_request(struct smbdirect_socket *lsc,
size_t backlog = max_t(size_t, 1, lsc->listen.backlog);
size_t psockets;
size_t rsockets;
+ size_t osockets;
int ret;
if (!smbdirect_frwr_is_supported(&new_id->device->attrs)) {
@@ -254,14 +330,21 @@ static int smbdirect_listen_connect_request(struct smbdirect_socket *lsc,
spin_lock_irqsave(&lsc->listen.lock, flags);
psockets = list_count_nodes(&lsc->listen.pending);
rsockets = list_count_nodes(&lsc->listen.ready);
+ /*
+ * Orphaned sockets still count against
+ * the backlog until they are released by
+ * smbdirect_listen_purge_orphaned_work().
+ */
+ osockets = list_count_nodes(&lsc->listen.orphaned);
spin_unlock_irqrestore(&lsc->listen.lock, flags);
if (psockets > backlog ||
rsockets > backlog ||
- (psockets + rsockets) > backlog) {
+ osockets > backlog ||
+ (psockets + rsockets + osockets) > backlog) {
smbdirect_log_rdma_event(lsc, SMBDIRECT_LOG_ERR,
- "Backlog[%d][%zu] full pending[%zu] ready[%zu]\n",
- lsc->listen.backlog, backlog, psockets, rsockets);
+ "Backlog[%d][%zu] full pending[%zu] ready[%zu] orphaned[%zu]\n",
+ lsc->listen.backlog, backlog, psockets, rsockets, osockets);
return -EBUSY;
}
@@ -279,22 +362,54 @@ static int smbdirect_listen_connect_request(struct smbdirect_socket *lsc,
if (ret)
goto set_settings_failed;
+ /*
+ * Publish nsc on the pending list with accept.listener set before
+ * smbdirect_accept_connect_request() calls rdma_accept(). Once the
+ * connection can establish, smbdirect_accept_negotiate_recv_work()
+ * may run and it must observe accept.listener, otherwise nsc would
+ * be left stranded on the pending list forever.
+ *
+ * The listener's handler_mutex is held while we're called, so
+ * smbdirect_socket_destroy() of the listener can't reach nsc on the
+ * pending list before we're done.
+ *
+ * From here nsc is published on the pending list: on failure of
+ * smbdirect_accept_connect_request() below we schedule nsc's teardown,
+ * which orphans nsc off the listener so
+ * smbdirect_listen_purge_orphaned_work() -> smbdirect_socket_release()
+ * releases it.
+ */
spin_lock_irqsave(&lsc->listen.lock, flags);
list_add_tail(&nsc->accept.list, &lsc->listen.pending);
- nsc->accept.listener = lsc;
+ WRITE_ONCE(nsc->accept.listener, lsc);
spin_unlock_irqrestore(&lsc->listen.lock, flags);
ret = smbdirect_accept_connect_request(nsc, &event->param.conn);
- if (ret)
- goto accept_connect_failed;
+ if (ret) {
+ /*
+ * The rdma_cm core holds both the listener's and nsc's
+ * id_priv->handler_mutex across this CONNECT_REQUEST handler,
+ * so neither can go away under us here and nsc cannot receive
+ * any rdma event: it is safe to hand nsc to its teardown.
+ *
+ * That teardown must be deferred though: nsc->rdma.cm_id
+ * (= new_id) has its handler_mutex held by us, so it cannot be
+ * destroyed synchronously from here.
+ * smbdirect_socket_schedule_cleanup() only queues work;
+ * smbdirect_socket_cleanup_work() then orphans nsc off the
+ * listener and smbdirect_listen_purge_orphaned_work() releases
+ * it, destroying nsc's cm_id with rdma_destroy_id().
+ */
+ smbdirect_socket_schedule_cleanup(nsc, ret);
+ }
+ /*
+ * Always return 0 so the rdma_cm core keeps new_id: nsc owns it now.
+ * On success it stays connected; on failure its deferred teardown
+ * above destroys it.
+ */
return 0;
-accept_connect_failed:
- spin_lock_irqsave(&lsc->listen.lock, flags);
- list_del_init(&nsc->accept.list);
- nsc->accept.listener = NULL;
- spin_unlock_irqrestore(&lsc->listen.lock, flags);
set_settings_failed:
set_params_failed:
/*
diff --git a/fs/smb/smbdirect/socket.c b/fs/smb/smbdirect/socket.c
index c36cb7cc0088b..e270e36b3145e 100644
--- a/fs/smb/smbdirect/socket.c
+++ b/fs/smb/smbdirect/socket.c
@@ -319,6 +319,15 @@ void __smbdirect_socket_schedule_cleanup(struct smbdirect_socket *sc,
* (smbdirect_socket_destroy) to reap.
*/
if (sc->listen.backlog != -1) { /* was a listener */
+ /*
+ * We don't move them to the orphaned list here,
+ * each child does that itself at the end of its
+ * smbdirect_socket_cleanup_work(), see
+ * smbdirect_listen_orphan_socket(). Only that checks
+ * accept.listener, which is still NULL for a child
+ * that smbdirect_listen_connect_request() is still
+ * setting up and will release itself on failure.
+ */
spin_lock_irqsave(&sc->listen.lock, flags);
list_splice_init(&sc->listen.ready, &sc->listen.pending);
list_for_each_entry_safe(psc, tsc, &sc->listen.pending, accept.list)
@@ -427,6 +436,15 @@ static void smbdirect_socket_cleanup_work(struct work_struct *work)
* instances of one class -- harmless, but lockdep cannot tell).
*/
if (sc->listen.backlog != -1) { /* was a listener */
+ /*
+ * We don't move them to the orphaned list here,
+ * each child does that itself at the end of its
+ * smbdirect_socket_cleanup_work(), see
+ * smbdirect_listen_orphan_socket(). Only that checks
+ * accept.listener, which is still NULL for a child
+ * that smbdirect_listen_connect_request() is still
+ * setting up and will release itself on failure.
+ */
spin_lock_irqsave(&sc->listen.lock, flags);
list_splice_init(&sc->listen.ready, &sc->listen.pending);
list_for_each_entry_safe(psc, tsc, &sc->listen.pending, accept.list)
@@ -486,6 +504,18 @@ static void smbdirect_socket_cleanup_work(struct work_struct *work)
* in order to notice the broken connection.
*/
smbdirect_socket_wake_up_all(sc);
+
+ /*
+ * If we're still on the pending or ready list
+ * of a listener, we started the disconnect
+ * as far as possible above, so we move ourself
+ * to the orphaned list of the listener,
+ * which will release us.
+ *
+ * This is a no-op internally if
+ * sc->accept.listener is NULL.
+ */
+ smbdirect_listen_orphan_socket(sc);
}
static void smbdirect_socket_destroy(struct smbdirect_socket *sc)
@@ -544,6 +574,7 @@ static void smbdirect_socket_destroy(struct smbdirect_socket *sc)
disable_work_sync(&sc->recv_io.posted.refill_work);
disable_work_sync(&sc->idle.immediate_work);
disable_delayed_work_sync(&sc->idle.timer_work);
+ disable_work_sync(&sc->listen.purge_orphaned_work);
if (sc->rdma.cm_id)
rdma_lock_handler(sc->rdma.cm_id);
@@ -607,6 +638,19 @@ static void smbdirect_socket_destroy(struct smbdirect_socket *sc)
spin_lock_irqsave(&sc->listen.lock, flags);
list_splice_tail_init(&sc->listen.ready, &pending_list);
list_splice_tail_init(&sc->listen.pending, &pending_list);
+ /*
+ * purge_orphaned_work is already disabled above,
+ * so we also need to release the orphaned sockets.
+ *
+ * Clearing accept.listener under listen.lock
+ * makes us responsible for releasing them and
+ * prevents them from moving themselves to
+ * the orphaned list via
+ * smbdirect_listen_orphan_socket().
+ */
+ list_splice_tail_init(&sc->listen.orphaned, &pending_list);
+ list_for_each_entry(psc, &pending_list, accept.list)
+ WRITE_ONCE(psc->accept.listener, NULL);
spin_unlock_irqrestore(&sc->listen.lock, flags);
/* It's not possible for upper layer to get to reassembly */
@@ -650,7 +694,6 @@ static void smbdirect_socket_destroy(struct smbdirect_socket *sc)
"release %zu pending sockets\n", psockets);
list_for_each_entry_safe(psc, tsc, &pending_list, accept.list) {
list_del_init(&psc->accept.list);
- psc->accept.listener = NULL;
smbdirect_socket_release(psc);
}
if (sc->listen.backlog != -1) /* was a listener */
@@ -777,7 +820,17 @@ static void smbdirect_socket_release_destroy(struct kref *kref)
* in DESTROYED state, before we free the memory.
*/
smbdirect_socket_destroy_sync(sc);
- kfree(sc);
+
+ /*
+ * Only a listener (backlog != -1) is ever dereferenced
+ * via sc->accept.listener under rcu_read_lock(), see
+ * smbdirect_listen_orphan_socket(). Other sockets can be
+ * freed immediately.
+ */
+ if (sc->listen.backlog != -1) /* was a listener */
+ kfree_rcu(sc, refs.rcu);
+ else
+ kfree(sc);
}
void smbdirect_socket_release(struct smbdirect_socket *sc)
diff --git a/fs/smb/smbdirect/socket.h b/fs/smb/smbdirect/socket.h
index c09eddd8ad16d..14114a2567a2e 100644
--- a/fs/smb/smbdirect/socket.h
+++ b/fs/smb/smbdirect/socket.h
@@ -151,6 +151,12 @@ struct smbdirect_socket {
* the disconnect refcount.
*/
struct kref destroy;
+
+ /*
+ * smbdirect_socket_release_destroy() uses
+ * kfree_rcu(), see accept.listener.
+ */
+ struct rcu_head rcu;
} refs;
/* RDMA related */
@@ -216,6 +222,16 @@ struct smbdirect_socket {
* only be > 0.
*/
int backlog;
+ /*
+ * Sockets on pending or ready that failed
+ * move themselves to orphaned and queue
+ * purge_orphaned_work, which releases them.
+ * So that they are freed while the listener
+ * is still alive. They still count against
+ * the backlog until they are released.
+ */
+ struct list_head orphaned;
+ struct work_struct purge_orphaned_work;
} listen;
/*
@@ -226,7 +242,30 @@ struct smbdirect_socket {
* connection.
*/
struct {
+ /*
+ * This is only set, protected by
+ * listener->listen.lock, while the socket
+ * is owned by the listener (on its pending,
+ * ready or orphaned list). The one who clears
+ * it is responsible for releasing the socket.
+ *
+ * The memory of a struct smbdirect_socket is
+ * freed via kfree_rcu(), so the listener
+ * can be dereferenced under rcu_read_lock(),
+ * even if accept.listener is cleared and
+ * the listener is released concurrently.
+ */
struct smbdirect_socket *listener;
+ /*
+ * Linkage on one of the listener's
+ * listen.{pending,ready,orphaned} lists.
+ *
+ * accept.list and accept.listener are set
+ * together under listener->listen.lock before
+ * smbdirect_accept_connect_request() is called,
+ * so whenever the socket is on one of those lists
+ * accept.listener is that listener (never NULL).
+ */
struct list_head list;
} accept;
@@ -588,6 +627,9 @@ static __always_inline void smbdirect_socket_init(struct smbdirect_socket *sc)
spin_lock_init(&sc->listen.lock);
INIT_LIST_HEAD(&sc->listen.pending);
INIT_LIST_HEAD(&sc->listen.ready);
+ INIT_LIST_HEAD(&sc->listen.orphaned);
+ INIT_WORK(&sc->listen.purge_orphaned_work, __smbdirect_socket_disabled_work);
+ disable_work_sync(&sc->listen.purge_orphaned_work);
sc->listen.backlog = -1; /* not a listener */
init_waitqueue_head(&sc->listen.wait_queue);
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 7.2 04/10] smb: smbdirect: dont hand out already failed sockets in smbdirect_socket_accept()
2026-10-30 12:15 [PATCH 7.2 00/10] 7.2.15-rc1 review Greg Kroah-Hartman
` (2 preceding siblings ...)
2026-10-30 12:15 ` [PATCH 7.2 03/10] smb: smbdirect: release failed pending sockets of a listener Greg Kroah-Hartman
@ 2026-10-30 12:15 ` Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 05/10] iio: hid-sensor: als: scale each channel individually Greg Kroah-Hartman
` (9 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-30 12:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Namjae Jeon,
Paulo Alcantara, Tom Talpey, linux-cifs, samba-technical,
Stefan Metzmacher, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Metzmacher <metze@samba.org>
[ Upstream commit 5c171c90c446bdce80ebaecfc5ed2c410bcc7427 ]
A socket on the ready list is in SMBDIRECT_SOCKET_NEGOTIATE_RUNNING,
but it may fail before smbdirect_socket_accept() picks it up, e.g.
RDMA_CM_EVENT_DISCONNECTED already moved it to
SMBDIRECT_SOCKET_DISCONNECTED.
smbdirect_socket_accept() unconditionally overwrote the status with
SMBDIRECT_SOCKET_CONNECTED and handed out the already disconnected
socket. smbdirect_socket_cleanup_work() then called rdma_disconnect()
on it again, and before the recent commit
smbdirect_socket_destroy_sync() waited forever for an
RDMA_CM_EVENT_DISCONNECTED that already happened.
Now we check first_error and change the status to
SMBDIRECT_SOCKET_CONNECTED only via cmpxchg() from
SMBDIRECT_SOCKET_NEGOTIATE_RUNNING, while we still hold listen.lock.
If the socket already failed, we move it to the orphaned list and
queue purge_orphaned_work, like smbdirect_listen_orphan_socket() does,
and try the next one. If we only found failed sockets, we wait for
the next one.
Fixes: dc691b91ad16 ("smb: smbdirect: introduce smbdirect_socket_{listen,accept}()")
Reported-by: Sashiko <sashiko-bot+sashiko@kernel.org>
Closes: https://sashiko.dev/#/patchset/cover.1791224972.git.metze%40samba.org
Closes: https://sashiko.dev/#/bug/linux-f9dbca09-30a7-4145-9bdb-4676759982c8
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: Paulo Alcantara <pc@manguebit.org>
Cc: Tom Talpey <tom@talpey.com>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/smbdirect/accept.c | 84 +++++++++++++++++++++++++++++++++------
1 file changed, 72 insertions(+), 12 deletions(-)
diff --git a/fs/smb/smbdirect/accept.c b/fs/smb/smbdirect/accept.c
index 66db978bd8f73..d1bc08ac97575 100644
--- a/fs/smb/smbdirect/accept.c
+++ b/fs/smb/smbdirect/accept.c
@@ -835,7 +835,11 @@ static long smbdirect_socket_wait_for_accept(struct smbdirect_socket *lsc, long
if (ret < 0)
return ret;
- return 0;
+ /*
+ * Return the remaining timeout, so the caller can carry it
+ * over to the next smbdirect_socket_wait_for_accept() call.
+ */
+ return ret;
}
struct smbdirect_socket *smbdirect_socket_accept(struct smbdirect_socket *lsc,
@@ -845,6 +849,7 @@ struct smbdirect_socket *smbdirect_socket_accept(struct smbdirect_socket *lsc,
struct smbdirect_socket *nsc;
unsigned long flags;
+again:
if (lsc->status != SMBDIRECT_SOCKET_LISTENING) {
arg->err = -EINVAL;
return NULL;
@@ -856,7 +861,7 @@ struct smbdirect_socket *smbdirect_socket_accept(struct smbdirect_socket *lsc,
}
if (list_empty_careful(&lsc->listen.ready)) {
- int ret;
+ long ret;
if (timeo == 0) {
arg->err = -EAGAIN;
@@ -864,16 +869,64 @@ struct smbdirect_socket *smbdirect_socket_accept(struct smbdirect_socket *lsc,
}
ret = smbdirect_socket_wait_for_accept(lsc, timeo);
- if (ret) {
+ if (ret < 0) {
arg->err = ret;
return NULL;
}
+ /*
+ * Carry the remaining timeout over, so that a stream of
+ * failed connections that we orphan and skip (goto again)
+ * can't reset the caller's timeout and wait forever.
+ */
+ timeo = ret;
}
spin_lock_irqsave(&lsc->listen.lock, flags);
- nsc = list_first_entry_or_null(&lsc->listen.ready,
- struct smbdirect_socket,
- accept.list);
+ /*
+ * Recheck under the lock.
+ */
+ if (lsc->status != SMBDIRECT_SOCKET_LISTENING) {
+ arg->err = -EINVAL;
+ spin_unlock_irqrestore(&lsc->listen.lock, flags);
+ return NULL;
+ }
+ if (lsc->first_error) {
+ arg->err = lsc->first_error;
+ spin_unlock_irqrestore(&lsc->listen.lock, flags);
+ return NULL;
+ }
+
+ while ((nsc = list_first_entry_or_null(&lsc->listen.ready,
+ struct smbdirect_socket,
+ accept.list))) {
+ /*
+ * nsc may have failed after it was moved
+ * to the ready list, e.g. RDMA_CM_EVENT_DISCONNECTED
+ * already moved it to SMBDIRECT_SOCKET_DISCONNECTED.
+ * We must not overwrite that with
+ * SMBDIRECT_SOCKET_CONNECTED and hand
+ * out an already disconnected socket.
+ *
+ * Doing this under listen.lock means nsc
+ * still belongs to us, so we can just move
+ * a failed socket to the orphaned list,
+ * like smbdirect_listen_orphan_socket() does,
+ * and try the next one.
+ */
+ if (!READ_ONCE(nsc->first_error) &&
+ cmpxchg(&nsc->status,
+ SMBDIRECT_SOCKET_NEGOTIATE_RUNNING,
+ SMBDIRECT_SOCKET_CONNECTED) ==
+ SMBDIRECT_SOCKET_NEGOTIATE_RUNNING)
+ break;
+
+ smbdirect_log_rdma_event(nsc, SMBDIRECT_LOG_INFO,
+ "orphaning failed socket status=%s first_error=%1pe\n",
+ smbdirect_socket_status_string(nsc->status),
+ SMBDIRECT_DEBUG_ERR_PTR(nsc->first_error));
+ list_move_tail(&nsc->accept.list, &lsc->listen.orphaned);
+ queue_work(lsc->workqueues.cleanup, &lsc->listen.purge_orphaned_work);
+ }
if (nsc) {
WRITE_ONCE(nsc->accept.listener, NULL);
list_del_init_careful(&nsc->accept.list);
@@ -881,8 +934,13 @@ struct smbdirect_socket *smbdirect_socket_accept(struct smbdirect_socket *lsc,
}
spin_unlock_irqrestore(&lsc->listen.lock, flags);
if (!nsc) {
- arg->err = -EAGAIN;
- return NULL;
+ /*
+ * If we only found failed sockets or no socket,
+ * we wait for the next one.
+ *
+ * A possible -EAGAIN/-ETIMEOUT is handled above.
+ */
+ goto again;
}
/*
@@ -891,12 +949,14 @@ struct smbdirect_socket *smbdirect_socket_accept(struct smbdirect_socket *lsc,
* so it didn't grant any credits to us.
*
* The caller expects a connected socket
- * now as there are no credits anyway.
+ * now as there are no credits anyway,
+ * above we already changed to SMBDIRECT_SOCKET_CONNECTED
+ * under the lsc->listen.lock and with cmpxchg.
*
- * Then we send the negotiation response in
- * order to grant credits to the peer.
+ * Now we send the negotiation response in
+ * order to grant credits to the peer,
+ * as the socket is now visible to the application layer.
*/
- nsc->status = SMBDIRECT_SOCKET_CONNECTED;
smbdirect_accept_negotiate_finish(nsc, 0);
return nsc;
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 7.2 05/10] iio: hid-sensor: als: scale each channel individually
2026-10-30 12:15 [PATCH 7.2 00/10] 7.2.15-rc1 review Greg Kroah-Hartman
` (3 preceding siblings ...)
2026-10-30 12:15 ` [PATCH 7.2 04/10] smb: smbdirect: dont hand out already failed sockets in smbdirect_socket_accept() Greg Kroah-Hartman
@ 2026-10-30 12:15 ` Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 06/10] platform: cznic: turris-omnia-mcu: Add missing MODULE_DEVICE_TABLE() Greg Kroah-Hartman
` (8 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-30 12:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daniel Schaefer, Srinivas Pandruvada,
Jonathan Cameron, Sasha Levin, Sven Vainküla
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Schaefer <dhs@frame.work>
[ Upstream commit cad928dad9a4c26aa56b4223dc2a29bca517fb5f ]
Some sensors have multiple channels (not just brightness but color ALS
sensors) with different scaling factors.
Signed-off-by: Daniel Schaefer <dhs@frame.work>
Link: https://gitlab.freedesktop.org/hadess/iio-sensor-proxy/-/merge_requests/413
Tested-by: Sven Vainküla <sven@xn--vainkla-r2a.ee> #Asus ProArt PX13 laptop.
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/light/hid-sensor-als.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c
index 6bf1bc9a38fe6..8f2affb226a35 100644
--- a/drivers/iio/light/hid-sensor-als.c
+++ b/drivers/iio/light/hid-sensor-als.c
@@ -33,9 +33,9 @@ struct als_state {
u32 illum[CHANNEL_SCAN_INDEX_MAX];
aligned_s64 timestamp;
} scan;
- int scale_pre_decml;
- int scale_post_decml;
- int scale_precision;
+ int scale_pre_decml[CHANNEL_SCAN_INDEX_MAX];
+ int scale_post_decml[CHANNEL_SCAN_INDEX_MAX];
+ int scale_precision[CHANNEL_SCAN_INDEX_MAX];
int value_offset;
int num_channels;
s64 timestamp;
@@ -175,9 +175,11 @@ static int als_read_raw(struct iio_dev *indio_dev,
ret_type = IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SCALE:
- *val = als_state->scale_pre_decml;
- *val2 = als_state->scale_post_decml;
- ret_type = als_state->scale_precision;
+ if (chan->scan_index >= CHANNEL_SCAN_INDEX_MAX)
+ return -EINVAL;
+ *val = als_state->scale_pre_decml[chan->scan_index];
+ *val2 = als_state->scale_post_decml[chan->scan_index];
+ ret_type = als_state->scale_precision[chan->scan_index];
break;
case IIO_CHAN_INFO_OFFSET:
*val = als_state->value_offset;
@@ -331,6 +333,10 @@ static int als_parse_report(struct platform_device *pdev,
};
++index;
+ st->scale_precision[i] = hid_sensor_format_scale(usage_id,
+ &st->als[i], &st->scale_pre_decml[i],
+ &st->scale_post_decml[i]);
+
dev_dbg(&pdev->dev, "als %x:%x\n", st->als[i].index,
st->als[i].report_id);
}
@@ -340,10 +346,6 @@ static int als_parse_report(struct platform_device *pdev,
if (index)
ret = 0;
- st->scale_precision = hid_sensor_format_scale(usage_id,
- &st->als[CHANNEL_SCAN_INDEX_INTENSITY],
- &st->scale_pre_decml, &st->scale_post_decml);
-
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 7.2 06/10] platform: cznic: turris-omnia-mcu: Add missing MODULE_DEVICE_TABLE()
2026-10-30 12:15 [PATCH 7.2 00/10] 7.2.15-rc1 review Greg Kroah-Hartman
` (4 preceding siblings ...)
2026-10-30 12:15 ` [PATCH 7.2 05/10] iio: hid-sensor: als: scale each channel individually Greg Kroah-Hartman
@ 2026-10-30 12:15 ` Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 07/10] kbuild: link-vmlinux.sh: improve detection of third pass requirement Greg Kroah-Hartman
` (7 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-30 12:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ridham Khurana, Krzysztof Kozlowski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ridham Khurana <khurana.ridham222@gmail.com>
[ Upstream commit 59797443846bc2451c35816026bbb79d281c9f23 ]
The driver wires of_omnia_mcu_match into the i2c_driver's
.of_match_table but never exports it with MODULE_DEVICE_TABLE(), so no
module alias is generated and the module is not autoloaded when the MCU
is probed from the device tree.
Found by code inspection. Not tested on the hardware itself; with the
module built, the alias lookup
$ modprobe -R 'of:Nsystem-controllerT(null)Ccznic,turris-omnia-mcu'
reports no match before this change and resolves to turris_omnia_mcu
after it.
Fixes: 992f1a3d4e88 ("platform: cznic: Add preliminary support for Turris Omnia MCU")
Signed-off-by: Ridham Khurana <khurana.ridham222@gmail.com>
Link: https://patch.msgid.link/20260921204204.797294-1-khurana.ridham222@gmail.com
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/platform/cznic/turris-omnia-mcu-base.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/platform/cznic/turris-omnia-mcu-base.c b/drivers/platform/cznic/turris-omnia-mcu-base.c
index e8fc0d7b33434..f0416302a1f3c 100644
--- a/drivers/platform/cznic/turris-omnia-mcu-base.c
+++ b/drivers/platform/cznic/turris-omnia-mcu-base.c
@@ -403,6 +403,7 @@ static const struct of_device_id of_omnia_mcu_match[] = {
{ .compatible = "cznic,turris-omnia-mcu" },
{}
};
+MODULE_DEVICE_TABLE(of, of_omnia_mcu_match);
static struct i2c_driver omnia_mcu_driver = {
.probe = omnia_mcu_probe,
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 7.2 07/10] kbuild: link-vmlinux.sh: improve detection of third pass requirement
2026-10-30 12:15 [PATCH 7.2 00/10] 7.2.15-rc1 review Greg Kroah-Hartman
` (5 preceding siblings ...)
2026-10-30 12:15 ` [PATCH 7.2 06/10] platform: cznic: turris-omnia-mcu: Add missing MODULE_DEVICE_TABLE() Greg Kroah-Hartman
@ 2026-10-30 12:15 ` Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 08/10] exec: cancel io_uring requests before de_thread() Greg Kroah-Hartman
` (6 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-30 12:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, André Draszik,
Nathan Chancellor, Nicolas Schier, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: André Draszik <andre.draszik@linaro.org>
[ Upstream commit 14b8b4bf2d7bd5d58c17adbeed0edfda1dfc1a7f ]
It can happen that symbol sizes within .tmp_vmlinux1.kallsyms.o and
.tmp_vmlinux2.kallsyms.o differ, without affecting file size on disk
because of section alignment and/or padding emitted by the assembler.
link-vmlinux.sh doesn't detect this case currently and keeps using
.tmp_vmlinux2.kallsyms.o to link the final vmlinux. Due to the
different symbol sizes, other symbols are shifted within the final
image compared to .tmp_vmlinux2, and the final comparison of System.map
against "${kallsyms_sysmap}" fails with the message:
Inconsistent kallsyms data
Try "make KALLSYMS_EXTRA_PASS=1" as a workaround
This can happen in particular if the linker emits additional symbols
that might have different names between our (re-)linking steps, e.g.
because those names depend on the virtual address of the symbol. Linker
stubs for ARM errata work-arounds are one such case.
These changed symbol names can cause the output of the token
compression of kallsyms.c to change due to the changed symbol substring
count, which in turn can change the size of the kallsyms_names symbol
itself, causing the potential shift of subsequent symbol addresses in
.tmp_vmlinux2.kallsyms.o and therefore the final image.
Update link-vmlinux.sh to not rely on file size of
.tmp_vmlinux?.kallsyms.o alone but to also consider symbol offsets
within to resolve this, and do a third pass if required.
Signed-off-by: André Draszik <andre.draszik@linaro.org>
Tested-by: Nathan Chancellor <nathan@kernel.org>
Reviewed-by: Nicolas Schier <nsc@kernel.org>
Signed-off-by: Nicolas Schier <nsc@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
scripts/link-vmlinux.sh | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index f99e196abeea4..a032560eda0e8 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -106,6 +106,18 @@ vmlinux_link()
${kallsymso} ${btf_vmlinux_bin_o} ${arch_vmlinux_o} ${ldlibs}
}
+# Check if kallsymso_prev and kallsymso differ
+# If symbol sizes within ${kallsymso} change, any symbols within vmlinux are
+# likely to shift, invalidating ${kallsymso}.
+# Since file size can remain unchanged even if symbol sizes change, compare the
+# actual symbols instead of relying on file size only.
+kallsymso_changed()
+{
+ ${NM} -n "${kallsymso_prev}" > "${kallsymso_prev}.sym"
+ ${NM} -n "${kallsymso}" > "${kallsymso}.sym"
+ ! cmp -s "${kallsymso_prev}.sym" "${kallsymso}.sym"
+}
+
# Create ${2}.o file with all symbols from the ${1} object file
kallsyms()
{
@@ -126,6 +138,7 @@ kallsyms()
${CC} ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS} \
${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} -c -o "${2}.o" "${2}.S"
+ kallsymso_prev="${kallsymso:-}"
kallsymso=${2}.o
}
@@ -255,7 +268,12 @@ if is_enabled CONFIG_KALLSYMS; then
sysmap_and_kallsyms .tmp_vmlinux2
size2=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" ${kallsymso})
- if [ $size1 -ne $size2 ] || [ -n "${KALLSYMS_EXTRA_PASS}" ]; then
+ # Due to alignment, file size of the kallsymso object file might remain
+ # unchanged even if individual symbols within change size. Changed
+ # symbol sizes can still shift other symbols, though. Therefore, don't
+ # rely on file size alone.
+ if [ $size1 -ne $size2 ] || kallsymso_changed || \
+ [ -n "${KALLSYMS_EXTRA_PASS}" ]; then
vmlinux_link .tmp_vmlinux3
sysmap_and_kallsyms .tmp_vmlinux3
fi
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 7.2 08/10] exec: cancel io_uring requests before de_thread()
2026-10-30 12:15 [PATCH 7.2 00/10] 7.2.15-rc1 review Greg Kroah-Hartman
` (6 preceding siblings ...)
2026-10-30 12:15 ` [PATCH 7.2 07/10] kbuild: link-vmlinux.sh: improve detection of third pass requirement Greg Kroah-Hartman
@ 2026-10-30 12:15 ` Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 09/10] fork: move the coredump and exec checks into create_io_thread() Greg Kroah-Hartman
` (5 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-30 12:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Oleg Nesterov, Jens Axboe,
Christian Brauner (Amutable), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
[ Upstream commit b42c85c20d84ff3e4f0f027d6596c3b3b4a20657 ]
begin_new_exec() cancels the exec'ing thread's io_uring requests after
de_thread() made it the only thread in the thread-group. Now
io_uring_task_cancel() runs task work after. If it runs a
create_worker_cb() item then a io-wq queued on the thread before the
exec creates a new io-wq worker thread.
Said thread joins the thread-group which de_thread() just took down. The
io-iwq sticks around until it notices that its workqueue is dying. But
code after de_thread() relies on being single-threaded.
Move io_uring_task_cancel() before de_thread() but behind the point of
no return. Any worker created during task work run from
io_uring_task_cancel() is just a sibling thread that de_thread() will
take down and reap.
Once io_uring_task_cancel() returned the thread has neither a task
context nor a workqueue left so nothing can add a thread behind
de_thread()'s back anymore.
Suggested-by: Oleg Nesterov <oleg@redhat.com>
Link: https://lore.kernel.org/r/aq0_lvHDViIpX_Mu@redhat.com
Fixes: 3bfe6106693b ("io-wq: fork worker threads from original task")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260921-work-coredump-fixes-v3-12-8e4adb1619e6@kernel.org
Acked-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/exec.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1145,6 +1145,13 @@ int begin_new_exec(struct linux_binprm *
*/
bprm->point_of_no_return = true;
+ /*
+ * Cancel any io_uring activity across execve. This runs task work
+ * that may still create an io-wq worker, so do it while de_thread()
+ * can still zap it.
+ */
+ io_uring_task_cancel();
+
/* Make this the only thread in the thread group */
retval = de_thread(me);
if (retval)
@@ -1161,10 +1168,6 @@ int begin_new_exec(struct linux_binprm *
/* see the comment in check_unsafe_exec() */
current->fs->in_exec = 0;
- /*
- * Cancel any io_uring activity across execve
- */
- io_uring_task_cancel();
/* Ensure the files table is not shared. */
retval = unshare_files();
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 7.2 09/10] fork: move the coredump and exec checks into create_io_thread()
2026-10-30 12:15 [PATCH 7.2 00/10] 7.2.15-rc1 review Greg Kroah-Hartman
` (7 preceding siblings ...)
2026-10-30 12:15 ` [PATCH 7.2 08/10] exec: cancel io_uring requests before de_thread() Greg Kroah-Hartman
@ 2026-10-30 12:15 ` Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 10/10] fork: dont create io threads once PF_POSTCOREDUMP is set Greg Kroah-Hartman
` (4 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-30 12:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Oleg Nesterov,
Christian Brauner (Amutable), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
[ Upstream commit e760200370e4de054b6b5f568a7faa911e2956bb ]
Only a PF_USER_WORKER thread returns from get_signal() after a fatal
signal and can go on to create a thread. get_signal() sets PF_SIGNALED
before it dumps core and before it lets a PF_USER_WORKER thread return.
That flags sticks.
The exec'ing thread itself is never signaled. But it doesn't need the check
anyway as we moved cancellation of io_uring requests before de_thread().
create_io_thread() is the only way a signaled thread creates another
one. vhost_task_create() is reached from ioctls alone.
io_should_retry_thread() doesn't retry -EINTR, so io-wq callers give up
the same way they did when copy_process() refused.
Suggested-by: Oleg Nesterov <oleg@redhat.com>
Link: https://lore.kernel.org/r/aq0VLTyxNatFmLOK@redhat.com
Link: https://patch.msgid.link/20260921-work-coredump-fixes-v3-13-8e4adb1619e6@kernel.org
Acked-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Stable-dep-of: 1f978881ce6c ("fork: don't create io threads once PF_POSTCOREDUMP is set")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/fork.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -2689,6 +2689,10 @@ struct task_struct *create_io_thread(int
.user_worker = 1,
};
+ /* A creator past its fatal signal gets no thread. */
+ if (current->flags & PF_SIGNALED)
+ return ERR_PTR(-EINTR);
+
return copy_process(NULL, 0, node, &args);
}
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 7.2 10/10] fork: dont create io threads once PF_POSTCOREDUMP is set
2026-10-30 12:15 [PATCH 7.2 00/10] 7.2.15-rc1 review Greg Kroah-Hartman
` (8 preceding siblings ...)
2026-10-30 12:15 ` [PATCH 7.2 09/10] fork: move the coredump and exec checks into create_io_thread() Greg Kroah-Hartman
@ 2026-10-30 12:15 ` Greg Kroah-Hartman
2026-10-30 12:20 ` [PATCH 7.2 00/10] 7.2.15-rc1 review Peter Schneider
` (3 subsequent siblings)
13 siblings, 0 replies; 18+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-30 12:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Oleg Nesterov,
Christian Brauner (Amutable), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
[ Upstream commit 1f978881ce6c9ac4f4d4a7b6a6e52339eadcd350 ]
zap_process() skips every thread that already has PF_POSTCOREDUMP set.
Such a thread is past synchronize_group_exit(), so a coredump can't
catch it anymore. It isn't counted in core_state->threads_remaining and
it isn't sent SIGKILL.
do_exit() sets PF_POSTCOREDUMP in synchronize_group_exit() and calls
io_uring_files_cancel() right after that. The cancellation runs task
work and a create_worker_cb() that io-wq queued before the exit creates
a new io-wq worker from there. If another thread started a coredump in
the meantime that worker joins a thread-group which is already being
dumped. zap_process() never saw it so it was never counted. But when it
exits it sees signal->core_state in synchronize_group_exit() and
decrements threads_remaining like any other thread.
So the count reaches zero one thread early and the dumper leaves
coredump_wait_inactive() while a thread it counted is still running.
The task has no fatal signal pending because zap_process() deliberately
didn't send it one, and it never went through get_signal() so it doesn't
have PF_SIGNALED either.
Refuse to create an io thread when the creator has PF_POSTCOREDUMP.
That costs nothing. io_uring_files_cancel() raises IO_WQ_BIT_EXIT
before it runs any task work, so a worker created from there only ever
gets to exit again, and io_should_retry_thread() doesn't retry -EINTR.
Clearing PF_POSTCOREDUMP for the new thread in copy_process() was the
other option. It makes the worker a thread like any other, but it only
helps while the dump hasn't started. A worker born after zap_process()
has run is invisible to it whatever its flags say and still decrements
threads_remaining on the way out. Refusing to create it covers both, and
then no task is ever born with the flag, so there is nothing to clear.
Moving io_uring_files_cancel() ahead of synchronize_group_exit() closes
the same window. It runs the cancellation, and whatever that can block
on, before the thread announces itself to the dumper. A thread that
blocks there never reaches coredump_task_exit() at all, so the dumper
ends up waiting for a thread that never parks. Refusing the creation
leaves the cancellation where it is. But it's very ugly to run io_uring
work even before we did all the generic exit work.
Fixes: 92307383082d ("coredump: Don't perform any cleanups before dumping core")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260921-work-coredump-fixes-v3-14-8e4adb1619e6@kernel.org
Acked-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/fork.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -2689,8 +2689,8 @@ struct task_struct *create_io_thread(int
.user_worker = 1,
};
- /* A creator past its fatal signal gets no thread. */
- if (current->flags & PF_SIGNALED)
+ /* A creator past its fatal signal or its coredump point gets no thread. */
+ if (current->flags & (PF_SIGNALED | PF_POSTCOREDUMP))
return ERR_PTR(-EINTR);
return copy_process(NULL, 0, node, &args);
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 7.2 00/10] 7.2.15-rc1 review
2026-10-30 12:15 [PATCH 7.2 00/10] 7.2.15-rc1 review Greg Kroah-Hartman
` (9 preceding siblings ...)
2026-10-30 12:15 ` [PATCH 7.2 10/10] fork: dont create io threads once PF_POSTCOREDUMP is set Greg Kroah-Hartman
@ 2026-10-30 12:20 ` Peter Schneider
2026-10-30 12:51 ` Greg Kroah-Hartman
2026-10-30 13:12 ` Brett A C Sheffield
` (2 subsequent siblings)
13 siblings, 1 reply; 18+ messages in thread
From: Peter Schneider @ 2026-10-30 12:20 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, linux-kernel, torvalds, akpm, linux, shuah, patches,
lkft-triage, pavel, jonathanh, f.fainelli, sudipm.mukherjee,
rwarsow, conor, hargar, broonie, achill, sr
Am 30.10.2026 um 13:15 schrieb Greg Kroah-Hartman:
> This is the start of the stable review cycle for the 7.2.15 release.
Three minutes after the release of 7.2.14? Really? That's, well... ambitious.
Beste Grüße,
Peter Schneider
--
Climb the mountain not to plant your flag, but to embrace the challenge,
enjoy the air and behold the view. Climb it so you can see the world,
not so the world can see you. -- David McCullough Jr.
OpenPGP: 0xA3828BD796CCE11A8CADE8866E3A92C92C3FF244
Download: https://www.peters-netzplatz.de/download/pschneider1968_pub.asc
https://keys.mailvelope.com/pks/lookup?op=get&search=pschneider1968@googlemail.com
https://keys.mailvelope.com/pks/lookup?op=get&search=pschneider1968@gmail.com
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 7.2 03/10] smb: smbdirect: release failed pending sockets of a listener
2026-10-30 12:15 ` [PATCH 7.2 03/10] smb: smbdirect: release failed pending sockets of a listener Greg Kroah-Hartman
@ 2026-10-30 12:42 ` 이성현
0 siblings, 0 replies; 18+ messages in thread
From: 이성현 @ 2026-10-30 12:42 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: stable, patches, Sashiko, Namjae Jeon, Paulo Alcantara,
Tom Talpey, linux-cifs, samba-technical, Stefan Metzmacher,
Sasha Levin
Hi Greg and Stefan,
Thank you for fixing the SMB Direct listener backlog issue and
for considering the fix for 7.2-stable.
I also appreciate you preserving my Reported-by credit.
Best regards,
Lee Seong Hyeon
On Fri, Oct 30, 2026 at 7:15 PM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> 7.2-stable review patch. If anyone has any objections, please let me know.
>
> ------------------
>
> From: Stefan Metzmacher <metze@samba.org>
>
> [ Upstream commit 328c7e307e8411899e2f90beae83da9e4c45d700 ]
>
> A child of a listener only left the listen.pending or listen.ready
> list via smbdirect_socket_accept() or when the listener was
> destroyed. So every connection that failed before it was accepted
> (negotiate timeout, peer disconnect, invalid negotiate request, ...)
> stayed on the list and counted against the backlog until the listener
> was destroyed. After about backlog (10 for ksmbd) such connections
> smbdirect_listen_connect_request() rejected every new connection with
> -EBUSY, so an unauthenticated peer was able to permanently stop
> ksmbd from accepting SMB-Direct connections.
>
> Now a failed child moves itself to a new listen.orphaned list at the
> end of smbdirect_socket_cleanup_work(), after the disconnect was
> started, and queues listen.purge_orphaned_work, which releases it
> with smbdirect_socket_release(), without holding the listener's
> rdma_lock_handler() lock, in the same way smbdirect_socket_destroy()
> does for the remaining children. Orphaned sockets still count against
> the backlog until they are released.
>
> sc->accept.listener is now only changed under listener->listen.lock
> and whoever clears it is responsible for releasing the socket:
> smbdirect_socket_accept(), purge_orphaned_work or the destroy of the
> listener.
>
> In order to make that work:
>
> - a struct smbdirect_socket that is a listener is now freed via
> kfree_rcu(), so that a child can dereference sc->accept.listener
> under rcu_read_lock(), even if the listener is released concurrently.
>
> - smbdirect_listen_connect_request() adds nsc to the listen.pending
> list and sets nsc->accept.listener before it calls
> smbdirect_accept_connect_request(), and always returns 0 so the
> rdma_cm core keeps the connection id and nsc owns it. On a non-zero
> return it schedules nsc's teardown with
> smbdirect_socket_schedule_cleanup(), which orphans it off the
> listener so that purge_orphaned_work releases it; nsc destroys its
> own connection id with rdma_destroy_id() in that teardown. The
> teardown has to be deferred because the rdma_cm core holds nsc's
> id_priv->handler_mutex across the handler, so nsc->rdma.cm_id must
> not be destroyed synchronously from here. That same handler_mutex
> (and the listener's) also guarantees nsc can't go away under us,
> so setting the listener before the call is safe and lets a failure
> orphan nsc.
>
> - smbdirect_accept_negotiate_recv_work() no longer moves a socket to
> the ready list if it already failed or no longer belongs to the
> listener. Every accepting socket has a listener, so if
> sc->accept.listener is already cleared, it no longer sends a
> negotiate response, as the socket is about to be released.
>
> - smbdirect_socket_destroy() of the listener disables
> purge_orphaned_work and also releases the orphaned sockets.
>
> Fixes: dc691b91ad16 ("smb: smbdirect: introduce smbdirect_socket_{listen,accept}()")
> Reported-by: Lee Seong Hyeon <ihopenre@gmail.com>
> Closes: https://lore.kernel.org/linux-cifs/CANTrAmxL5sWU8Sn29JAGZvSq5PBB2OA+VKA0MHsZJMesagtfzA@mail.gmail.com/
> Reported-by: Sashiko <sashiko-bot+sashiko@kernel.org>
> Closes: https://sashiko.dev/#/patchset/cover.1791224972.git.metze%40samba.org
> Closes: https://sashiko.dev/#/patchset/cover.1791229120.git.metze%40samba.org
> Cc: Namjae Jeon <linkinjeon@kernel.org>
> Cc: Paulo Alcantara <pc@manguebit.org>
> Cc: Tom Talpey <tom@talpey.com>
> Cc: linux-cifs@vger.kernel.org
> Cc: samba-technical@lists.samba.org
> Assisted-by: Claude:claude-opus-5-5
> Signed-off-by: Stefan Metzmacher <metze@samba.org>
> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---
> fs/smb/smbdirect/accept.c | 141 +++++++++++++++++++++++-------------
> fs/smb/smbdirect/internal.h | 2 +
> fs/smb/smbdirect/listen.c | 137 ++++++++++++++++++++++++++++++++---
> fs/smb/smbdirect/socket.c | 57 ++++++++++++++-
> fs/smb/smbdirect/socket.h | 42 +++++++++++
> 5 files changed, 314 insertions(+), 65 deletions(-)
>
> diff --git a/fs/smb/smbdirect/accept.c b/fs/smb/smbdirect/accept.c
> index 039c9bfbd8acd..66db978bd8f73 100644
> --- a/fs/smb/smbdirect/accept.c
> +++ b/fs/smb/smbdirect/accept.c
> @@ -19,15 +19,33 @@ int smbdirect_accept_connect_request(struct smbdirect_socket *sc,
> const struct rdma_conn_param *param)
> {
> struct smbdirect_socket_parameters *sp = &sc->parameters;
> - struct smbdirect_recv_io *recv_io;
> + struct smbdirect_recv_io *recv_io = NULL;
> u8 peer_initiator_depth;
> u8 peer_responder_resources;
> struct rdma_conn_param conn_param;
> __be32 ird_ord_hdr[2];
> int ret;
>
> - if (SMBDIRECT_CHECK_STATUS_WARN(sc, SMBDIRECT_SOCKET_CREATED))
> - return -EINVAL;
> + /*
> + * Install the real event handler (and the event we expect next)
> + * before anything that can fail. On an early error the caller
> + * (smbdirect_listen_connect_request()) only schedules our deferred
> + * cleanup and returns 0 to the rdma_cm core, which keeps the cm_id, so
> + * the cm_id must already carry smbdirect_accept_rdma_event_handler():
> + * it turns any unexpected event (e.g. RDMA_CM_EVENT_DEVICE_REMOVAL)
> + * into a clean smbdirect_socket_schedule_cleanup(). Otherwise the
> + * placeholder smbdirect_socket_rdma_event_handler() installed by
> + * smbdirect_socket_init_accepting() stays in place and returns -ESTALE,
> + * which makes the rdma_cm core destroy the cm_id behind the back of our
> + * pending teardown.
> + */
> + sc->rdma.expected_event = RDMA_CM_EVENT_ESTABLISHED;
> + sc->rdma.cm_id->event_handler = smbdirect_accept_rdma_event_handler;
> +
> + if (SMBDIRECT_CHECK_STATUS_WARN(sc, SMBDIRECT_SOCKET_CREATED)) {
> + ret = -EINVAL;
> + goto cleanup;
> + }
>
> /*
> * First set what the we as server are able to support
> @@ -47,7 +65,7 @@ int smbdirect_accept_connect_request(struct smbdirect_socket *sc,
> smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR,
> "smbdirect_accept_init_params() failed %1pe\n",
> SMBDIRECT_DEBUG_ERR_PTR(ret));
> - goto init_params_failed;
> + goto cleanup;
> }
>
> ret = smbdirect_connection_create_qp(sc);
> @@ -55,7 +73,7 @@ int smbdirect_accept_connect_request(struct smbdirect_socket *sc,
> smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR,
> "smbdirect_connection_create_qp() failed %1pe\n",
> SMBDIRECT_DEBUG_ERR_PTR(ret));
> - goto create_qp_failed;
> + goto cleanup;
> }
>
> ret = smbdirect_connection_create_mem_pools(sc);
> @@ -63,7 +81,7 @@ int smbdirect_accept_connect_request(struct smbdirect_socket *sc,
> smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR,
> "smbdirect_connection_create_mem_pools() failed %1pe\n",
> SMBDIRECT_DEBUG_ERR_PTR(ret));
> - goto create_mem_failed;
> + goto cleanup;
> }
>
> recv_io = smbdirect_connection_get_recv_io(sc);
> @@ -72,7 +90,7 @@ int smbdirect_accept_connect_request(struct smbdirect_socket *sc,
> smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR,
> "smbdirect_connection_get_recv_io() failed %1pe\n",
> SMBDIRECT_DEBUG_ERR_PTR(ret));
> - goto get_recv_io_failed;
> + goto cleanup;
> }
> recv_io->cqe.done = smbdirect_accept_negotiate_recv_done;
>
> @@ -86,7 +104,7 @@ int smbdirect_accept_connect_request(struct smbdirect_socket *sc,
> smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR,
> "smbdirect_connection_post_recv_io() failed %1pe\n",
> SMBDIRECT_DEBUG_ERR_PTR(ret));
> - goto post_recv_io_failed;
> + goto cleanup;
> }
> /*
> * From here recv_io is known to the RDMA QP and needs ib_drain_qp and
> @@ -122,14 +140,12 @@ int smbdirect_accept_connect_request(struct smbdirect_socket *sc,
> /* explicitly set above */
> WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RDMA_CONNECT_NEEDED);
> sc->status = SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING;
> - sc->rdma.expected_event = RDMA_CM_EVENT_ESTABLISHED;
> - sc->rdma.cm_id->event_handler = smbdirect_accept_rdma_event_handler;
> ret = rdma_accept(sc->rdma.cm_id, &conn_param);
> if (ret) {
> smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR,
> "rdma_accept() failed %1pe\n",
> SMBDIRECT_DEBUG_ERR_PTR(ret));
> - goto rdma_accept_failed;
> + goto cleanup;
> }
>
> /*
> @@ -143,31 +159,25 @@ int smbdirect_accept_connect_request(struct smbdirect_socket *sc,
>
> return 0;
>
> -rdma_accept_failed:
> +cleanup:
> /*
> - * The recv_io posted above is now owned by the QP (recv_io was set to
> - * NULL after a successful post). smbdirect_connection_destroy_qp()
> - * calls ib_drain_qp(), whose completion
> - * (smbdirect_accept_negotiate_recv_done) returns the recv_io to the
> - * free list via smbdirect_connection_put_recv_io(). It therefore MUST
> - * run BEFORE smbdirect_connection_destroy_mem_pools(): otherwise the
> - * posted recv_io is still outstanding when kmem_cache_destroy() runs
> - * ("Slab cache still has objects") and is later freed into an
> - * already-destroyed mempool (mempool_free_bulk NULL-ptr-deref).
> + * No RDMA state is torn down here, and in particular sc is not
> + * released: the caller (smbdirect_listen_connect_request()) owns that
> + * decision and schedules sc's teardown via
> + * smbdirect_socket_schedule_cleanup() on a non-zero return. All of the
> + * RDMA state - the QP, the memory pools and the cm_id itself - is then
> + * torn down asynchronously by smbdirect_socket_cleanup_work() ->
> + * smbdirect_socket_release() -> smbdirect_socket_destroy(), which
> + * drains the QP (returning any posted recv_io to the pool) before
> + * destroying the memory pools and destroys the cm_id with
> + * rdma_destroy_id(), all in the correct order.
> + *
> + * The only resource not reachable by that teardown is a recv_io that
> + * was taken from the pool but not yet posted to the QP (recv_io is set
> + * to NULL after a successful post), so hand it back here.
> */
> - smbdirect_connection_destroy_qp(sc);
> - smbdirect_connection_destroy_mem_pools(sc);
> - return ret;
> -post_recv_io_failed:
> - /* post failed: recv_io was not accepted by the QP, still in hand */
> if (recv_io)
> smbdirect_connection_put_recv_io(recv_io);
> -get_recv_io_failed:
> - smbdirect_connection_destroy_mem_pools(sc);
> -create_mem_failed:
> - smbdirect_connection_destroy_qp(sc);
> -create_qp_failed:
> -init_params_failed:
> return ret;
> }
>
> @@ -301,6 +311,7 @@ static void smbdirect_accept_negotiate_recv_work(struct work_struct *work)
> struct smbdirect_socket *sc =
> container_of(work, struct smbdirect_socket, connect.work);
> struct smbdirect_socket_parameters *sp = &sc->parameters;
> + struct smbdirect_socket *lsc;
> struct smbdirect_recv_io *recv_io;
> struct smbdirect_negotiate_req *nreq;
> unsigned long flags;
> @@ -463,29 +474,55 @@ static void smbdirect_accept_negotiate_recv_work(struct work_struct *work)
> */
> sp->max_fragmented_send_size = max_fragmented_size;
>
> - if (sc->accept.listener) {
> - struct smbdirect_socket *lsc = sc->accept.listener;
> - unsigned long flags;
> + /*
> + * Every accepting socket was created by
> + * smbdirect_listen_connect_request() and has a
> + * listener. If it's already cleared, the listener
> + * (or its purge_orphaned_work) is responsible for
> + * releasing us, so we must not send a negotiate
> + * response.
> + *
> + * The memory of the listener is freed via kfree_rcu(),
> + * see smbdirect_listen_orphan_socket().
> + */
> + rcu_read_lock();
> + lsc = READ_ONCE(sc->accept.listener);
> + if (!lsc) {
> + rcu_read_unlock();
> + return;
> + }
>
> - spin_lock_irqsave(&lsc->listen.lock, flags);
> - list_del(&sc->accept.list);
> - list_add_tail(&sc->accept.list, &lsc->listen.ready);
> + spin_lock_irqsave(&lsc->listen.lock, flags);
> + /*
> + * The listener (or its purge_orphaned_work)
> + * may have cleared sc->accept.listener in the
> + * meantime and is responsible for releasing us.
> + *
> + * If we already failed, we're either
> + * already on the orphaned list or
> + * smbdirect_socket_cleanup_work() will
> + * move us there.
> + *
> + * In both cases we must not move us
> + * to the ready list.
> + */
> + if (sc->accept.listener == lsc && !READ_ONCE(sc->first_error)) {
> + list_move_tail(&sc->accept.list, &lsc->listen.ready);
> wake_up(&lsc->listen.wait_queue);
> - spin_unlock_irqrestore(&lsc->listen.lock, flags);
> -
> - /*
> - * smbdirect_socket_accept() will call
> - * smbdirect_accept_negotiate_finish(nsc, 0);
> - *
> - * So that we don't send the negotiation
> - * response that grants credits to the peer
> - * before the socket is accepted by the
> - * application.
> - */
> - return;
> }
> + spin_unlock_irqrestore(&lsc->listen.lock, flags);
> + rcu_read_unlock();
>
> - ntstatus = le32_to_cpu(STATUS_SUCCESS);
> + /*
> + * smbdirect_socket_accept() will call
> + * smbdirect_accept_negotiate_finish(nsc, 0);
> + *
> + * So that we don't send the negotiation
> + * response that grants credits to the peer
> + * before the socket is accepted by the
> + * application.
> + */
> + return;
>
> not_supported:
> smbdirect_accept_negotiate_finish(sc, ntstatus);
> @@ -838,7 +875,7 @@ struct smbdirect_socket *smbdirect_socket_accept(struct smbdirect_socket *lsc,
> struct smbdirect_socket,
> accept.list);
> if (nsc) {
> - nsc->accept.listener = NULL;
> + WRITE_ONCE(nsc->accept.listener, NULL);
> list_del_init_careful(&nsc->accept.list);
> arg->is_empty = list_empty_careful(&lsc->listen.ready);
> }
> diff --git a/fs/smb/smbdirect/internal.h b/fs/smb/smbdirect/internal.h
> index e9959e6dc13ae..69d0c9f899dec 100644
> --- a/fs/smb/smbdirect/internal.h
> +++ b/fs/smb/smbdirect/internal.h
> @@ -74,6 +74,8 @@ void __smbdirect_socket_schedule_cleanup(struct smbdirect_socket *sc,
>
> void smbdirect_socket_destroy_sync(struct smbdirect_socket *sc);
>
> +void smbdirect_listen_orphan_socket(struct smbdirect_socket *sc);
> +
> int smbdirect_socket_wait_for_credits(struct smbdirect_socket *sc,
> enum smbdirect_socket_status expected_status,
> int unexpected_errno,
> diff --git a/fs/smb/smbdirect/listen.c b/fs/smb/smbdirect/listen.c
> index 2f78bcaedbf82..3c91f00d95ce4 100644
> --- a/fs/smb/smbdirect/listen.c
> +++ b/fs/smb/smbdirect/listen.c
> @@ -10,6 +10,78 @@
> static int smbdirect_listen_rdma_event_handler(struct rdma_cm_id *id,
> struct rdma_cm_event *event);
>
> +/*
> + * This is called by a socket that failed while it
> + * is still on the pending or ready list of its
> + * listener, typically at the end of
> + * smbdirect_socket_cleanup_work(), when the
> + * disconnect was already started.
> + *
> + * It moves itself to the orphaned list and
> + * lets smbdirect_listen_purge_orphaned_work()
> + * release it. Otherwise it would stay on the
> + * pending or ready list until the listener is
> + * destroyed and fill up the backlog, so that
> + * no new connections would be accepted.
> + *
> + * It's fine to call this more than once.
> + */
> +void smbdirect_listen_orphan_socket(struct smbdirect_socket *sc)
> +{
> + struct smbdirect_socket *lsc;
> + unsigned long flags;
> +
> + /*
> + * The memory of the listener is freed via
> + * kfree_rcu(), so it's safe to dereference it
> + * under rcu_read_lock(), even if sc->accept.listener
> + * is cleared and the listener is released concurrently.
> + */
> + rcu_read_lock();
> + lsc = READ_ONCE(sc->accept.listener);
> + if (!lsc) {
> + rcu_read_unlock();
> + return;
> + }
> +
> + spin_lock_irqsave(&lsc->listen.lock, flags);
> + if (sc->accept.listener == lsc) {
> + list_move_tail(&sc->accept.list, &lsc->listen.orphaned);
> + queue_work(lsc->workqueues.cleanup, &lsc->listen.purge_orphaned_work);
> + }
> + spin_unlock_irqrestore(&lsc->listen.lock, flags);
> + rcu_read_unlock();
> +}
> +
> +static void smbdirect_listen_purge_orphaned_work(struct work_struct *work)
> +{
> + struct smbdirect_socket *lsc =
> + container_of(work, struct smbdirect_socket, listen.purge_orphaned_work);
> + struct smbdirect_socket *psc, *tsc;
> + LIST_HEAD(orphaned_list);
> + unsigned long flags;
> +
> + /*
> + * Clearing accept.listener under listen.lock
> + * makes us responsible for releasing them.
> + */
> + spin_lock_irqsave(&lsc->listen.lock, flags);
> + list_splice_tail_init(&lsc->listen.orphaned, &orphaned_list);
> + list_for_each_entry(psc, &orphaned_list, accept.list)
> + WRITE_ONCE(psc->accept.listener, NULL);
> + spin_unlock_irqrestore(&lsc->listen.lock, flags);
> +
> + /*
> + * We don't hold the listener's rdma_lock_handler()
> + * lock here, see smbdirect_socket_destroy()
> + * for why that's important.
> + */
> + list_for_each_entry_safe(psc, tsc, &orphaned_list, accept.list) {
> + list_del_init(&psc->accept.list);
> + smbdirect_socket_release(psc);
> + }
> +}
> +
> int smbdirect_socket_listen(struct smbdirect_socket *sc, int backlog)
> {
> int ret;
> @@ -47,6 +119,9 @@ int smbdirect_socket_listen(struct smbdirect_socket *sc, int backlog)
> sc->rdma.cm_id->event_handler = smbdirect_listen_rdma_event_handler;
> rdma_unlock_handler(sc->rdma.cm_id);
>
> + INIT_WORK(&sc->listen.purge_orphaned_work,
> + smbdirect_listen_purge_orphaned_work);
> +
> ret = rdma_listen(sc->rdma.cm_id, backlog);
> if (ret) {
> sc->first_error = ret;
> @@ -214,6 +289,7 @@ static int smbdirect_listen_connect_request(struct smbdirect_socket *lsc,
> size_t backlog = max_t(size_t, 1, lsc->listen.backlog);
> size_t psockets;
> size_t rsockets;
> + size_t osockets;
> int ret;
>
> if (!smbdirect_frwr_is_supported(&new_id->device->attrs)) {
> @@ -254,14 +330,21 @@ static int smbdirect_listen_connect_request(struct smbdirect_socket *lsc,
> spin_lock_irqsave(&lsc->listen.lock, flags);
> psockets = list_count_nodes(&lsc->listen.pending);
> rsockets = list_count_nodes(&lsc->listen.ready);
> + /*
> + * Orphaned sockets still count against
> + * the backlog until they are released by
> + * smbdirect_listen_purge_orphaned_work().
> + */
> + osockets = list_count_nodes(&lsc->listen.orphaned);
> spin_unlock_irqrestore(&lsc->listen.lock, flags);
>
> if (psockets > backlog ||
> rsockets > backlog ||
> - (psockets + rsockets) > backlog) {
> + osockets > backlog ||
> + (psockets + rsockets + osockets) > backlog) {
> smbdirect_log_rdma_event(lsc, SMBDIRECT_LOG_ERR,
> - "Backlog[%d][%zu] full pending[%zu] ready[%zu]\n",
> - lsc->listen.backlog, backlog, psockets, rsockets);
> + "Backlog[%d][%zu] full pending[%zu] ready[%zu] orphaned[%zu]\n",
> + lsc->listen.backlog, backlog, psockets, rsockets, osockets);
> return -EBUSY;
> }
>
> @@ -279,22 +362,54 @@ static int smbdirect_listen_connect_request(struct smbdirect_socket *lsc,
> if (ret)
> goto set_settings_failed;
>
> + /*
> + * Publish nsc on the pending list with accept.listener set before
> + * smbdirect_accept_connect_request() calls rdma_accept(). Once the
> + * connection can establish, smbdirect_accept_negotiate_recv_work()
> + * may run and it must observe accept.listener, otherwise nsc would
> + * be left stranded on the pending list forever.
> + *
> + * The listener's handler_mutex is held while we're called, so
> + * smbdirect_socket_destroy() of the listener can't reach nsc on the
> + * pending list before we're done.
> + *
> + * From here nsc is published on the pending list: on failure of
> + * smbdirect_accept_connect_request() below we schedule nsc's teardown,
> + * which orphans nsc off the listener so
> + * smbdirect_listen_purge_orphaned_work() -> smbdirect_socket_release()
> + * releases it.
> + */
> spin_lock_irqsave(&lsc->listen.lock, flags);
> list_add_tail(&nsc->accept.list, &lsc->listen.pending);
> - nsc->accept.listener = lsc;
> + WRITE_ONCE(nsc->accept.listener, lsc);
> spin_unlock_irqrestore(&lsc->listen.lock, flags);
>
> ret = smbdirect_accept_connect_request(nsc, &event->param.conn);
> - if (ret)
> - goto accept_connect_failed;
> + if (ret) {
> + /*
> + * The rdma_cm core holds both the listener's and nsc's
> + * id_priv->handler_mutex across this CONNECT_REQUEST handler,
> + * so neither can go away under us here and nsc cannot receive
> + * any rdma event: it is safe to hand nsc to its teardown.
> + *
> + * That teardown must be deferred though: nsc->rdma.cm_id
> + * (= new_id) has its handler_mutex held by us, so it cannot be
> + * destroyed synchronously from here.
> + * smbdirect_socket_schedule_cleanup() only queues work;
> + * smbdirect_socket_cleanup_work() then orphans nsc off the
> + * listener and smbdirect_listen_purge_orphaned_work() releases
> + * it, destroying nsc's cm_id with rdma_destroy_id().
> + */
> + smbdirect_socket_schedule_cleanup(nsc, ret);
> + }
>
> + /*
> + * Always return 0 so the rdma_cm core keeps new_id: nsc owns it now.
> + * On success it stays connected; on failure its deferred teardown
> + * above destroys it.
> + */
> return 0;
>
> -accept_connect_failed:
> - spin_lock_irqsave(&lsc->listen.lock, flags);
> - list_del_init(&nsc->accept.list);
> - nsc->accept.listener = NULL;
> - spin_unlock_irqrestore(&lsc->listen.lock, flags);
> set_settings_failed:
> set_params_failed:
> /*
> diff --git a/fs/smb/smbdirect/socket.c b/fs/smb/smbdirect/socket.c
> index c36cb7cc0088b..e270e36b3145e 100644
> --- a/fs/smb/smbdirect/socket.c
> +++ b/fs/smb/smbdirect/socket.c
> @@ -319,6 +319,15 @@ void __smbdirect_socket_schedule_cleanup(struct smbdirect_socket *sc,
> * (smbdirect_socket_destroy) to reap.
> */
> if (sc->listen.backlog != -1) { /* was a listener */
> + /*
> + * We don't move them to the orphaned list here,
> + * each child does that itself at the end of its
> + * smbdirect_socket_cleanup_work(), see
> + * smbdirect_listen_orphan_socket(). Only that checks
> + * accept.listener, which is still NULL for a child
> + * that smbdirect_listen_connect_request() is still
> + * setting up and will release itself on failure.
> + */
> spin_lock_irqsave(&sc->listen.lock, flags);
> list_splice_init(&sc->listen.ready, &sc->listen.pending);
> list_for_each_entry_safe(psc, tsc, &sc->listen.pending, accept.list)
> @@ -427,6 +436,15 @@ static void smbdirect_socket_cleanup_work(struct work_struct *work)
> * instances of one class -- harmless, but lockdep cannot tell).
> */
> if (sc->listen.backlog != -1) { /* was a listener */
> + /*
> + * We don't move them to the orphaned list here,
> + * each child does that itself at the end of its
> + * smbdirect_socket_cleanup_work(), see
> + * smbdirect_listen_orphan_socket(). Only that checks
> + * accept.listener, which is still NULL for a child
> + * that smbdirect_listen_connect_request() is still
> + * setting up and will release itself on failure.
> + */
> spin_lock_irqsave(&sc->listen.lock, flags);
> list_splice_init(&sc->listen.ready, &sc->listen.pending);
> list_for_each_entry_safe(psc, tsc, &sc->listen.pending, accept.list)
> @@ -486,6 +504,18 @@ static void smbdirect_socket_cleanup_work(struct work_struct *work)
> * in order to notice the broken connection.
> */
> smbdirect_socket_wake_up_all(sc);
> +
> + /*
> + * If we're still on the pending or ready list
> + * of a listener, we started the disconnect
> + * as far as possible above, so we move ourself
> + * to the orphaned list of the listener,
> + * which will release us.
> + *
> + * This is a no-op internally if
> + * sc->accept.listener is NULL.
> + */
> + smbdirect_listen_orphan_socket(sc);
> }
>
> static void smbdirect_socket_destroy(struct smbdirect_socket *sc)
> @@ -544,6 +574,7 @@ static void smbdirect_socket_destroy(struct smbdirect_socket *sc)
> disable_work_sync(&sc->recv_io.posted.refill_work);
> disable_work_sync(&sc->idle.immediate_work);
> disable_delayed_work_sync(&sc->idle.timer_work);
> + disable_work_sync(&sc->listen.purge_orphaned_work);
>
> if (sc->rdma.cm_id)
> rdma_lock_handler(sc->rdma.cm_id);
> @@ -607,6 +638,19 @@ static void smbdirect_socket_destroy(struct smbdirect_socket *sc)
> spin_lock_irqsave(&sc->listen.lock, flags);
> list_splice_tail_init(&sc->listen.ready, &pending_list);
> list_splice_tail_init(&sc->listen.pending, &pending_list);
> + /*
> + * purge_orphaned_work is already disabled above,
> + * so we also need to release the orphaned sockets.
> + *
> + * Clearing accept.listener under listen.lock
> + * makes us responsible for releasing them and
> + * prevents them from moving themselves to
> + * the orphaned list via
> + * smbdirect_listen_orphan_socket().
> + */
> + list_splice_tail_init(&sc->listen.orphaned, &pending_list);
> + list_for_each_entry(psc, &pending_list, accept.list)
> + WRITE_ONCE(psc->accept.listener, NULL);
> spin_unlock_irqrestore(&sc->listen.lock, flags);
>
> /* It's not possible for upper layer to get to reassembly */
> @@ -650,7 +694,6 @@ static void smbdirect_socket_destroy(struct smbdirect_socket *sc)
> "release %zu pending sockets\n", psockets);
> list_for_each_entry_safe(psc, tsc, &pending_list, accept.list) {
> list_del_init(&psc->accept.list);
> - psc->accept.listener = NULL;
> smbdirect_socket_release(psc);
> }
> if (sc->listen.backlog != -1) /* was a listener */
> @@ -777,7 +820,17 @@ static void smbdirect_socket_release_destroy(struct kref *kref)
> * in DESTROYED state, before we free the memory.
> */
> smbdirect_socket_destroy_sync(sc);
> - kfree(sc);
> +
> + /*
> + * Only a listener (backlog != -1) is ever dereferenced
> + * via sc->accept.listener under rcu_read_lock(), see
> + * smbdirect_listen_orphan_socket(). Other sockets can be
> + * freed immediately.
> + */
> + if (sc->listen.backlog != -1) /* was a listener */
> + kfree_rcu(sc, refs.rcu);
> + else
> + kfree(sc);
> }
>
> void smbdirect_socket_release(struct smbdirect_socket *sc)
> diff --git a/fs/smb/smbdirect/socket.h b/fs/smb/smbdirect/socket.h
> index c09eddd8ad16d..14114a2567a2e 100644
> --- a/fs/smb/smbdirect/socket.h
> +++ b/fs/smb/smbdirect/socket.h
> @@ -151,6 +151,12 @@ struct smbdirect_socket {
> * the disconnect refcount.
> */
> struct kref destroy;
> +
> + /*
> + * smbdirect_socket_release_destroy() uses
> + * kfree_rcu(), see accept.listener.
> + */
> + struct rcu_head rcu;
> } refs;
>
> /* RDMA related */
> @@ -216,6 +222,16 @@ struct smbdirect_socket {
> * only be > 0.
> */
> int backlog;
> + /*
> + * Sockets on pending or ready that failed
> + * move themselves to orphaned and queue
> + * purge_orphaned_work, which releases them.
> + * So that they are freed while the listener
> + * is still alive. They still count against
> + * the backlog until they are released.
> + */
> + struct list_head orphaned;
> + struct work_struct purge_orphaned_work;
> } listen;
>
> /*
> @@ -226,7 +242,30 @@ struct smbdirect_socket {
> * connection.
> */
> struct {
> + /*
> + * This is only set, protected by
> + * listener->listen.lock, while the socket
> + * is owned by the listener (on its pending,
> + * ready or orphaned list). The one who clears
> + * it is responsible for releasing the socket.
> + *
> + * The memory of a struct smbdirect_socket is
> + * freed via kfree_rcu(), so the listener
> + * can be dereferenced under rcu_read_lock(),
> + * even if accept.listener is cleared and
> + * the listener is released concurrently.
> + */
> struct smbdirect_socket *listener;
> + /*
> + * Linkage on one of the listener's
> + * listen.{pending,ready,orphaned} lists.
> + *
> + * accept.list and accept.listener are set
> + * together under listener->listen.lock before
> + * smbdirect_accept_connect_request() is called,
> + * so whenever the socket is on one of those lists
> + * accept.listener is that listener (never NULL).
> + */
> struct list_head list;
> } accept;
>
> @@ -588,6 +627,9 @@ static __always_inline void smbdirect_socket_init(struct smbdirect_socket *sc)
> spin_lock_init(&sc->listen.lock);
> INIT_LIST_HEAD(&sc->listen.pending);
> INIT_LIST_HEAD(&sc->listen.ready);
> + INIT_LIST_HEAD(&sc->listen.orphaned);
> + INIT_WORK(&sc->listen.purge_orphaned_work, __smbdirect_socket_disabled_work);
> + disable_work_sync(&sc->listen.purge_orphaned_work);
> sc->listen.backlog = -1; /* not a listener */
> init_waitqueue_head(&sc->listen.wait_queue);
>
> --
> 2.53.0
>
>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 7.2 00/10] 7.2.15-rc1 review
2026-10-30 12:20 ` [PATCH 7.2 00/10] 7.2.15-rc1 review Peter Schneider
@ 2026-10-30 12:51 ` Greg Kroah-Hartman
2026-10-30 12:58 ` Peter Schneider
0 siblings, 1 reply; 18+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-30 12:51 UTC (permalink / raw)
To: Peter Schneider
Cc: stable, patches, linux-kernel, torvalds, akpm, linux, shuah,
patches, lkft-triage, pavel, jonathanh, f.fainelli,
sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr
On Fri, Oct 30, 2026 at 01:20:49PM +0100, Peter Schneider wrote:
> Am 30.10.2026 um 13:15 schrieb Greg Kroah-Hartman:
> > This is the start of the stable review cycle for the 7.2.15 release.
>
> Three minutes after the release of 7.2.14? Really? That's, well... ambitious.
Yes it is :)
I want this to be the last 7.2.y release, and everyone move to 7.3.y
after it is out in a day or so. We have just too many stable kernels
"in flight" right now, and too many pending patches based on the huge
number of bugfixes flowing through the system right now. This is an
attempt to keep on top of that by reducing our release load (and your
testing load).
thanks,
greg k-h
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 7.2 00/10] 7.2.15-rc1 review
2026-10-30 12:51 ` Greg Kroah-Hartman
@ 2026-10-30 12:58 ` Peter Schneider
0 siblings, 0 replies; 18+ messages in thread
From: Peter Schneider @ 2026-10-30 12:58 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: stable, patches, linux-kernel, torvalds, akpm, linux, shuah,
patches, lkft-triage, pavel, jonathanh, f.fainelli,
sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr
Am 30.10.2026 um 13:51 schrieb Greg Kroah-Hartman:
> On Fri, Oct 30, 2026 at 01:20:49PM +0100, Peter Schneider wrote:
>> Am 30.10.2026 um 13:15 schrieb Greg Kroah-Hartman:
>>> This is the start of the stable review cycle for the 7.2.15 release.
>>
>> Three minutes after the release of 7.2.14? Really? That's, well... ambitious.
>
> Yes it is :)
>
> I want this to be the last 7.2.y release, and everyone move to 7.3.y
> after it is out in a day or so. We have just too many stable kernels
> "in flight" right now, and too many pending patches based on the huge
> number of bugfixes flowing through the system right now. This is an
> attempt to keep on top of that by reducing our release load (and your
> testing load).
Ah ok, understood. That makes perfect sense.
I was wondering, anyway, how on earth you and Sasha manage that immense workload. I guessed that you must have,
together, at least twelve arms and five heads to be able to do what you are doing.
I have to say, that I am damn glad that I don't have your job! 😉😁
Beste Grüße,
Peter Schneider
--
Climb the mountain not to plant your flag, but to embrace the challenge,
enjoy the air and behold the view. Climb it so you can see the world,
not so the world can see you. -- David McCullough Jr.
OpenPGP: 0xA3828BD796CCE11A8CADE8866E3A92C92C3FF244
Download: https://www.peters-netzplatz.de/download/pschneider1968_pub.asc
https://keys.mailvelope.com/pks/lookup?op=get&search=pschneider1968@googlemail.com
https://keys.mailvelope.com/pks/lookup?op=get&search=pschneider1968@gmail.com
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 7.2 00/10] 7.2.15-rc1 review
2026-10-30 12:15 [PATCH 7.2 00/10] 7.2.15-rc1 review Greg Kroah-Hartman
` (10 preceding siblings ...)
2026-10-30 12:20 ` [PATCH 7.2 00/10] 7.2.15-rc1 review Peter Schneider
@ 2026-10-30 13:12 ` Brett A C Sheffield
2026-10-30 13:47 ` Pavel Machek
2026-10-30 14:01 ` Miguel Ojeda
13 siblings, 0 replies; 18+ messages in thread
From: Brett A C Sheffield @ 2026-10-30 13:12 UTC (permalink / raw)
To: gregkh
Cc: stable, patches, linux-kernel, torvalds, akpm, linux, shuah,
patches, lkft-triage, pavel, jonathanh, f.fainelli,
sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr,
Brett A C Sheffield
# Librecast Test Results
044/044 [ OK ] liblcrq
010/010 [ OK ] libmld
120/120 [ OK ] liblibrecast
CPU/kernel: Linux auntie 7.2.15-rc1-g82a6a11b11e6 #1 SMP PREEMPT_DYNAMIC Fri Oct 30 12:31:49 -00 2026 x86_64 AMD Ryzen 9 9950X 16-Core Processor AuthenticAMD GNU/Linux
Tested-by: Brett A C Sheffield <bacs@librecast.net>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 7.2 00/10] 7.2.15-rc1 review
2026-10-30 12:15 [PATCH 7.2 00/10] 7.2.15-rc1 review Greg Kroah-Hartman
` (11 preceding siblings ...)
2026-10-30 13:12 ` Brett A C Sheffield
@ 2026-10-30 13:47 ` Pavel Machek
2026-10-30 14:01 ` Miguel Ojeda
13 siblings, 0 replies; 18+ messages in thread
From: Pavel Machek @ 2026-10-30 13:47 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: stable, patches, linux-kernel, torvalds, akpm, linux, shuah,
patches, lkft-triage, pavel, jonathanh, f.fainelli,
sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr
[-- Attachment #1: Type: text/plain, Size: 501 bytes --]
Hi!
> This is the start of the stable review cycle for the 7.2.15 release.
> There are 10 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
CIP testing did not find any problems here:
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-7.2.y
Tested-by: Pavel Machek (CIP) <pavel@nabladev.com>
Best regards,
Pavel
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 7.2 00/10] 7.2.15-rc1 review
2026-10-30 12:15 [PATCH 7.2 00/10] 7.2.15-rc1 review Greg Kroah-Hartman
` (12 preceding siblings ...)
2026-10-30 13:47 ` Pavel Machek
@ 2026-10-30 14:01 ` Miguel Ojeda
13 siblings, 0 replies; 18+ messages in thread
From: Miguel Ojeda @ 2026-10-30 14:01 UTC (permalink / raw)
To: gregkh
Cc: achill, akpm, broonie, conor, f.fainelli, hargar, jonathanh,
linux-kernel, linux, lkft-triage, patches, patches, pavel,
rwarsow, shuah, sr, stable, sudipm.mukherjee, torvalds,
Miguel Ojeda
On Fri, 30 Oct 2026 13:15:01 +0100 Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote:
>
> This is the start of the stable review cycle for the 7.2.15 release.
> There are 10 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Sun, 01 Nov 2026 12:12:50 +0000.
> Anything received after that time might be too late.
Boot-tested under QEMU for Rust x86_64, arm64 and riscv64; built-tested
for loongarch64 and arm32:
Tested-by: Miguel Ojeda <ojeda@kernel.org>
Thanks!
Cheers,
Miguel
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2026-10-30 14:02 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-30 12:15 [PATCH 7.2 00/10] 7.2.15-rc1 review Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 01/10] ksmbd: wait for negotiation before receiving another PDU Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 02/10] smb: smbdirect: dont wait for RDMA_CM_EVENT_DISCONNECTED in smbdirect_socket_destroy_sync() Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 03/10] smb: smbdirect: release failed pending sockets of a listener Greg Kroah-Hartman
2026-10-30 12:42 ` 이성현
2026-10-30 12:15 ` [PATCH 7.2 04/10] smb: smbdirect: dont hand out already failed sockets in smbdirect_socket_accept() Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 05/10] iio: hid-sensor: als: scale each channel individually Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 06/10] platform: cznic: turris-omnia-mcu: Add missing MODULE_DEVICE_TABLE() Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 07/10] kbuild: link-vmlinux.sh: improve detection of third pass requirement Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 08/10] exec: cancel io_uring requests before de_thread() Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 09/10] fork: move the coredump and exec checks into create_io_thread() Greg Kroah-Hartman
2026-10-30 12:15 ` [PATCH 7.2 10/10] fork: dont create io threads once PF_POSTCOREDUMP is set Greg Kroah-Hartman
2026-10-30 12:20 ` [PATCH 7.2 00/10] 7.2.15-rc1 review Peter Schneider
2026-10-30 12:51 ` Greg Kroah-Hartman
2026-10-30 12:58 ` Peter Schneider
2026-10-30 13:12 ` Brett A C Sheffield
2026-10-30 13:47 ` Pavel Machek
2026-10-30 14:01 ` Miguel Ojeda
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox