[PATCH 6.19 08/49] smb: smbdirect: introduce smbdirect_socket.send_io.bcredits.*

Greg Kroah-Hartman
2026-02-13T13:50:44Z

From: Stefan Metzmacher <metze@samba.org>

commit 8e94268b21c8235d430ce1aa6dc0b15952744b9b upstream.

It turns out that our code will corrupt the stream of
reassabled data transfer messages when we trigger an
immendiate (empty) send.

In order to fix this we'll have a single 'batch' credit per
connection. And code getting that credit is free to use
as much messages until remaining_length reaches 0, then
the batch credit it given back and the next logical send can
happen.

Cc: <stable@vger.kernel.org> # 6.18.x
Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/common/smbdirect/smbdirect_socket.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)

--- a/fs/smb/common/smbdirect/smbdirect_socket.h
+++ b/fs/smb/common/smbdirect/smbdirect_socket.h
@@ -163,6 +163,17 @@ struct smbdirect_socket {
} mem;

/*
+ * This is a coordination for smbdirect_send_batch.
+ *
+ * There's only one possible credit, which means
+ * only one instance is running at a time.
+ */
+ struct {
+ atomic_t count;
+ wait_queue_head_t wait_queue;
+ } bcredits;
+
+ /*
* The local credit state for ib_post_send()
*/
struct {
@@ -371,6 +382,9 @@ static __always_inline void smbdirect_so
INIT_DELAYED_WORK(&sc->idle.timer_work, __smbdirect_socket_disabled_work);
disable_delayed_work_sync(&sc->idle.timer_work);

+ atomic_set(&sc->send_io.bcredits.count, 0);
+ init_waitqueue_head(&sc->send_io.bcredits.wait_queue);
+
atomic_set(&sc->send_io.lcredits.count, 0);
init_waitqueue_head(&sc->send_io.lcredits.wait_queue);

@@ -485,6 +499,8 @@ struct smbdirect_send_batch {
*/
bool need_invalidate_rkey;
u32 remote_key;
+
+ int credit;
};

struct smbdirect_recv_io {