Skip to content

Commit ea90708

Browse files
sprasad-microsoftsmfrench
authored andcommitted
cifs: use the least loaded channel for sending requests
Till now, we've used a simple round robin approach to distribute the requests between the channels. This does not work well if the channels consume the requests at different speeds, even if the advertised speeds are the same. This change will allow the client to pick the channel with least number of requests currently in-flight. This will disregard the link speed, and select a channel based on the current load of the channels. For cases when all the channels are equally loaded, fall back to the old round robin method. Signed-off-by: Shyam Prasad N <[email protected]> Reviewed-by: Paulo Alcantara (SUSE) <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent e7388b8 commit ea90708

File tree

1 file changed

+29
-4
lines changed

1 file changed

+29
-4
lines changed

fs/cifs/transport.c

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,15 +1007,40 @@ cifs_cancelled_callback(struct mid_q_entry *mid)
10071007
struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses)
10081008
{
10091009
uint index = 0;
1010+
unsigned int min_in_flight = UINT_MAX, max_in_flight = 0;
1011+
struct TCP_Server_Info *server = NULL;
1012+
int i;
10101013

10111014
if (!ses)
10121015
return NULL;
10131016

1014-
/* round robin */
1015-
index = (uint)atomic_inc_return(&ses->chan_seq);
1016-
10171017
spin_lock(&ses->chan_lock);
1018-
index %= ses->chan_count;
1018+
for (i = 0; i < ses->chan_count; i++) {
1019+
server = ses->chans[i].server;
1020+
if (!server)
1021+
continue;
1022+
1023+
/*
1024+
* strictly speaking, we should pick up req_lock to read
1025+
* server->in_flight. But it shouldn't matter much here if we
1026+
* race while reading this data. The worst that can happen is
1027+
* that we could use a channel that's not least loaded. Avoiding
1028+
* taking the lock could help reduce wait time, which is
1029+
* important for this function
1030+
*/
1031+
if (server->in_flight < min_in_flight) {
1032+
min_in_flight = server->in_flight;
1033+
index = i;
1034+
}
1035+
if (server->in_flight > max_in_flight)
1036+
max_in_flight = server->in_flight;
1037+
}
1038+
1039+
/* if all channels are equally loaded, fall back to round-robin */
1040+
if (min_in_flight == max_in_flight) {
1041+
index = (uint)atomic_inc_return(&ses->chan_seq);
1042+
index %= ses->chan_count;
1043+
}
10191044
spin_unlock(&ses->chan_lock);
10201045

10211046
return ses->chans[index].server;

0 commit comments

Comments
 (0)