From: "Aurélien Aptel" <aaptel@suse.com>
To: linux-cifs@vger.kernel.org
Cc: smfrench@gmail.com, Aurelien Aptel <aaptel@suse.com>
Subject: [PATCH] cifs: try to pick channel with a minimum of credits
Date: Fri, 5 Mar 2021 15:24:07 +0100 [thread overview]
Message-ID: <20210305142407.23652-1-aaptel@suse.com> (raw)
From: Aurelien Aptel <aaptel@suse.com>
Check channel credits to prevent the client from using a starved
channel that cannot send anything.
Special care must be taken in selecting the minimum value: when
channels are created they start off with a small amount that slowly
ramps up as the channel gets used. Thus a new channel might never be
picked if the min value is too small.
Signed-off-by: Aurelien Aptel <aaptel@suse.com>
---
fs/cifs/transport.c | 57 ++++++++++++++++++++++++++++++++++++++-------
1 file changed, 49 insertions(+), 8 deletions(-)
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index e90a1d1380b0..7bb1584b3724 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -44,6 +44,14 @@
/* Max number of iovectors we can use off the stack when sending requests. */
#define CIFS_MAX_IOV_SIZE 8
+/*
+ * Min number of credits for a channel to be picked.
+ *
+ * Note that once a channel reaches this threshold it will never be
+ * picked again as no credits can be requested from it.
+ */
+#define CIFS_CHANNEL_MIN_CREDITS 3
+
void
cifs_wake_up_task(struct mid_q_entry *mid)
{
@@ -1051,20 +1059,53 @@ cifs_cancelled_callback(struct mid_q_entry *mid)
struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses)
{
uint index = 0;
+ struct TCP_Server_Info *s;
if (!ses)
return NULL;
- if (!ses->binding) {
- /* round robin */
- if (ses->chan_count > 1) {
- index = (uint)atomic_inc_return(&ses->chan_seq);
- index %= ses->chan_count;
- }
- return ses->chans[index].server;
- } else {
+ if (ses->binding)
return cifs_ses_server(ses);
+
+ /*
+ * Channels are created right after the session is made. The
+ * count cannot change after that so it is not racy to check.
+ */
+ if (ses->chan_count == 1)
+ return ses->chans[index].server;
+
+ /* round robin */
+ index = (uint)atomic_inc_return(&ses->chan_seq);
+ index %= ses->chan_count;
+ s = ses->chans[index].server;
+
+ /*
+ * Checking server credits is racy, but getting a slightly
+ * stale value should not be an issue here
+ */
+ if (s->credits <= CIFS_CHANNEL_MIN_CREDITS) {
+ uint i;
+
+ cifs_dbg(VFS, "cannot pick conn_id=0x%llx not enough credits (%u)",
+ s->conn_id,
+ s->credits);
+
+ /*
+ * Look at all other channels starting from the next
+ * one and pick first possible channel.
+ */
+ for (i = 1; i < ses->chan_count; i++) {
+ s = ses->chans[(index+i) % ses->chan_count].server;
+ if (s->credits > CIFS_CHANNEL_MIN_CREDITS)
+ return s;
+ }
}
+
+ /*
+ * If none are possible, keep the initially picked one, but
+ * later on it will block to wait for credits or fail.
+ */
+ return ses->chans[index].server;
}
int
--
2.30.0
next reply other threads:[~2021-03-05 14:25 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-05 14:24 Aurélien Aptel [this message]
2021-03-05 16:08 ` [PATCH] cifs: try to pick channel with a minimum of credits Steve French
2021-03-07 3:14 ` Shyam Prasad N
2021-03-08 11:52 ` Aurélien Aptel
2021-03-08 16:58 ` Aurélien Aptel
2021-03-11 10:49 ` Shyam Prasad N
2021-03-11 13:31 ` Shyam Prasad N
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210305142407.23652-1-aaptel@suse.com \
--to=aaptel@suse.com \
--cc=linux-cifs@vger.kernel.org \
--cc=smfrench@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox