aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2025-08-14 16:05:47 +0200
committerSteve French <stfrench@microsoft.com>2025-09-28 18:29:52 -0500
commit89b021a72663c4d96d8a8b85272bb42d991a1c6f (patch)
tree4d13fd3b9c77c0aa3a8672233a6e2cfeff0d7495
parentsmb: server: take the recv_credit_target from the negotiate req and always li... (diff)
downloadlinux-89b021a72663c4d96d8a8b85272bb42d991a1c6f.tar.gz
linux-89b021a72663c4d96d8a8b85272bb42d991a1c6f.zip
smb: server: manage recv credits by counting posted recv_io and granted credits
(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: Namjae Jeon <linkinjeon@kernel.org> Cc: Steve French <smfrench@gmail.com> Cc: Tom Talpey <tom@talpey.com> 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>
-rw-r--r--fs/smb/server/transport_rdma.c53
1 files changed, 21 insertions, 32 deletions
diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c
index 283f06cf4938..bd6d927e9656 100644
--- a/fs/smb/server/transport_rdma.c
+++ b/fs/smb/server/transport_rdma.c
@@ -92,13 +92,10 @@ struct smb_direct_transport {
struct smbdirect_socket socket;
- spinlock_t receive_credit_lock;
- int recv_credits;
+ atomic_t recv_credits;
u16 recv_credit_target;
- spinlock_t lock_new_recv_credits;
- int new_recv_credits;
-
+ atomic_t recv_posted;
struct work_struct post_recv_credits_work;
struct work_struct send_immediate_work;
@@ -309,9 +306,8 @@ static struct smb_direct_transport *alloc_transport(struct rdma_cm_id *cm_id)
sc->ib.dev = sc->rdma.cm_id->device;
- spin_lock_init(&t->receive_credit_lock);
-
- spin_lock_init(&t->lock_new_recv_credits);
+ atomic_set(&t->recv_posted, 0);
+ atomic_set(&t->recv_credits, 0);
INIT_WORK(&t->post_recv_credits_work,
smb_direct_post_recv_credits);
@@ -552,9 +548,8 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
sc->recv_io.reassembly.full_packet_received = true;
}
- spin_lock(&t->receive_credit_lock);
- t->recv_credits -= 1;
- spin_unlock(&t->receive_credit_lock);
+ atomic_dec(&t->recv_posted);
+ atomic_dec(&t->recv_credits);
old_recv_credit_target = t->recv_credit_target;
t->recv_credit_target =
@@ -758,14 +753,10 @@ static void smb_direct_post_recv_credits(struct work_struct *work)
struct smb_direct_transport *t = container_of(work,
struct smb_direct_transport, post_recv_credits_work);
struct smbdirect_recv_io *recvmsg;
- int receive_credits, credits = 0;
+ int credits = 0;
int ret;
- spin_lock(&t->receive_credit_lock);
- receive_credits = t->recv_credits;
- spin_unlock(&t->receive_credit_lock);
-
- if (receive_credits < t->recv_credit_target) {
+ if (atomic_read(&t->recv_credits) < t->recv_credit_target) {
while (true) {
recvmsg = get_free_recvmsg(t);
if (!recvmsg)
@@ -780,17 +771,11 @@ static void smb_direct_post_recv_credits(struct work_struct *work)
break;
}
credits++;
+
+ atomic_inc(&t->recv_posted);
}
}
- spin_lock(&t->receive_credit_lock);
- t->recv_credits += credits;
- spin_unlock(&t->receive_credit_lock);
-
- spin_lock(&t->lock_new_recv_credits);
- t->new_recv_credits += credits;
- spin_unlock(&t->lock_new_recv_credits);
-
if (credits)
queue_work(smb_direct_wq, &t->send_immediate_work);
}
@@ -837,11 +822,18 @@ static int manage_credits_prior_sending(struct smb_direct_transport *t)
{
int new_credits;
- spin_lock(&t->lock_new_recv_credits);
- new_credits = t->new_recv_credits;
- t->new_recv_credits = 0;
- spin_unlock(&t->lock_new_recv_credits);
+ if (atomic_read(&t->recv_credits) >= t->recv_credit_target)
+ return 0;
+
+ new_credits = atomic_read(&t->recv_posted);
+ if (new_credits == 0)
+ return 0;
+ new_credits -= atomic_read(&t->recv_credits);
+ if (new_credits <= 0)
+ return 0;
+
+ atomic_add(new_credits, &t->recv_credits);
return new_credits;
}
@@ -1824,11 +1816,8 @@ static int smb_direct_init_params(struct smb_direct_transport *t,
return -EINVAL;
}
- t->recv_credits = 0;
-
sp->recv_credit_max = smb_direct_receive_credit_max;
t->recv_credit_target = 1;
- t->new_recv_credits = 0;
sp->send_credit_target = smb_direct_send_credit_target;
atomic_set(&sc->rw_io.credits.count, sc->rw_io.credits.max);