Skip to content

Commit f554af2

Browse files
author
Trond Myklebust
committed
SUNRPC: Optimise transport balancing code
Moves the balancing code to avoid doing cursor changes on every search iteration. Signed-off-by: Trond Myklebust <[email protected]>
1 parent 7536908 commit f554af2

File tree

1 file changed

+38
-29
lines changed

1 file changed

+38
-29
lines changed

net/sunrpc/xprtmultipath.c

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
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

2525
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,
291291
}
292292

293293
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,
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

326317
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,
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

338329
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)
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+
360368
static
361369
struct 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

Comments
 (0)