diff options
author | Eric Dumazet <edumazet@google.com> | 2012-06-08 01:03:21 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-06-08 17:27:23 -0400 |
commit | 7123aaa3a1416529ce461e98108e6b343b294643 (patch) | |
tree | 094070a521666979523411422109cce72a1db8c4 /net/unix/diag.c | |
parent | 54db0cc2ba0d38166acc2d6bae21721405305537 (diff) |
af_unix: speedup /proc/net/unix
/proc/net/unix has quadratic behavior, and can hold unix_table_lock for
a while if high number of unix sockets are alive. (90 ms for 200k
sockets...)
We already have a hash table, so its quite easy to use it.
Problem is unbound sockets are still hashed in a single hash slot
(unix_socket_table[UNIX_HASH_TABLE])
This patch also spreads unbound sockets to 256 hash slots, to speedup
both /proc/net/unix and unix_diag.
Time to read /proc/net/unix with 200k unix sockets :
(time dd if=/proc/net/unix of=/dev/null bs=4k)
before : 520 secs
after : 2 secs
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Steven Whitehouse <swhiteho@redhat.com>
Cc: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/unix/diag.c')
-rw-r--r-- | net/unix/diag.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/net/unix/diag.c b/net/unix/diag.c index 47d3002737f5..7e8a24bff34a 100644 --- a/net/unix/diag.c +++ b/net/unix/diag.c | |||
@@ -195,7 +195,9 @@ static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
195 | num = s_num = cb->args[1]; | 195 | num = s_num = cb->args[1]; |
196 | 196 | ||
197 | spin_lock(&unix_table_lock); | 197 | spin_lock(&unix_table_lock); |
198 | for (slot = s_slot; slot <= UNIX_HASH_SIZE; s_num = 0, slot++) { | 198 | for (slot = s_slot; |
199 | slot < ARRAY_SIZE(unix_socket_table); | ||
200 | s_num = 0, slot++) { | ||
199 | struct sock *sk; | 201 | struct sock *sk; |
200 | struct hlist_node *node; | 202 | struct hlist_node *node; |
201 | 203 | ||
@@ -228,7 +230,7 @@ static struct sock *unix_lookup_by_ino(int ino) | |||
228 | struct sock *sk; | 230 | struct sock *sk; |
229 | 231 | ||
230 | spin_lock(&unix_table_lock); | 232 | spin_lock(&unix_table_lock); |
231 | for (i = 0; i <= UNIX_HASH_SIZE; i++) { | 233 | for (i = 0; i < ARRAY_SIZE(unix_socket_table); i++) { |
232 | struct hlist_node *node; | 234 | struct hlist_node *node; |
233 | 235 | ||
234 | sk_for_each(sk, node, &unix_socket_table[i]) | 236 | sk_for_each(sk, node, &unix_socket_table[i]) |