Skip to content

Commit 2670047

Browse files
sprasad-microsoftjohn-cabaj
authored andcommitted
cifs: deal with the channel loading lag while picking channels
BugLink: https://bugs.launchpad.net/bugs/2118807 Our current approach to select a channel for sending requests is this: 1. iterate all channels to find the min and max queue depth 2. if min and max are not the same, pick the channel with min depth 3. if min and max are same, round robin, as all channels are equally loaded The problem with this approach is that there's a lag between selecting a channel and sending the request (that increases the queue depth on the channel). While these numbers will eventually catch up, there could be a skew in the channel usage, depending on the application's I/O parallelism and the server's speed of handling requests. With sufficient parallelism, this lag can artificially increase the queue depth, thereby impacting the performance negatively. This change will change the step 1 above to start the iteration from the last selected channel. This is to reduce the skew in channel usage even in the presence of this lag. Fixes: ea90708 ("cifs: use the least loaded channel for sending requests") Cc: <stable@vger.kernel.org> Signed-off-by: Shyam Prasad N <sprasad@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com> (cherry picked from commit 66d590b828b1fd9fa337047ae58fe1c4c6f43609) Signed-off-by: Vinicius Peixoto <vinicius.peixoto@canonical.com> Acked-by: Manuel Diewald <manuel.diewald@canonical.com> Acked-by: Alessio Faina <alessio.faina@canonical.com> Signed-off-by: Vinicius Peixoto <vinicius.peixoto@canonical.com>
1 parent 90e2284 commit 2670047

File tree

1 file changed

+7
-7
lines changed

1 file changed

+7
-7
lines changed

fs/smb/client/transport.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,14 +1015,16 @@ struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses)
10151015
uint index = 0;
10161016
unsigned int min_in_flight = UINT_MAX, max_in_flight = 0;
10171017
struct TCP_Server_Info *server = NULL;
1018-
int i;
1018+
int i, start, cur;
10191019

10201020
if (!ses)
10211021
return NULL;
10221022

10231023
spin_lock(&ses->chan_lock);
1024+
start = atomic_inc_return(&ses->chan_seq);
10241025
for (i = 0; i < ses->chan_count; i++) {
1025-
server = ses->chans[i].server;
1026+
cur = (start + i) % ses->chan_count;
1027+
server = ses->chans[cur].server;
10261028
if (!server || server->terminate)
10271029
continue;
10281030

@@ -1039,17 +1041,15 @@ struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses)
10391041
*/
10401042
if (server->in_flight < min_in_flight) {
10411043
min_in_flight = server->in_flight;
1042-
index = i;
1044+
index = cur;
10431045
}
10441046
if (server->in_flight > max_in_flight)
10451047
max_in_flight = server->in_flight;
10461048
}
10471049

10481050
/* if all channels are equally loaded, fall back to round-robin */
1049-
if (min_in_flight == max_in_flight) {
1050-
index = (uint)atomic_inc_return(&ses->chan_seq);
1051-
index %= ses->chan_count;
1052-
}
1051+
if (min_in_flight == max_in_flight)
1052+
index = (uint)start % ses->chan_count;
10531053

10541054
server = ses->chans[index].server;
10551055
spin_unlock(&ses->chan_lock);

0 commit comments

Comments
 (0)