]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
smb: client: queue post_recv_credits_work also if the peer raises the credit target
authorStefan Metzmacher <metze@samba.org>
Mon, 11 Aug 2025 15:53:55 +0000 (17:53 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Oct 2025 13:10:17 +0000 (14:10 +0100)
[ Upstream commit 02548c477a90481c1fd0d6e7c84b4504ec2fcc12 ]

This is already handled in the server, but currently it done
in a very complex way there. So we do it much simpler.

Note that put_receive_buffer() will take care of it
in case data_length is 0.

Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/smb/client/smbdirect.c

index 6480945c24592325988ecf098a36c1b183afccd6..b3e04b410afe6cde5ae97364fdb6124255c5728c 100644 (file)
@@ -537,6 +537,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
        struct smbdirect_socket_parameters *sp = &sc->parameters;
        struct smbd_connection *info =
                container_of(sc, struct smbd_connection, socket);
+       int old_recv_credit_target;
        u32 data_offset = 0;
        u32 data_length = 0;
        u32 remaining_data_length = 0;
@@ -599,6 +600,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
                }
 
                atomic_dec(&info->receive_credits);
+               old_recv_credit_target = info->receive_credit_target;
                info->receive_credit_target =
                        le16_to_cpu(data_transfer->credits_requested);
                if (le16_to_cpu(data_transfer->credits_granted)) {
@@ -629,6 +631,9 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
                 * reassembly queue and wake up the reading thread
                 */
                if (data_length) {
+                       if (info->receive_credit_target > old_recv_credit_target)
+                               queue_work(info->workqueue, &info->post_send_credits_work);
+
                        enqueue_reassembly(info, response, data_length);
                        wake_up_interruptible(&sc->recv_io.reassembly.wait_queue);
                } else