From: Stefan Metzmacher Date: Thu, 14 Aug 2025 13:50:05 +0000 (+0200) Subject: smb: server: take the recv_credit_target from the negotiate req and always limit... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=113ed9d56f63d2e4eb3d74002c3d91de1e7a3485;p=thirdparty%2Fkernel%2Fstable.git smb: server: take the recv_credit_target from the negotiate req and always limit the range The clients sends the initial recv_credit_target in the negotiate req, so we should use that. We also limit the range between 1 and our local defined sp->recv_credit_max. This will simplify further logic changes. Cc: Namjae Jeon Cc: Steve French Cc: Tom Talpey Cc: linux-cifs@vger.kernel.org Cc: samba-technical@lists.samba.org Signed-off-by: Stefan Metzmacher Acked-by: Namjae Jeon Signed-off-by: Steve French --- diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c index 33ce90b15de5..283f06cf4938 100644 --- a/fs/smb/server/transport_rdma.c +++ b/fs/smb/server/transport_rdma.c @@ -94,7 +94,7 @@ struct smb_direct_transport { spinlock_t receive_credit_lock; int recv_credits; - int recv_credit_target; + u16 recv_credit_target; spinlock_t lock_new_recv_credits; int new_recv_credits; @@ -515,7 +515,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) struct smbdirect_data_transfer *data_transfer = (struct smbdirect_data_transfer *)recvmsg->packet; u32 remaining_data_length, data_offset, data_length; - int old_recv_credit_target; + u16 old_recv_credit_target; if (wc->byte_len < offsetof(struct smbdirect_data_transfer, padding)) { @@ -559,6 +559,10 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) old_recv_credit_target = t->recv_credit_target; t->recv_credit_target = le16_to_cpu(data_transfer->credits_requested); + t->recv_credit_target = + min_t(u16, t->recv_credit_target, sp->recv_credit_max); + t->recv_credit_target = + max_t(u16, t->recv_credit_target, 1); atomic_add(le16_to_cpu(data_transfer->credits_granted), &sc->send_io.credits.count); @@ -1823,7 +1827,7 @@ static int smb_direct_init_params(struct smb_direct_transport *t, t->recv_credits = 0; sp->recv_credit_max = smb_direct_receive_credit_max; - t->recv_credit_target = 10; + t->recv_credit_target = 1; t->new_recv_credits = 0; sp->send_credit_target = smb_direct_send_credit_target; @@ -2049,6 +2053,9 @@ static int smb_direct_prepare(struct ksmbd_transport *t) le32_to_cpu(req->max_fragmented_size); sp->max_fragmented_recv_size = (sp->recv_credit_max * sp->max_recv_size) / 2; + st->recv_credit_target = le16_to_cpu(req->credits_requested); + st->recv_credit_target = min_t(u16, st->recv_credit_target, sp->recv_credit_max); + st->recv_credit_target = max_t(u16, st->recv_credit_target, 1); ret = smb_direct_send_negotiate_response(st, ret); out: