tcp: do not lock listener to process SYN packets

Everything should now be ready to finally allow SYN
packets processing without holding listener lock.

Tested:

3.5 Mpps SYNFLOOD. Plenty of cpu cycles available.

Next bottleneck is the refcount taken on listener,
that could be avoided if we remove SLAB_DESTROY_BY_RCU
strict semantic for listeners, and use regular RCU.

    13.18%  [kernel]  [k] __inet_lookup_listener
     9.61%  [kernel]  [k] tcp_conn_request
     8.16%  [kernel]  [k] sha_transform
     5.30%  [kernel]  [k] inet_reqsk_alloc
     4.22%  [kernel]  [k] sock_put
     3.74%  [kernel]  [k] tcp_make_synack
     2.88%  [kernel]  [k] ipt_do_table
     2.56%  [kernel]  [k] memcpy_erms
     2.53%  [kernel]  [k] sock_wfree
     2.40%  [kernel]  [k] tcp_v4_rcv
     2.08%  [kernel]  [k] fib_table_lookup
     1.84%  [kernel]  [k] tcp_openreq_init_rwin

Change-Id: I113630b943ccf27a7c57920b03635ea5a986fbaf
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Eric Dumazet 2015-10-02 11:43:39 -07:00 committed by Flex1911
parent 5a3a309e77
commit 5ff7bc82fb
2 changed files with 14 additions and 2 deletions

View file

@ -1587,7 +1587,7 @@ static __sum16 tcp_v4_checksum_init(struct sk_buff *skb)
/* The socket must have it's spinlock held when we get
* here.
* here, unless it is a TCP_LISTEN socket.
*
* We have a potential double-lock case here, so even when
* doing backlog processing we use the BH locking scheme.
@ -1726,6 +1726,11 @@ process:
skb->dev = NULL;
if (sk->sk_state == TCP_LISTEN) {
ret = tcp_v4_do_rcv(sk, skb);
goto put_and_return;
}
bh_lock_sock_nested(sk);
ret = 0;
if (!sock_owned_by_user(sk)) {
@ -1748,6 +1753,7 @@ process:
}
bh_unlock_sock(sk);
put_and_return:
sock_put(sk);
return ret;

View file

@ -1459,7 +1459,7 @@ static __sum16 tcp_v6_checksum_init(struct sk_buff *skb)
}
/* The socket must have it's spinlock held when we get
* here.
* here, unless it is a TCP_LISTEN socket.
*
* We have a potential double-lock case here, so even when
* doing backlog processing we use the BH locking scheme.
@ -1653,6 +1653,11 @@ process:
skb->dev = NULL;
if (sk->sk_state == TCP_LISTEN) {
ret = tcp_v6_do_rcv(sk, skb);
goto put_and_return;
}
bh_lock_sock_nested(sk);
ret = 0;
if (!sock_owned_by_user(sk)) {
@ -1675,6 +1680,7 @@ process:
}
bh_unlock_sock(sk);
put_and_return:
sock_put(sk);
return ret ? -1 : 0;