There were cases reported where servers will sometimes return more credits than requested on oplock break responses, which can lead to most of the credits being allocated for oplock breaks (instead of for normal operations like read and write) if number of SMB3 requests in flight always stays above 0 (the oplock and echo credits are rebalanced when in flight requests goes down to zero). If oplock credits gets unexpectedly large (e.g. ten is more than it would ever be expected to be) and in flight requests are greater than zero, then rebalance the oplock credits and regular credits (go back to reserving just one oplock credit. See attached -- Thanks, Steve
From c50cae15903fc704c3df1170183c8505cd2eb0b9 Mon Sep 17 00:00:00 2001 From: Steve French <stfrench@xxxxxxxxxxxxx> Date: Mon, 19 Jun 2023 22:32:38 -0500 Subject: [PATCH] smb3: do not reserve too many oplock credits There were cases reported where servers will sometimes return more credits than requested on oplock break responses, which can lead to most of the credits being allocated for oplock breaks (instead of for normal operations like read and write) if number of SMB3 requests in flight always stays above 0 (the oplock and echo credits are rebalanced when in flight requests goes down to zero). If oplock credits gets unexpectedly large (e.g. ten is more than it would ever be expected to be) and in flight requests are greater than zero, then rebalance the oplock credits and regular credits (go back to reserving just one oplock crdit). Signed-off-by: Steve French <stfrench@xxxxxxxxxxxxx> --- fs/smb/client/smb2ops.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index a8bb9d00d33a..02780f175571 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -109,7 +109,11 @@ smb2_add_credits(struct TCP_Server_Info *server, server->credits--; server->oplock_credits++; } - } + } else if ((server->in_flight > 0) && (server->oplock_credits > 10) && + ((optype & CIFS_OP_MASK) == CIFS_OBREAK_OP)) + /* if now have too many oplock credits, rebalance so don't starve normal ops */ + change_conf(server); + scredits = *val; in_flight = server->in_flight; spin_unlock(&server->req_lock); -- 2.34.1