1919#include <linux/sunrpc/addr.h>
2020#include <linux/sunrpc/xprtmultipath.h>
2121
22- typedef struct rpc_xprt * (* xprt_switch_find_xprt_t )(struct list_head * head ,
22+ typedef struct rpc_xprt * (* xprt_switch_find_xprt_t )(struct rpc_xprt_switch * xps ,
2323 const struct rpc_xprt * cur );
2424
2525static const struct rpc_xprt_iter_ops rpc_xprt_iter_singular ;
@@ -291,22 +291,15 @@ struct rpc_xprt *xprt_switch_find_next_entry(struct list_head *head,
291291}
292292
293293static
294- struct rpc_xprt * xprt_switch_set_next_cursor (struct list_head * head ,
294+ struct rpc_xprt * xprt_switch_set_next_cursor (struct rpc_xprt_switch * xps ,
295295 struct rpc_xprt * * cursor ,
296296 xprt_switch_find_xprt_t find_next )
297297{
298- struct rpc_xprt * cur , * pos , * old ;
298+ struct rpc_xprt * pos , * old ;
299299
300- cur = READ_ONCE (* cursor );
301- for (;;) {
302- old = cur ;
303- pos = find_next (head , old );
304- if (pos == NULL )
305- break ;
306- cur = cmpxchg_relaxed (cursor , old , pos );
307- if (cur == old )
308- break ;
309- }
300+ old = smp_load_acquire (cursor );
301+ pos = find_next (xps , old );
302+ smp_store_release (cursor , pos );
310303 return pos ;
311304}
312305
@@ -318,13 +311,11 @@ struct rpc_xprt *xprt_iter_next_entry_multiple(struct rpc_xprt_iter *xpi,
318311
319312 if (xps == NULL )
320313 return NULL ;
321- return xprt_switch_set_next_cursor (& xps -> xps_xprt_list ,
322- & xpi -> xpi_cursor ,
323- find_next );
314+ return xprt_switch_set_next_cursor (xps , & xpi -> xpi_cursor , find_next );
324315}
325316
326317static
327- struct rpc_xprt * xprt_switch_find_next_entry_roundrobin (struct list_head * head ,
318+ struct rpc_xprt * __xprt_switch_find_next_entry_roundrobin (struct list_head * head ,
328319 const struct rpc_xprt * cur )
329320{
330321 struct rpc_xprt * ret ;
@@ -336,31 +327,49 @@ struct rpc_xprt *xprt_switch_find_next_entry_roundrobin(struct list_head *head,
336327}
337328
338329static
339- struct rpc_xprt * xprt_iter_next_entry_roundrobin (struct rpc_xprt_iter * xpi )
330+ struct rpc_xprt * xprt_switch_find_next_entry_roundrobin (struct rpc_xprt_switch * xps ,
331+ const struct rpc_xprt * cur )
340332{
341- struct rpc_xprt_switch * xps = rcu_dereference ( xpi -> xpi_xpswitch ) ;
333+ struct list_head * head = & xps -> xps_xprt_list ;
342334 struct rpc_xprt * xprt ;
343- unsigned long xprt_queuelen ;
344- unsigned long xps_queuelen ;
335+ unsigned int nactive ;
345336
346- do {
347- xprt = xprt_iter_next_entry_multiple (xpi ,
348- xprt_switch_find_next_entry_roundrobin );
349- if (xprt == NULL )
337+ for (;;) {
338+ unsigned long xprt_queuelen , xps_queuelen ;
339+
340+ xprt = __xprt_switch_find_next_entry_roundrobin (head , cur );
341+ if (!xprt )
350342 break ;
351343 xprt_queuelen = atomic_long_read (& xprt -> queuelen );
352- if (xprt_queuelen <= 2 )
353- break ;
354344 xps_queuelen = atomic_long_read (& xps -> xps_queuelen );
345+ nactive = READ_ONCE (xps -> xps_nactive );
355346 /* Exit loop if xprt_queuelen <= average queue length */
356- } while (xprt_queuelen * READ_ONCE (xps -> xps_nactive ) > xps_queuelen );
347+ if (xprt_queuelen * nactive <= xps_queuelen )
348+ break ;
349+ cur = xprt ;
350+ }
357351 return xprt ;
358352}
359353
354+ static
355+ struct rpc_xprt * xprt_iter_next_entry_roundrobin (struct rpc_xprt_iter * xpi )
356+ {
357+ return xprt_iter_next_entry_multiple (xpi ,
358+ xprt_switch_find_next_entry_roundrobin );
359+ }
360+
361+ static
362+ struct rpc_xprt * xprt_switch_find_next_entry_all (struct rpc_xprt_switch * xps ,
363+ const struct rpc_xprt * cur )
364+ {
365+ return xprt_switch_find_next_entry (& xps -> xps_xprt_list , cur );
366+ }
367+
360368static
361369struct rpc_xprt * xprt_iter_next_entry_all (struct rpc_xprt_iter * xpi )
362370{
363- return xprt_iter_next_entry_multiple (xpi , xprt_switch_find_next_entry );
371+ return xprt_iter_next_entry_multiple (xpi ,
372+ xprt_switch_find_next_entry_all );
364373}
365374
366375/*
0 commit comments