Skip to content

Commit a7504d4

Browse files
committed
cifs: distribute channels across interfaces based on speed
jira LE-4669 Rebuild_History Non-Buildable kernel-4.18.0-553.82.1.el8_10 commit-author Shyam Prasad N <sprasad@microsoft.com> commit a6d8fb5 Empty-Commit: Cherry-Pick Conflicts during history rebuild. Will be included in final tarball splat. Ref for failed cherry-pick at: ciq/ciq_backports/kernel-4.18.0-553.82.1.el8_10/a6d8fb54.failed Today, if the server interfaces RSS capable, we simply choose the fastest interface to setup a channel. This is not a scalable approach, and does not make a lot of attempt to distribute the connections. This change does a weighted distribution of channels across all the available server interfaces, where the weight is a function of the advertised interface speed. Also make sure that we don't mix rdma and non-rdma for channels. Signed-off-by: Shyam Prasad N <sprasad@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com> (cherry picked from commit a6d8fb5) Signed-off-by: Jonathan Maple <jmaple@ciq.com> # Conflicts: # fs/cifs/sess.c
1 parent 8bc9f08 commit a7504d4

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
cifs: distribute channels across interfaces based on speed
2+
3+
jira LE-4669
4+
Rebuild_History Non-Buildable kernel-4.18.0-553.82.1.el8_10
5+
commit-author Shyam Prasad N <sprasad@microsoft.com>
6+
commit a6d8fb54a515f0546ffdb7870102b1238917e567
7+
Empty-Commit: Cherry-Pick Conflicts during history rebuild.
8+
Will be included in final tarball splat. Ref for failed cherry-pick at:
9+
ciq/ciq_backports/kernel-4.18.0-553.82.1.el8_10/a6d8fb54.failed
10+
11+
Today, if the server interfaces RSS capable, we simply
12+
choose the fastest interface to setup a channel. This is not
13+
a scalable approach, and does not make a lot of attempt to
14+
distribute the connections.
15+
16+
This change does a weighted distribution of channels across
17+
all the available server interfaces, where the weight is
18+
a function of the advertised interface speed.
19+
20+
Also make sure that we don't mix rdma and non-rdma for channels.
21+
22+
Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
23+
Signed-off-by: Steve French <stfrench@microsoft.com>
24+
(cherry picked from commit a6d8fb54a515f0546ffdb7870102b1238917e567)
25+
Signed-off-by: Jonathan Maple <jmaple@ciq.com>
26+
27+
# Conflicts:
28+
# fs/cifs/sess.c
29+
diff --cc fs/cifs/sess.c
30+
index b9c9236e1312,336b64d93e41..000000000000
31+
--- a/fs/cifs/sess.c
32+
+++ b/fs/cifs/sess.c
33+
@@@ -231,22 -298,39 +252,40 @@@ int cifs_try_adding_channels(struct cif
34+
int
35+
cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)
36+
{
37+
++<<<<<<< HEAD:fs/cifs/sess.c
38+
+ unsigned int chan_index = cifs_ses_get_chan_index(ses, server);
39+
++=======
40+
+ unsigned int chan_index;
41+
+ size_t iface_weight = 0, iface_min_speed = 0;
42+
++>>>>>>> a6d8fb54a515 (cifs: distribute channels across interfaces based on speed):fs/smb/client/sess.c
43+
struct cifs_server_iface *iface = NULL;
44+
struct cifs_server_iface *old_iface = NULL;
45+
+ struct cifs_server_iface *last_iface = NULL;
46+
int rc = 0;
47+
48+
- spin_lock(&ses->chan_lock);
49+
- chan_index = cifs_ses_get_chan_index(ses, server);
50+
- if (chan_index == CIFS_INVAL_CHAN_INDEX) {
51+
- spin_unlock(&ses->chan_lock);
52+
+ /* primary channel. This can never go away */
53+
+ if (!chan_index)
54+
return 0;
55+
- }
56+
57+
if (ses->chans[chan_index].iface) {
58+
old_iface = ses->chans[chan_index].iface;
59+
- if (old_iface->is_active) {
60+
- spin_unlock(&ses->chan_lock);
61+
+ if (old_iface->is_active)
62+
return 1;
63+
- }
64+
}
65+
- spin_unlock(&ses->chan_lock);
66+
67+
spin_lock(&ses->iface_lock);
68+
++<<<<<<< HEAD:fs/cifs/sess.c
69+
++=======
70+
+ if (!ses->iface_count) {
71+
+ spin_unlock(&ses->iface_lock);
72+
+ cifs_dbg(VFS, "server %s does not advertise interfaces\n", ses->server->hostname);
73+
+ return 0;
74+
+ }
75+
+
76+
+ last_iface = list_last_entry(&ses->iface_list, struct cifs_server_iface,
77+
+ iface_head);
78+
+ iface_min_speed = last_iface->speed;
79+
++>>>>>>> a6d8fb54a515 (cifs: distribute channels across interfaces based on speed):fs/smb/client/sess.c
80+
81+
/* then look for a new one */
82+
list_for_each_entry(iface, &ses->iface_list, iface_head) {
83+
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
84+
index eb8541c3298e..903f64652422 100644
85+
--- a/fs/cifs/cifs_debug.c
86+
+++ b/fs/cifs/cifs_debug.c
87+
@@ -232,6 +232,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
88+
struct cifs_ses *ses;
89+
struct cifs_tcon *tcon;
90+
struct cifs_server_iface *iface;
91+
+ size_t iface_weight = 0, iface_min_speed = 0;
92+
+ struct cifs_server_iface *last_iface = NULL;
93+
int c, i, j;
94+
95+
seq_puts(m,
96+
@@ -472,11 +474,25 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
97+
"\tLast updated: %lu seconds ago",
98+
ses->iface_count,
99+
(jiffies - ses->iface_last_update) / HZ);
100+
+
101+
+ last_iface = list_last_entry(&ses->iface_list,
102+
+ struct cifs_server_iface,
103+
+ iface_head);
104+
+ iface_min_speed = last_iface->speed;
105+
+
106+
j = 0;
107+
list_for_each_entry(iface, &ses->iface_list,
108+
iface_head) {
109+
seq_printf(m, "\n\t%d)", ++j);
110+
cifs_dump_iface(m, iface);
111+
+
112+
+ iface_weight = iface->speed / iface_min_speed;
113+
+ seq_printf(m, "\t\tWeight (cur,total): (%zu,%zu)"
114+
+ "\n\t\tAllocated channels: %u\n",
115+
+ iface->weight_fulfilled,
116+
+ iface_weight,
117+
+ iface->num_channels);
118+
+
119+
if (is_ses_using_iface(ses, iface))
120+
seq_puts(m, "\t\t[CONNECTED]\n");
121+
}
122+
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
123+
index 9e7f8c48e52c..a68c17d158ba 100644
124+
--- a/fs/cifs/cifsglob.h
125+
+++ b/fs/cifs/cifsglob.h
126+
@@ -914,6 +914,8 @@ struct cifs_server_iface {
127+
struct list_head iface_head;
128+
struct kref refcount;
129+
size_t speed;
130+
+ size_t weight_fulfilled;
131+
+ unsigned int num_channels;
132+
unsigned int rdma_capable : 1;
133+
unsigned int rss_capable : 1;
134+
unsigned int is_active : 1; /* unset if non existent */
135+
* Unmerged path fs/cifs/sess.c

0 commit comments

Comments
 (0)