Skip to content

Commit 9a0e6ac

Browse files
neilbrownchucklever
authored andcommitted
SUNRPC: use lwq for sp_sockets - renamed to sp_xprts
lwq avoids using back pointers in lists, and uses less locking. This introduces a new spinlock, but the other one will be removed in a future patch. For svc_clean_up_xprts(), we now dequeue the entire queue, walk it to remove and process the xprts that need cleaning up, then re-enqueue the remaining queue. Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
1 parent 5b80147 commit 9a0e6ac

File tree

4 files changed

+21
-43
lines changed

4 files changed

+21
-43
lines changed

include/linux/sunrpc/svc.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/sunrpc/xdr.h>
1818
#include <linux/sunrpc/auth.h>
1919
#include <linux/sunrpc/svcauth.h>
20+
#include <linux/lwq.h>
2021
#include <linux/wait.h>
2122
#include <linux/mm.h>
2223
#include <linux/pagevec.h>
@@ -34,7 +35,7 @@
3435
struct svc_pool {
3536
unsigned int sp_id; /* pool id; also node id on NUMA */
3637
spinlock_t sp_lock; /* protects all fields */
37-
struct list_head sp_sockets; /* pending sockets */
38+
struct lwq sp_xprts; /* pending transports */
3839
unsigned int sp_nrthreads; /* # of threads in pool */
3940
struct list_head sp_all_threads; /* all server threads */
4041
struct llist_head sp_idle_threads; /* idle server threads */

include/linux/sunrpc/svc_xprt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ struct svc_xprt {
5454
const struct svc_xprt_ops *xpt_ops;
5555
struct kref xpt_ref;
5656
struct list_head xpt_list;
57-
struct list_head xpt_ready;
57+
struct lwq_node xpt_ready;
5858
unsigned long xpt_flags;
5959

6060
struct svc_serv *xpt_server; /* service for transport */

net/sunrpc/svc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
508508
i, serv->sv_name);
509509

510510
pool->sp_id = i;
511-
INIT_LIST_HEAD(&pool->sp_sockets);
511+
lwq_init(&pool->sp_xprts);
512512
INIT_LIST_HEAD(&pool->sp_all_threads);
513513
init_llist_head(&pool->sp_idle_threads);
514514
spin_lock_init(&pool->sp_lock);

net/sunrpc/svc_xprt.c

Lines changed: 17 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,6 @@ void svc_xprt_init(struct net *net, struct svc_xprt_class *xcl,
201201
kref_init(&xprt->xpt_ref);
202202
xprt->xpt_server = serv;
203203
INIT_LIST_HEAD(&xprt->xpt_list);
204-
INIT_LIST_HEAD(&xprt->xpt_ready);
205204
INIT_LIST_HEAD(&xprt->xpt_deferred);
206205
INIT_LIST_HEAD(&xprt->xpt_users);
207206
mutex_init(&xprt->xpt_mutex);
@@ -472,9 +471,7 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
472471
pool = svc_pool_for_cpu(xprt->xpt_server);
473472

474473
percpu_counter_inc(&pool->sp_sockets_queued);
475-
spin_lock_bh(&pool->sp_lock);
476-
list_add_tail(&xprt->xpt_ready, &pool->sp_sockets);
477-
spin_unlock_bh(&pool->sp_lock);
474+
lwq_enqueue(&xprt->xpt_ready, &pool->sp_xprts);
478475

479476
svc_pool_wake_idle_thread(pool);
480477
}
@@ -487,18 +484,9 @@ static struct svc_xprt *svc_xprt_dequeue(struct svc_pool *pool)
487484
{
488485
struct svc_xprt *xprt = NULL;
489486

490-
if (list_empty(&pool->sp_sockets))
491-
goto out;
492-
493-
spin_lock_bh(&pool->sp_lock);
494-
if (likely(!list_empty(&pool->sp_sockets))) {
495-
xprt = list_first_entry(&pool->sp_sockets,
496-
struct svc_xprt, xpt_ready);
497-
list_del_init(&xprt->xpt_ready);
487+
xprt = lwq_dequeue(&pool->sp_xprts, struct svc_xprt, xpt_ready);
488+
if (xprt)
498489
svc_xprt_get(xprt);
499-
}
500-
spin_unlock_bh(&pool->sp_lock);
501-
out:
502490
return xprt;
503491
}
504492

@@ -708,7 +696,7 @@ svc_thread_should_sleep(struct svc_rqst *rqstp)
708696
return false;
709697

710698
/* was a socket queued? */
711-
if (!list_empty(&pool->sp_sockets))
699+
if (!lwq_empty(&pool->sp_xprts))
712700
return false;
713701

714702
/* are we shutting down? */
@@ -1050,7 +1038,6 @@ static void svc_delete_xprt(struct svc_xprt *xprt)
10501038

10511039
spin_lock_bh(&serv->sv_lock);
10521040
list_del_init(&xprt->xpt_list);
1053-
WARN_ON_ONCE(!list_empty(&xprt->xpt_ready));
10541041
if (test_bit(XPT_TEMP, &xprt->xpt_flags))
10551042
serv->sv_tmpcnt--;
10561043
spin_unlock_bh(&serv->sv_lock);
@@ -1101,36 +1088,26 @@ static int svc_close_list(struct svc_serv *serv, struct list_head *xprt_list, st
11011088
return ret;
11021089
}
11031090

1104-
static struct svc_xprt *svc_dequeue_net(struct svc_serv *serv, struct net *net)
1091+
static void svc_clean_up_xprts(struct svc_serv *serv, struct net *net)
11051092
{
1106-
struct svc_pool *pool;
11071093
struct svc_xprt *xprt;
1108-
struct svc_xprt *tmp;
11091094
int i;
11101095

11111096
for (i = 0; i < serv->sv_nrpools; i++) {
1112-
pool = &serv->sv_pools[i];
1113-
1114-
spin_lock_bh(&pool->sp_lock);
1115-
list_for_each_entry_safe(xprt, tmp, &pool->sp_sockets, xpt_ready) {
1116-
if (xprt->xpt_net != net)
1117-
continue;
1118-
list_del_init(&xprt->xpt_ready);
1119-
spin_unlock_bh(&pool->sp_lock);
1120-
return xprt;
1097+
struct svc_pool *pool = &serv->sv_pools[i];
1098+
struct llist_node *q, **t1, *t2;
1099+
1100+
q = lwq_dequeue_all(&pool->sp_xprts);
1101+
lwq_for_each_safe(xprt, t1, t2, &q, xpt_ready) {
1102+
if (xprt->xpt_net == net) {
1103+
set_bit(XPT_CLOSE, &xprt->xpt_flags);
1104+
svc_delete_xprt(xprt);
1105+
xprt = NULL;
1106+
}
11211107
}
1122-
spin_unlock_bh(&pool->sp_lock);
1123-
}
1124-
return NULL;
1125-
}
11261108

1127-
static void svc_clean_up_xprts(struct svc_serv *serv, struct net *net)
1128-
{
1129-
struct svc_xprt *xprt;
1130-
1131-
while ((xprt = svc_dequeue_net(serv, net))) {
1132-
set_bit(XPT_CLOSE, &xprt->xpt_flags);
1133-
svc_delete_xprt(xprt);
1109+
if (q)
1110+
lwq_enqueue_batch(q, &pool->sp_xprts);
11341111
}
11351112
}
11361113

0 commit comments

Comments
 (0)