diff options
author | David S. Miller <davem@davemloft.net> | 2015-10-05 02:46:26 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-10-05 02:46:26 -0700 |
commit | 2472186f58ee1e4b9ca194245fef03931f6de90a (patch) | |
tree | 75c793a05dd64db3df05f804e429bae45ead20d1 /net/ipv4/tcp_fastopen.c | |
parent | 3e087caa23ef36370bfb925d3bbca78e8302d3ce (diff) | |
parent | a1a5344ddbe8fd3e080013b317ac9a664490cfdf (diff) |
Merge branch 'tcp-listener-fixes-and-improvement'
Eric Dumazet says:
====================
tcp: lockless listener fixes and improvement
This fixes issues with TCP FastOpen vs lockless listeners,
and SYNACK being attached to request sockets.
Then, last patch brings performance improvement for
syncookies generation and validation.
Tested under a 4.3 Mpps SYNFLOOD attack, new perf profile looks
like :
12.11% [kernel] [k] sha_transform
5.83% [kernel] [k] tcp_conn_request
4.59% [kernel] [k] __inet_lookup_listener
4.11% [kernel] [k] ipt_do_table
3.91% [kernel] [k] tcp_make_synack
3.05% [kernel] [k] fib_table_lookup
2.74% [kernel] [k] sock_wfree
2.66% [kernel] [k] memcpy_erms
2.12% [kernel] [k] tcp_v4_rcv
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_fastopen.c')
-rw-r--r-- | net/ipv4/tcp_fastopen.c | 26 |
1 files changed, 7 insertions, 19 deletions
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c index 410ac481fda0..93396bf7b475 100644 --- a/net/ipv4/tcp_fastopen.c +++ b/net/ipv4/tcp_fastopen.c @@ -168,8 +168,6 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk, TCP_TIMEOUT_INIT, TCP_RTO_MAX); atomic_set(&req->rsk_refcnt, 2); - /* Add the child socket directly into the accept queue */ - inet_csk_reqsk_queue_add(sk, req, child); /* Now finish processing the fastopen child socket. */ inet_csk(child)->icsk_af_ops->rebuild_header(child); @@ -178,12 +176,10 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk, tcp_init_metrics(child); tcp_init_buffer_space(child); - /* Queue the data carried in the SYN packet. We need to first - * bump skb's refcnt because the caller will attempt to free it. - * Note that IPv6 might also have used skb_get() trick - * in tcp_v6_conn_request() to keep this SYN around (treq->pktopts) - * So we need to eventually get a clone of the packet, - * before inserting it in sk_receive_queue. + /* Queue the data carried in the SYN packet. + * We used to play tricky games with skb_get(). + * With lockless listener, it is a dead end. + * Do not think about it. * * XXX (TFO) - we honor a zero-payload TFO request for now, * (any reason not to?) but no need to queue the skb since @@ -191,12 +187,7 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk, */ end_seq = TCP_SKB_CB(skb)->end_seq; if (end_seq != TCP_SKB_CB(skb)->seq + 1) { - struct sk_buff *skb2; - - if (unlikely(skb_shared(skb))) - skb2 = skb_clone(skb, GFP_ATOMIC); - else - skb2 = skb_get(skb); + struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); if (likely(skb2)) { skb_dst_drop(skb2); @@ -214,12 +205,9 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk, } } tcp_rsk(req)->rcv_nxt = tp->rcv_nxt = end_seq; - sk->sk_data_ready(sk); - bh_unlock_sock(child); - /* Note: sock_put(child) will be done by tcp_conn_request() - * after SYNACK packet is sent. + /* tcp_conn_request() is sending the SYNACK, + * and queues the child into listener accept queue. */ - WARN_ON(!req->sk); return child; } |