diff options
| author | Stefan Metzmacher <metze@samba.org> | 2026-01-22 20:16:49 +0300 |
|---|---|---|
| committer | Steve French <stfrench@microsoft.com> | 2026-02-09 02:12:57 +0300 |
| commit | defb3c05fee94b296eebe05aaea16d2664b00252 (patch) | |
| tree | 2c9e5dfff4b56390d2dea726313756f16ac38ae7 | |
| parent | 9911b1ed187a770a43950bf51f340ad4b7beecba (diff) | |
| download | linux-defb3c05fee94b296eebe05aaea16d2664b00252.tar.xz | |
smb: client: let recv_done() queue a refill when the peer is low on credits
In captures I saw that Windows was granting 191 credits in a batch
when its peer posted a lot of messages. We are asking for a
credit target of 255 and 191 is 252*3/4.
So we also use that logic in order to fill the
recv buffers available to the peer.
Fixes: 02548c477a90 ("smb: client: queue post_recv_credits_work also if the peer raises the credit target")
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>
Signed-off-by: Steve French <stfrench@microsoft.com>
| -rw-r--r-- | fs/smb/client/smbdirect.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c index 6679abbb9797..61693b4a83fc 100644 --- a/fs/smb/client/smbdirect.c +++ b/fs/smb/client/smbdirect.c @@ -663,6 +663,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) container_of(wc->wr_cqe, struct smbdirect_recv_io, cqe); struct smbdirect_socket *sc = response->socket; struct smbdirect_socket_parameters *sp = &sc->parameters; + int current_recv_credits; u16 old_recv_credit_target; u32 data_offset = 0; u32 data_length = 0; @@ -747,7 +748,8 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) } atomic_dec(&sc->recv_io.posted.count); - atomic_dec(&sc->recv_io.credits.count); + current_recv_credits = atomic_dec_return(&sc->recv_io.credits.count); + old_recv_credit_target = sc->recv_io.credits.target; sc->recv_io.credits.target = le16_to_cpu(data_transfer->credits_requested); @@ -783,7 +785,8 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) * reassembly queue and wake up the reading thread */ if (data_length) { - if (sc->recv_io.credits.target > old_recv_credit_target) + if (current_recv_credits <= (sc->recv_io.credits.target / 4) || + sc->recv_io.credits.target > old_recv_credit_target) queue_work(sc->workqueue, &sc->recv_io.posted.refill_work); enqueue_reassembly(sc, response, data_length); |
