Skip to content

Commit e994b2f

Browse files
Eric Dumazetdavem330
Eric Dumazet
authored andcommitted
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 Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 92d6f17 commit e994b2f

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

net/ipv4/tcp_ipv4.c

+9-2
Original file line numberDiff line numberDiff line change
@@ -1355,7 +1355,7 @@ static struct sock *tcp_v4_cookie_check(struct sock *sk, struct sk_buff *skb)
13551355
}
13561356

13571357
/* The socket must have it's spinlock held when we get
1358-
* here.
1358+
* here, unless it is a TCP_LISTEN socket.
13591359
*
13601360
* We have a potential double-lock case here, so even when
13611361
* doing backlog processing we use the BH locking scheme.
@@ -1619,9 +1619,15 @@ int tcp_v4_rcv(struct sk_buff *skb)
16191619
if (sk_filter(sk, skb))
16201620
goto discard_and_relse;
16211621

1622-
sk_incoming_cpu_update(sk);
16231622
skb->dev = NULL;
16241623

1624+
if (sk->sk_state == TCP_LISTEN) {
1625+
ret = tcp_v4_do_rcv(sk, skb);
1626+
goto put_and_return;
1627+
}
1628+
1629+
sk_incoming_cpu_update(sk);
1630+
16251631
bh_lock_sock_nested(sk);
16261632
tcp_sk(sk)->segs_in += max_t(u16, 1, skb_shinfo(skb)->gso_segs);
16271633
ret = 0;
@@ -1636,6 +1642,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
16361642
}
16371643
bh_unlock_sock(sk);
16381644

1645+
put_and_return:
16391646
sock_put(sk);
16401647

16411648
return ret;

net/ipv6/tcp_ipv6.c

+9-2
Original file line numberDiff line numberDiff line change
@@ -1161,7 +1161,7 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
11611161
}
11621162

11631163
/* The socket must have it's spinlock held when we get
1164-
* here.
1164+
* here, unless it is a TCP_LISTEN socket.
11651165
*
11661166
* We have a potential double-lock case here, so even when
11671167
* doing backlog processing we use the BH locking scheme.
@@ -1415,9 +1415,15 @@ static int tcp_v6_rcv(struct sk_buff *skb)
14151415
if (sk_filter(sk, skb))
14161416
goto discard_and_relse;
14171417

1418-
sk_incoming_cpu_update(sk);
14191418
skb->dev = NULL;
14201419

1420+
if (sk->sk_state == TCP_LISTEN) {
1421+
ret = tcp_v6_do_rcv(sk, skb);
1422+
goto put_and_return;
1423+
}
1424+
1425+
sk_incoming_cpu_update(sk);
1426+
14211427
bh_lock_sock_nested(sk);
14221428
tcp_sk(sk)->segs_in += max_t(u16, 1, skb_shinfo(skb)->gso_segs);
14231429
ret = 0;
@@ -1432,6 +1438,7 @@ static int tcp_v6_rcv(struct sk_buff *skb)
14321438
}
14331439
bh_unlock_sock(sk);
14341440

1441+
put_and_return:
14351442
sock_put(sk);
14361443
return ret ? -1 : 0;
14371444

0 commit comments

Comments
 (0)