summaryrefslogtreecommitdiffstats
path: root/net/unix/diag.c
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2012-06-08 05:03:21 +0000
committerDavid S. Miller <davem@davemloft.net>2012-06-08 14:27:23 -0700
commit7123aaa3a1416529ce461e98108e6b343b294643 (patch)
tree094070a521666979523411422109cce72a1db8c4 /net/unix/diag.c
parent54db0cc2ba0d38166acc2d6bae21721405305537 (diff)
downloadlinux-7123aaa3a1416529ce461e98108e6b343b294643.tar.gz
linux-7123aaa3a1416529ce461e98108e6b343b294643.tar.bz2
linux-7123aaa3a1416529ce461e98108e6b343b294643.zip
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.c6
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)
num = s_num = cb->args[1];
spin_lock(&unix_table_lock);
- for (slot = s_slot; slot <= UNIX_HASH_SIZE; s_num = 0, slot++) {
+ for (slot = s_slot;
+ slot < ARRAY_SIZE(unix_socket_table);
+ s_num = 0, slot++) {
struct sock *sk;
struct hlist_node *node;
@@ -228,7 +230,7 @@ static struct sock *unix_lookup_by_ino(int ino)
struct sock *sk;
spin_lock(&unix_table_lock);
- for (i = 0; i <= UNIX_HASH_SIZE; i++) {
+ for (i = 0; i < ARRAY_SIZE(unix_socket_table); i++) {
struct hlist_node *node;
sk_for_each(sk, node, &unix_socket_table[i])