@@ -179,7 +179,9 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses)
179179 int left ;
180180 int rc = 0 ;
181181 int tries = 0 ;
182+ size_t iface_weight = 0 , iface_min_speed = 0 ;
182183 struct cifs_server_iface * iface = NULL , * niface = NULL ;
184+ struct cifs_server_iface * last_iface = NULL ;
183185
184186 spin_lock (& ses -> chan_lock );
185187
@@ -207,39 +209,47 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses)
207209 }
208210 spin_unlock (& ses -> chan_lock );
209211
210- /*
211- * Keep connecting to same, fastest, iface for all channels as
212- * long as its RSS. Try next fastest one if not RSS or channel
213- * creation fails.
214- */
215- spin_lock (& ses -> iface_lock );
216- iface = list_first_entry (& ses -> iface_list , struct cifs_server_iface ,
217- iface_head );
218- spin_unlock (& ses -> iface_lock );
219-
220212 while (left > 0 ) {
221213
222214 tries ++ ;
223215 if (tries > 3 * ses -> chan_max ) {
224- cifs_dbg (FYI , "too many channel open attempts (%d channels left to open)\n" ,
216+ cifs_dbg (VFS , "too many channel open attempts (%d channels left to open)\n" ,
225217 left );
226218 break ;
227219 }
228220
229221 spin_lock (& ses -> iface_lock );
230222 if (!ses -> iface_count ) {
231223 spin_unlock (& ses -> iface_lock );
224+ cifs_dbg (VFS , "server %s does not advertise interfaces\n" ,
225+ ses -> server -> hostname );
232226 break ;
233227 }
234228
229+ if (!iface )
230+ iface = list_first_entry (& ses -> iface_list , struct cifs_server_iface ,
231+ iface_head );
232+ last_iface = list_last_entry (& ses -> iface_list , struct cifs_server_iface ,
233+ iface_head );
234+ iface_min_speed = last_iface -> speed ;
235+
235236 list_for_each_entry_safe_from (iface , niface , & ses -> iface_list ,
236237 iface_head ) {
238+ /* do not mix rdma and non-rdma interfaces */
239+ if (iface -> rdma_capable != ses -> server -> rdma )
240+ continue ;
241+
237242 /* skip ifaces that are unusable */
238243 if (!iface -> is_active ||
239244 (is_ses_using_iface (ses , iface ) &&
240- !iface -> rss_capable )) {
245+ !iface -> rss_capable ))
246+ continue ;
247+
248+ /* check if we already allocated enough channels */
249+ iface_weight = iface -> speed / iface_min_speed ;
250+
251+ if (iface -> weight_fulfilled >= iface_weight )
241252 continue ;
242- }
243253
244254 /* take ref before unlock */
245255 kref_get (& iface -> refcount );
@@ -256,10 +266,21 @@ int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses)
256266 continue ;
257267 }
258268
259- cifs_dbg (FYI , "successfully opened new channel on iface:%pIS\n" ,
269+ iface -> num_channels ++ ;
270+ iface -> weight_fulfilled ++ ;
271+ cifs_dbg (VFS , "successfully opened new channel on iface:%pIS\n" ,
260272 & iface -> sockaddr );
261273 break ;
262274 }
275+
276+ /* reached end of list. reset weight_fulfilled and start over */
277+ if (list_entry_is_head (iface , & ses -> iface_list , iface_head )) {
278+ list_for_each_entry (iface , & ses -> iface_list , iface_head )
279+ iface -> weight_fulfilled = 0 ;
280+ spin_unlock (& ses -> iface_lock );
281+ iface = NULL ;
282+ continue ;
283+ }
263284 spin_unlock (& ses -> iface_lock );
264285
265286 left -- ;
278299cifs_chan_update_iface (struct cifs_ses * ses , struct TCP_Server_Info * server )
279300{
280301 unsigned int chan_index ;
302+ size_t iface_weight = 0 , iface_min_speed = 0 ;
281303 struct cifs_server_iface * iface = NULL ;
282304 struct cifs_server_iface * old_iface = NULL ;
305+ struct cifs_server_iface * last_iface = NULL ;
283306 int rc = 0 ;
284307
285308 spin_lock (& ses -> chan_lock );
@@ -299,13 +322,34 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)
299322 spin_unlock (& ses -> chan_lock );
300323
301324 spin_lock (& ses -> iface_lock );
325+ if (!ses -> iface_count ) {
326+ spin_unlock (& ses -> iface_lock );
327+ cifs_dbg (VFS , "server %s does not advertise interfaces\n" , ses -> server -> hostname );
328+ return 0 ;
329+ }
330+
331+ last_iface = list_last_entry (& ses -> iface_list , struct cifs_server_iface ,
332+ iface_head );
333+ iface_min_speed = last_iface -> speed ;
334+
302335 /* then look for a new one */
303336 list_for_each_entry (iface , & ses -> iface_list , iface_head ) {
337+ /* do not mix rdma and non-rdma interfaces */
338+ if (iface -> rdma_capable != server -> rdma )
339+ continue ;
340+
304341 if (!iface -> is_active ||
305342 (is_ses_using_iface (ses , iface ) &&
306343 !iface -> rss_capable )) {
307344 continue ;
308345 }
346+
347+ /* check if we already allocated enough channels */
348+ iface_weight = iface -> speed / iface_min_speed ;
349+
350+ if (iface -> weight_fulfilled >= iface_weight )
351+ continue ;
352+
309353 kref_get (& iface -> refcount );
310354 break ;
311355 }
@@ -321,10 +365,22 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)
321365 cifs_dbg (FYI , "replacing iface: %pIS with %pIS\n" ,
322366 & old_iface -> sockaddr ,
323367 & iface -> sockaddr );
368+
369+ old_iface -> num_channels -- ;
370+ if (old_iface -> weight_fulfilled )
371+ old_iface -> weight_fulfilled -- ;
372+ iface -> num_channels ++ ;
373+ iface -> weight_fulfilled ++ ;
374+
324375 kref_put (& old_iface -> refcount , release_iface );
325376 } else if (old_iface ) {
326377 cifs_dbg (FYI , "releasing ref to iface: %pIS\n" ,
327378 & old_iface -> sockaddr );
379+
380+ old_iface -> num_channels -- ;
381+ if (old_iface -> weight_fulfilled )
382+ old_iface -> weight_fulfilled -- ;
383+
328384 kref_put (& old_iface -> refcount , release_iface );
329385 } else {
330386 WARN_ON (!iface );
0 commit comments