|
@@ -2947,7 +2947,8 @@ int tcp_send_synack(struct sock *sk)
|
|
|
*/
|
|
|
struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
|
|
|
struct request_sock *req,
|
|
|
- struct tcp_fastopen_cookie *foc)
|
|
|
+ struct tcp_fastopen_cookie *foc,
|
|
|
+ bool attach_req)
|
|
|
{
|
|
|
struct inet_request_sock *ireq = inet_rsk(req);
|
|
|
const struct tcp_sock *tp = tcp_sk(sk);
|
|
@@ -2959,11 +2960,7 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
|
|
|
u16 user_mss;
|
|
|
int mss;
|
|
|
|
|
|
- /* sk is a const pointer, because we want to express multiple cpus
|
|
|
- * might call us concurrently.
|
|
|
- * sock_wmalloc() will change sk->sk_wmem_alloc in an atomic way.
|
|
|
- */
|
|
|
- skb = sock_wmalloc((struct sock *)sk, MAX_TCP_HEADER, 1, GFP_ATOMIC);
|
|
|
+ skb = alloc_skb(MAX_TCP_HEADER, GFP_ATOMIC);
|
|
|
if (unlikely(!skb)) {
|
|
|
dst_release(dst);
|
|
|
return NULL;
|
|
@@ -2971,6 +2968,17 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
|
|
|
/* Reserve space for headers. */
|
|
|
skb_reserve(skb, MAX_TCP_HEADER);
|
|
|
|
|
|
+ if (attach_req) {
|
|
|
+ skb->destructor = sock_edemux;
|
|
|
+ sock_hold(req_to_sk(req));
|
|
|
+ skb->sk = req_to_sk(req);
|
|
|
+ } else {
|
|
|
+ /* sk is a const pointer, because we want to express multiple
|
|
|
+ * cpu might call us concurrently.
|
|
|
+ * sk->sk_wmem_alloc in an atomic, we can promote to rw.
|
|
|
+ */
|
|
|
+ skb_set_owner_w(skb, (struct sock *)sk);
|
|
|
+ }
|
|
|
skb_dst_set(skb, dst);
|
|
|
|
|
|
mss = dst_metric_advmss(dst);
|
|
@@ -3510,7 +3518,7 @@ int tcp_rtx_synack(const struct sock *sk, struct request_sock *req)
|
|
|
int res;
|
|
|
|
|
|
tcp_rsk(req)->txhash = net_tx_rndhash();
|
|
|
- res = af_ops->send_synack(sk, NULL, &fl, req, 0, NULL);
|
|
|
+ res = af_ops->send_synack(sk, NULL, &fl, req, 0, NULL, true);
|
|
|
if (!res) {
|
|
|
TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
|
|
|
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSYNRETRANS);
|