mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-22 07:27:12 +08:00
smb: client: fix cifs_pick_channel when channels are equally loaded
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>
This commit is contained in:
committed by
Steve French
parent
6de23f81a5
commit
663c28469d
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user