diff options
author | Greg Banks <gnb@melbourne.sgi.com> | 2006-10-02 05:17:54 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-02 10:57:19 -0400 |
commit | 36bdfc8bae51339aa27ef8e4ce148185293061ae (patch) | |
tree | deab54ff70d6991c1e5be0d9efe97d10f65375b0 /net/sunrpc/svc.c | |
parent | 4a3ae42dc312dbdffee803efaf393421b79f997a (diff) |
[PATCH] knfsd: move tempsock aging to a timer
Following are 11 patches from Greg Banks which combine to make knfsd more
Numa-aware. They reduce hitting on 'global' data structures, and create some
data-structures that can be node-local.
knfsd threads are bound to a particular node, and the thread to handle a new
request is chosen from the threads that are attach to the node that received
the interrupt.
The distribution of threads across nodes can be controlled by a new file in
the 'nfsd' filesystem, though the default approach of an even spread is
probably fine for most sites.
Some (old) numbers that show the efficacy of these patches: N == number of
NICs == number of CPUs == nmber of clients. Number of NUMA nodes == N/2
N Throughput, MiB/s CPU usage, % (max=N*100)
Before After Before After
--- ------ ---- ----- -----
4 312 435 350 228
6 500 656 501 418
8 562 804 690 589
This patch:
Move the aging of RPC/TCP connection sockets from the main svc_recv() loop to
a timer which uses a mark-and-sweep algorithm every 6 minutes. This reduces
the amount of work that needs to be done in the main RPC loop and the length
of time we need to hold the (effectively global) svc_serv->sv_lock.
[akpm@osdl.org: cleanup]
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>
Diffstat (limited to 'net/sunrpc/svc.c')
-rw-r--r-- | net/sunrpc/svc.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index eee45a58f3ee..0c2c52276285 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -59,6 +59,7 @@ svc_create(struct svc_program *prog, unsigned int bufsize, | |||
59 | INIT_LIST_HEAD(&serv->sv_sockets); | 59 | INIT_LIST_HEAD(&serv->sv_sockets); |
60 | INIT_LIST_HEAD(&serv->sv_tempsocks); | 60 | INIT_LIST_HEAD(&serv->sv_tempsocks); |
61 | INIT_LIST_HEAD(&serv->sv_permsocks); | 61 | INIT_LIST_HEAD(&serv->sv_permsocks); |
62 | init_timer(&serv->sv_temptimer); | ||
62 | spin_lock_init(&serv->sv_lock); | 63 | spin_lock_init(&serv->sv_lock); |
63 | 64 | ||
64 | /* Remove any stale portmap registrations */ | 65 | /* Remove any stale portmap registrations */ |
@@ -87,6 +88,8 @@ svc_destroy(struct svc_serv *serv) | |||
87 | } else | 88 | } else |
88 | printk("svc_destroy: no threads for serv=%p!\n", serv); | 89 | printk("svc_destroy: no threads for serv=%p!\n", serv); |
89 | 90 | ||
91 | del_timer_sync(&serv->sv_temptimer); | ||
92 | |||
90 | while (!list_empty(&serv->sv_tempsocks)) { | 93 | while (!list_empty(&serv->sv_tempsocks)) { |
91 | svsk = list_entry(serv->sv_tempsocks.next, | 94 | svsk = list_entry(serv->sv_tempsocks.next, |
92 | struct svc_sock, | 95 | struct svc_sock, |