]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
smb: client: count the number of posted recv_io messages in order to calculated credits
authorStefan Metzmacher <metze@samba.org>
Thu, 14 Aug 2025 11:57:37 +0000 (13:57 +0200)
committerSteve French <stfrench@microsoft.com>
Sun, 28 Sep 2025 23:29:49 +0000 (18:29 -0500)
(At least for me) the logic maintaining the count of posted
recv_io messages and the count of granted credits is much easier
to understand.

From there we can easily calculate the number of new_credits we'll
grant to the peer in outgoing send_io messages.

This will simplify the move to common logic that can be
shared between client and server in the following patches.

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>
fs/smb/client/smbdirect.c
fs/smb/client/smbdirect.h

index 92d4d75dc38d13db973254eaa782aac118c5b22f..6332230ad4cab435526e506e3bf2d23bcb6a874d 100644 (file)
@@ -492,6 +492,7 @@ static bool process_negotiation_response(
        atomic_set(&sc->send_io.credits.count, le16_to_cpu(packet->credits_granted));
 
        atomic_set(&info->receive_credits, 0);
+       atomic_set(&info->receive_posted, 0);
 
        if (le32_to_cpu(packet->preferred_send_size) > sp->max_recv_size) {
                log_rdma_event(ERR, "error: preferred_send_size=%d\n",
@@ -533,7 +534,6 @@ static bool process_negotiation_response(
 
 static void smbd_post_send_credits(struct work_struct *work)
 {
-       int ret = 0;
        int rc;
        struct smbdirect_recv_io *response;
        struct smbd_connection *info =
@@ -561,14 +561,10 @@ static void smbd_post_send_credits(struct work_struct *work)
                                break;
                        }
 
-                       ret++;
+                       atomic_inc(&info->receive_posted);
                }
        }
 
-       spin_lock(&info->lock_new_credits_offered);
-       info->new_credits_offered += ret;
-       spin_unlock(&info->lock_new_credits_offered);
-
        /* Promptly send an immediate packet as defined in [MS-SMBD] 3.1.1.1 */
        info->send_immediate = true;
        if (atomic_read(&info->receive_credits) <
@@ -665,6 +661,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
                                sc->recv_io.reassembly.full_packet_received = true;
                }
 
+               atomic_dec(&info->receive_posted);
                atomic_dec(&info->receive_credits);
                old_recv_credit_target = info->receive_credit_target;
                info->receive_credit_target =
@@ -965,10 +962,16 @@ static int manage_credits_prior_sending(struct smbd_connection *info)
 {
        int new_credits;
 
-       spin_lock(&info->lock_new_credits_offered);
-       new_credits = info->new_credits_offered;
-       info->new_credits_offered = 0;
-       spin_unlock(&info->lock_new_credits_offered);
+       if (atomic_read(&info->receive_credits) >= info->receive_credit_target)
+               return 0;
+
+       new_credits = atomic_read(&info->receive_posted);
+       if (new_credits == 0)
+               return 0;
+
+       new_credits -= atomic_read(&info->receive_credits);
+       if (new_credits <= 0)
+               return 0;
 
        return new_credits;
 }
@@ -1177,10 +1180,7 @@ err_dma:
                                            DMA_TO_DEVICE);
        mempool_free(request, sc->send_io.mem.pool);
 
-       /* roll back receive credits and credits to be offered */
-       spin_lock(&info->lock_new_credits_offered);
-       info->new_credits_offered += new_credits;
-       spin_unlock(&info->lock_new_credits_offered);
+       /* roll back the granted receive credits */
        atomic_sub(new_credits, &info->receive_credits);
 
 err_alloc:
@@ -1866,8 +1866,6 @@ static struct smbd_connection *_smbd_get_connection(
                msecs_to_jiffies(sp->keepalive_interval_msec));
 
        INIT_WORK(&info->post_send_credits_work, smbd_post_send_credits);
-       info->new_credits_offered = 0;
-       spin_lock_init(&info->lock_new_credits_offered);
 
        rc = smbd_negotiate(info);
        if (rc) {
index d5ccb92fb618bbf0c4cfdecb02b1c950a5cc420d..a10f69fab5734136b0d12c111c5fdf78a4dfeca6 100644 (file)
@@ -46,9 +46,7 @@ struct smbd_connection {
        struct smbdirect_socket socket;
 
        struct work_struct post_send_credits_work;
-
-       spinlock_t lock_new_credits_offered;
-       int new_credits_offered;
+       atomic_t receive_posted;
 
        /* dynamic connection parameters defined in [MS-SMBD] 3.1.1.1 */
        enum keep_alive_status keep_alive_requested;