diff options
author | Eric Dumazet <edumazet@google.com> | 2016-10-20 00:24:58 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-10-20 11:24:32 -0400 |
commit | 9652dc2eb9e40d100e0a3abfdcc0ea852c8be254 (patch) | |
tree | e3efd14c1b27eba8a65381fa769023fb9f473831 /net/ipv4/tcp_ipv4.c | |
parent | 25c07e2c5ec80a1c7390b41e2b03ca3d0e31fc01 (diff) |
tcp: relax listening_hash operations
softirq handlers use RCU protection to lookup listeners,
and write operations all happen from process context.
We do not need to block BH for dump operations.
Also SYN_RECV since request sockets are stored in the ehash table :
1) inet_diag_dump_icsk() no longer need to clear
cb->args[3] and cb->args[4] that were used as cursors while
iterating the old per listener hash table.
2) Also factorize a test : No need to scan listening_hash[]
if r->id.idiag_dport is not zero.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index bd5e8d10893f..83b3d0b8c481 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -1893,7 +1893,7 @@ static void *listening_get_next(struct seq_file *seq, void *cur) | |||
1893 | if (!sk) { | 1893 | if (!sk) { |
1894 | get_head: | 1894 | get_head: |
1895 | ilb = &tcp_hashinfo.listening_hash[st->bucket]; | 1895 | ilb = &tcp_hashinfo.listening_hash[st->bucket]; |
1896 | spin_lock_bh(&ilb->lock); | 1896 | spin_lock(&ilb->lock); |
1897 | sk = sk_head(&ilb->head); | 1897 | sk = sk_head(&ilb->head); |
1898 | st->offset = 0; | 1898 | st->offset = 0; |
1899 | goto get_sk; | 1899 | goto get_sk; |
@@ -1911,7 +1911,7 @@ get_sk: | |||
1911 | return sk; | 1911 | return sk; |
1912 | icsk = inet_csk(sk); | 1912 | icsk = inet_csk(sk); |
1913 | } | 1913 | } |
1914 | spin_unlock_bh(&ilb->lock); | 1914 | spin_unlock(&ilb->lock); |
1915 | st->offset = 0; | 1915 | st->offset = 0; |
1916 | if (++st->bucket < INET_LHTABLE_SIZE) | 1916 | if (++st->bucket < INET_LHTABLE_SIZE) |
1917 | goto get_head; | 1917 | goto get_head; |
@@ -2119,7 +2119,7 @@ static void tcp_seq_stop(struct seq_file *seq, void *v) | |||
2119 | switch (st->state) { | 2119 | switch (st->state) { |
2120 | case TCP_SEQ_STATE_LISTENING: | 2120 | case TCP_SEQ_STATE_LISTENING: |
2121 | if (v != SEQ_START_TOKEN) | 2121 | if (v != SEQ_START_TOKEN) |
2122 | spin_unlock_bh(&tcp_hashinfo.listening_hash[st->bucket].lock); | 2122 | spin_unlock(&tcp_hashinfo.listening_hash[st->bucket].lock); |
2123 | break; | 2123 | break; |
2124 | case TCP_SEQ_STATE_ESTABLISHED: | 2124 | case TCP_SEQ_STATE_ESTABLISHED: |
2125 | if (v) | 2125 | if (v) |