mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
cifs: reset iface weights when we cannot find a candidate
commit 9d5eff7821f6d70f7d1b4d8a60680fba4de868a7 upstream.
We now do a weighted selection of server interfaces when allocating
new channels. The weights are decided based on the speed advertised.
The fulfilled weight for an interface is a counter that is used to
track the interface selection. It should be reset back to zero once
all interfaces fulfilling their weight.
In cifs_chan_update_iface, this reset logic was missing. As a result
when the server interface list changes, the client may not be able
to find a new candidate for other channels after all interfaces have
been fulfilled.
Fixes: a6d8fb54a515 ("cifs: distribute channels across interfaces based on speed")
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>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
1b6310d14b
commit
7e0c0664e9
@@ -372,6 +372,7 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)
|
||||
struct cifs_server_iface *old_iface = NULL;
|
||||
struct cifs_server_iface *last_iface = NULL;
|
||||
struct sockaddr_storage ss;
|
||||
int retry = 0;
|
||||
|
||||
spin_lock(&ses->chan_lock);
|
||||
chan_index = cifs_ses_get_chan_index(ses, server);
|
||||
@@ -400,6 +401,7 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)
|
||||
return;
|
||||
}
|
||||
|
||||
try_again:
|
||||
last_iface = list_last_entry(&ses->iface_list, struct cifs_server_iface,
|
||||
iface_head);
|
||||
iface_min_speed = last_iface->speed;
|
||||
@@ -437,6 +439,13 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)
|
||||
}
|
||||
|
||||
if (list_entry_is_head(iface, &ses->iface_list, iface_head)) {
|
||||
list_for_each_entry(iface, &ses->iface_list, iface_head)
|
||||
iface->weight_fulfilled = 0;
|
||||
|
||||
/* see if it can be satisfied in second attempt */
|
||||
if (!retry++)
|
||||
goto try_again;
|
||||
|
||||
iface = NULL;
|
||||
cifs_dbg(FYI, "unable to find a suitable iface\n");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user