Linux CIFS filesystem development
 help / color / mirror / Atom feed
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


             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