Skip to content

Commit 3dac422

Browse files
sprasad-microsoftpopcornmix
authored andcommitted
cifs: deal with the channel loading lag while picking channels
commit 66d590b upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent dfa9ae8 commit 3dac422

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
@@ -1029,14 +1029,16 @@ struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses)
10291029
uint index = 0;
10301030
unsigned int min_in_flight = UINT_MAX, max_in_flight = 0;
10311031
struct TCP_Server_Info *server = NULL;
1032-
int i;
1032+
int i, start, cur;
10331033

10341034
if (!ses)
10351035
return NULL;
10361036

10371037
spin_lock(&ses->chan_lock);
1038+
start = atomic_inc_return(&ses->chan_seq);
10381039
for (i = 0; i < ses->chan_count; i++) {
1039-
server = ses->chans[i].server;
1040+
cur = (start + i) % ses->chan_count;
1041+
server = ses->chans[cur].server;
10401042
if (!server || server->terminate)
10411043
continue;
10421044

@@ -1053,17 +1055,15 @@ struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses)
10531055
*/
10541056
if (server->in_flight < min_in_flight) {
10551057
min_in_flight = server->in_flight;
1056-
index = i;
1058+
index = cur;
10571059
}
10581060
if (server->in_flight > max_in_flight)
10591061
max_in_flight = server->in_flight;
10601062
}
10611063

10621064
/* if all channels are equally loaded, fall back to round-robin */
1063-
if (min_in_flight == max_in_flight) {
1064-
index = (uint)atomic_inc_return(&ses->chan_seq);
1065-
index %= ses->chan_count;
1066-
}
1065+
if (min_in_flight == max_in_flight)
1066+
index = (uint)start % ses->chan_count;
10671067

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

0 commit comments

Comments
 (0)