]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
smb: client: fix cifs_pick_channel when channels are equally loaded
authorHenrique Carvalho <henrique.carvalho@suse.com>
Sat, 21 Feb 2026 04:59:44 +0000 (01:59 -0300)
committerSteve French <stfrench@microsoft.com>
Sun, 22 Feb 2026 22:52:50 +0000 (16:52 -0600)
cifs_pick_channel uses (start % chan_count) when channels are equally
loaded, but that can return a channel that failed the eligibility
checks.

Drop the fallback and return the scan-selected channel instead. If none
is eligible, keep the existing behavior of using the primary channel.

Signed-off-by: Henrique Carvalho <henrique.carvalho@suse.com>
Acked-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
Acked-by: Meetakshi Setiya <msetiya@microsoft.com>
Reviewed-by: Shyam Prasad N <sprasad@microsoft.com>
Cc: stable@vger.kernel.org
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/transport.c

index 75697f6d2566e91c80397a295eaa53bf6c724ed7..05f8099047e1a423a12a1cea2eaec009d9dd050d 100644 (file)
@@ -807,16 +807,21 @@ cifs_cancelled_callback(struct TCP_Server_Info *server, struct mid_q_entry *mid)
 }
 
 /*
- * Return a channel (master if none) of @ses that can be used to send
- * regular requests.
+ * cifs_pick_channel - pick an eligible channel for network operations
  *
- * If we are currently binding a new channel (negprot/sess.setup),
- * return the new incomplete channel.
+ * @ses: session reference
+ *
+ * Select an eligible channel (not terminating and not marked as needing
+ * reconnect), preferring the least loaded one. If no eligible channel is
+ * found, fall back to the primary channel (index 0).
+ *
+ * Return: TCP_Server_Info pointer for the chosen channel, or NULL if @ses is
+ * NULL.
  */
 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;
+       unsigned int min_in_flight = UINT_MAX;
        struct TCP_Server_Info *server = NULL;
        int i, start, cur;
 
@@ -846,14 +851,8 @@ struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses)
                        min_in_flight = server->in_flight;
                        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)start % ses->chan_count;
-
        server = ses->chans[index].server;
        spin_unlock(&ses->chan_lock);