Merged all six of these multichannel fixes into cifs-2.6.git for-next pending additional testing and any review comments but these three in particular looked most obvious/safe:
b4f60a053a25 cifs: dns resolution is needed only for primary channel c1846893991f cifs: update dstaddr whenever channel iface is updated 1f396b9bfe39 cifs: reset connections for all channels when reconnect requested
I want to look more carefully especially at these three: 2f2c5d38fb9d (HEAD -> for-next, origin/for-next) cifs: do not disable interface polling on failure 4394c936623d cifs: serialize other channels when query server interfaces is pending bf75ad3631c7 cifs: deal with the channel loading lag while picking channels
On Mon, Jun 2, 2025 at 12:09 PM nspmangalore@gmail.com wrote:
From: Shyam Prasad N sprasad@microsoft.com
Our current approach to select a channel for sending requests is this:
- iterate all channels to find the min and max queue depth
- if min and max are not the same, pick the channel with min depth
- 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: ea90708d3cf3 ("cifs: use the least loaded channel for sending requests") Cc: stable@vger.kernel.org Signed-off-by: Shyam Prasad N sprasad@microsoft.com
fs/smb/client/transport.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c index 266af17aa7d9..191783f553ce 100644 --- a/fs/smb/client/transport.c +++ b/fs/smb/client/transport.c @@ -1018,14 +1018,16 @@ struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses) uint index = 0; unsigned int min_in_flight = UINT_MAX, max_in_flight = 0; struct TCP_Server_Info *server = NULL;
int i;
int i, start, cur; if (!ses) return NULL; spin_lock(&ses->chan_lock);
start = atomic_inc_return(&ses->chan_seq); for (i = 0; i < ses->chan_count; i++) {
server = ses->chans[i].server;
cur = (start + i) % ses->chan_count;
server = ses->chans[cur].server; if (!server || server->terminate) continue;
@@ -1042,17 +1044,15 @@ struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses) */ if (server->in_flight < min_in_flight) { min_in_flight = server->in_flight;
index = i;
index = cur; } if (server->in_flight > max_in_flight) max_in_flight = server->in_flight; } /* if all channels are equally loaded, fall back to round-robin */
if (min_in_flight == max_in_flight) {
index = (uint)atomic_inc_return(&ses->chan_seq);
index %= ses->chan_count;
}
if (min_in_flight == max_in_flight)
index = (uint)start % ses->chan_count; server = ses->chans[index].server; spin_unlock(&ses->chan_lock);
-- 2.43.0