]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
smb: smbdirect: introduce smbdirect_socket.send_io.bcredits.*
authorStefan Metzmacher <metze@samba.org>
Thu, 22 Jan 2026 17:16:42 +0000 (18:16 +0100)
committerSteve French <stfrench@microsoft.com>
Sun, 8 Feb 2026 23:12:57 +0000 (17:12 -0600)
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>
fs/smb/common/smbdirect/smbdirect_socket.h

index 403a8b2cd30e4ac096880169a5a9b5862d030cab..95265192bb01b2fb5c368b28751970338703fbf7 100644 (file)
@@ -162,6 +162,17 @@ struct smbdirect_socket {
                        mempool_t               *pool;
                } 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()
                 */
@@ -371,6 +382,9 @@ static __always_inline void smbdirect_socket_init(struct smbdirect_socket *sc)
        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 {