tcp/dccp: do not touch listener sk_refcnt under synflood
When a SYNFLOOD targets a non SO_REUSEPORT listener, multiple cpus contend on sk->sk_refcnt and sk->sk_wmem_alloc changes. By letting listeners use SOCK_RCU_FREE infrastructure, we can relax TCP_LISTEN lookup rules and avoid touching sk_refcnt Note that we still use SLAB_DESTROY_BY_RCU rules for other sockets, only listeners are impacted by this change. Peak performance under SYNFLOOD is increased by ~33% : On my test machine, I could process 3.2 Mpps instead of 2.4 Mpps Most consuming functions are now skb_set_owner_w() and sock_wfree() contending on sk->sk_wmem_alloc when cooking SYNACK and freeing them. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
此提交包含在:
@@ -642,6 +642,7 @@ discard:
|
||||
static int dccp_v6_rcv(struct sk_buff *skb)
|
||||
{
|
||||
const struct dccp_hdr *dh;
|
||||
bool refcounted;
|
||||
struct sock *sk;
|
||||
int min_cov;
|
||||
|
||||
@@ -670,7 +671,7 @@ static int dccp_v6_rcv(struct sk_buff *skb)
|
||||
lookup:
|
||||
sk = __inet6_lookup_skb(&dccp_hashinfo, skb, __dccp_hdr_len(dh),
|
||||
dh->dccph_sport, dh->dccph_dport,
|
||||
inet6_iif(skb));
|
||||
inet6_iif(skb), &refcounted);
|
||||
if (!sk) {
|
||||
dccp_pr_debug("failed to look up flow ID in table and "
|
||||
"get corresponding socket\n");
|
||||
@@ -699,6 +700,7 @@ lookup:
|
||||
goto lookup;
|
||||
}
|
||||
sock_hold(sk);
|
||||
refcounted = true;
|
||||
nsk = dccp_check_req(sk, skb, req);
|
||||
if (!nsk) {
|
||||
reqsk_put(req);
|
||||
@@ -752,7 +754,8 @@ discard_it:
|
||||
return 0;
|
||||
|
||||
discard_and_relse:
|
||||
sock_put(sk);
|
||||
if (refcounted)
|
||||
sock_put(sk);
|
||||
goto discard_it;
|
||||
}
|
||||
|
||||
|
新增問題並參考
封鎖使用者