19
19
#include <linux/sunrpc/addr.h>
20
20
#include <linux/sunrpc/xprtmultipath.h>
21
21
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 ,
23
23
const struct rpc_xprt * cur );
24
24
25
25
static 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,
291
291
}
292
292
293
293
static
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 ,
295
295
struct rpc_xprt * * cursor ,
296
296
xprt_switch_find_xprt_t find_next )
297
297
{
298
- struct rpc_xprt * cur , * pos , * old ;
298
+ struct rpc_xprt * pos , * old ;
299
299
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 );
310
303
return pos ;
311
304
}
312
305
@@ -318,13 +311,11 @@ struct rpc_xprt *xprt_iter_next_entry_multiple(struct rpc_xprt_iter *xpi,
318
311
319
312
if (xps == NULL )
320
313
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 );
324
315
}
325
316
326
317
static
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 ,
328
319
const struct rpc_xprt * cur )
329
320
{
330
321
struct rpc_xprt * ret ;
@@ -336,31 +327,49 @@ struct rpc_xprt *xprt_switch_find_next_entry_roundrobin(struct list_head *head,
336
327
}
337
328
338
329
static
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 )
340
332
{
341
- struct rpc_xprt_switch * xps = rcu_dereference ( xpi -> xpi_xpswitch ) ;
333
+ struct list_head * head = & xps -> xps_xprt_list ;
342
334
struct rpc_xprt * xprt ;
343
- unsigned long xprt_queuelen ;
344
- unsigned long xps_queuelen ;
335
+ unsigned int nactive ;
345
336
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 )
350
342
break ;
351
343
xprt_queuelen = atomic_long_read (& xprt -> queuelen );
352
- if (xprt_queuelen <= 2 )
353
- break ;
354
344
xps_queuelen = atomic_long_read (& xps -> xps_queuelen );
345
+ nactive = READ_ONCE (xps -> xps_nactive );
355
346
/* 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
+ }
357
351
return xprt ;
358
352
}
359
353
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
+
360
368
static
361
369
struct rpc_xprt * xprt_iter_next_entry_all (struct rpc_xprt_iter * xpi )
362
370
{
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 );
364
373
}
365
374
366
375
/*
0 commit comments