Skip to content

Commit 26ad87a

Browse files
metze-sambasmfrench
authored andcommitted
smb: server: make use of smbdirect_socket.recv_io.credits.available
The logic off managing recv credits by counting posted recv_io and granted credits is racy. That's because the peer might already consumed a credit, but between receiving the incoming recv at the hardware and processing the completion in the 'recv_done' functions we likely have a window where we grant credits, which don't really exist. So we better have a decicated counter for the available credits, which will be incremented when we posted new recv buffers and drained when we grant the credits to the peer. This fixes regression Namjae reported with the 6.18 release. Fixes: 89b021a ("smb: server: manage recv credits by counting posted recv_io and granted credits") Cc: <stable@vger.kernel.org> # 6.18.x 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>
1 parent 8e94268 commit 26ad87a

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

fs/smb/server/transport_rdma.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,6 +1028,8 @@ static void smb_direct_post_recv_credits(struct work_struct *work)
10281028
}
10291029
}
10301030

1031+
atomic_add(credits, &sc->recv_io.credits.available);
1032+
10311033
if (credits)
10321034
queue_work(sc->workqueue, &sc->idle.immediate_work);
10331035
}
@@ -1074,19 +1076,37 @@ static void send_done(struct ib_cq *cq, struct ib_wc *wc)
10741076

10751077
static int manage_credits_prior_sending(struct smbdirect_socket *sc)
10761078
{
1079+
int missing;
1080+
int available;
10771081
int new_credits;
10781082

10791083
if (atomic_read(&sc->recv_io.credits.count) >= sc->recv_io.credits.target)
10801084
return 0;
10811085

1082-
new_credits = atomic_read(&sc->recv_io.posted.count);
1083-
if (new_credits == 0)
1086+
missing = (int)sc->recv_io.credits.target - atomic_read(&sc->recv_io.credits.count);
1087+
available = atomic_xchg(&sc->recv_io.credits.available, 0);
1088+
new_credits = (u16)min3(U16_MAX, missing, available);
1089+
if (new_credits <= 0) {
1090+
/*
1091+
* If credits are available, but not granted
1092+
* we need to re-add them again.
1093+
*/
1094+
if (available)
1095+
atomic_add(available, &sc->recv_io.credits.available);
10841096
return 0;
1097+
}
10851098

1086-
new_credits -= atomic_read(&sc->recv_io.credits.count);
1087-
if (new_credits <= 0)
1088-
return 0;
1099+
if (new_credits < available) {
1100+
/*
1101+
* Readd the remaining available again.
1102+
*/
1103+
available -= new_credits;
1104+
atomic_add(available, &sc->recv_io.credits.available);
1105+
}
10891106

1107+
/*
1108+
* Remember we granted the credits
1109+
*/
10901110
atomic_add(new_credits, &sc->recv_io.credits.count);
10911111
return new_credits;
10921112
}

0 commit comments

Comments
 (0)