[PATCH] knfsd: split svc_serv into pools
Split out the list of idle threads and pending sockets from svc_serv into a new svc_pool structure, and allocate a fixed number (in this patch, 1) of pools per svc_serv. The new structure contains a lock which takes over several of the duties of svc_serv->sv_lock, which is now relegated to protecting only sv_tempsocks, sv_permsocks, and sv_tmpcnt in svc_serv. The point is to move the hottest fields out of svc_serv and into svc_pool, allowing a following patch to arrange for a svc_pool per NUMA node or per CPU. This is a major step towards making the NFS server NUMA-friendly. Signed-off-by: Greg Banks <gnb@melbourne.sgi.com> Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
c081a0c7cf
commit
3262c816a3
4 changed files with 152 additions and 53 deletions
|
|
@ -17,6 +17,25 @@
|
|||
#include <linux/wait.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* RPC service thread pool.
|
||||
*
|
||||
* Pool of threads and temporary sockets. Generally there is only
|
||||
* a single one of these per RPC service, but on NUMA machines those
|
||||
* services that can benefit from it (i.e. nfs but not lockd) will
|
||||
* have one pool per NUMA node. This optimisation reduces cross-
|
||||
* node traffic on multi-node NUMA NFS servers.
|
||||
*/
|
||||
struct svc_pool {
|
||||
unsigned int sp_id; /* pool id; also node id on NUMA */
|
||||
spinlock_t sp_lock; /* protects all fields */
|
||||
struct list_head sp_threads; /* idle server threads */
|
||||
struct list_head sp_sockets; /* pending sockets */
|
||||
unsigned int sp_nrthreads; /* # of threads in pool */
|
||||
} ____cacheline_aligned_in_smp;
|
||||
|
||||
/*
|
||||
* RPC service.
|
||||
*
|
||||
|
|
@ -28,8 +47,6 @@
|
|||
* We currently do not support more than one RPC program per daemon.
|
||||
*/
|
||||
struct svc_serv {
|
||||
struct list_head sv_threads; /* idle server threads */
|
||||
struct list_head sv_sockets; /* pending sockets */
|
||||
struct svc_program * sv_program; /* RPC program */
|
||||
struct svc_stat * sv_stats; /* RPC statistics */
|
||||
spinlock_t sv_lock;
|
||||
|
|
@ -44,6 +61,9 @@ struct svc_serv {
|
|||
|
||||
char * sv_name; /* service name */
|
||||
|
||||
unsigned int sv_nrpools; /* number of thread pools */
|
||||
struct svc_pool * sv_pools; /* array of thread pools */
|
||||
|
||||
void (*sv_shutdown)(struct svc_serv *serv);
|
||||
/* Callback to use when last thread
|
||||
* exits.
|
||||
|
|
@ -138,6 +158,7 @@ struct svc_rqst {
|
|||
int rq_addrlen;
|
||||
|
||||
struct svc_serv * rq_server; /* RPC service definition */
|
||||
struct svc_pool * rq_pool; /* thread pool */
|
||||
struct svc_procedure * rq_procinfo; /* procedure info */
|
||||
struct auth_ops * rq_authop; /* authentication flavour */
|
||||
struct svc_cred rq_cred; /* auth info */
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ struct svc_sock {
|
|||
struct socket * sk_sock; /* berkeley socket layer */
|
||||
struct sock * sk_sk; /* INET layer */
|
||||
|
||||
struct svc_pool * sk_pool; /* current pool iff queued */
|
||||
struct svc_serv * sk_server; /* service for this socket */
|
||||
atomic_t sk_inuse; /* use count */
|
||||
unsigned long sk_flags;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue