ipv6: hand away dst refs to cork setup
Subsystems (4)
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 9/14 ipv6: hand away dst refs to cork setup
udpv6_sendmsg() doesn't need dst after calling into ip6_make_skb(), however it still retains a ref and ip6_make_skb() has to do an addition get/put pair. Hand over dst with the reference from ip6_sk_dst_lookup_flow() to avoid two atomics.
Signed-off-by Pavel Begunkov <[email protected]>
--- net/ipv6/ip6_output.c | 9 ++++++--- net/ipv6/udp.c | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-)
net/ipv6/ip6_output.c +6 -3
@@ -1356,6 +1356,8 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,unsigned int mtu;struct ipv6_txoptions *nopt, *opt = ipc6->opt; + cork->base.dst = &rt->dst; +/* * setup for corking */
@@ -1389,8 +1391,6 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,/* need source address above miyazawa*/ } -dst_hold (&rt->dst); - cork->base.dst = &rt->dst; v6_cork->hop_limit = ipc6->hlimit; v6_cork->tclass = ipc6->tclass;if (rt->dst.flags &DST_XFRM_TUNNEL )
@@ -1784,6 +1784,7 @@ int ip6_append_data(struct sock *sk,/* * setup for corking */ +dst_hold (&rt->dst); err =ip6_setup_cork (sk, &inet->cork, &np->cork, ipc6, rt);if (err)
@@ -1974,8 +1975,10 @@ struct sk_buff *ip6_make_skb(struct sock *sk,int exthdrlen = (ipc6->opt ? ipc6->opt->opt_flen :0 );int err; -if (flags &MSG_PROBE ) +if (flags &MSG_PROBE ) { +dst_release (&rt->dst);return NULL ; + }__skb_queue_head_init (&queue);
net/ipv6/udp.c +2 -1
@@ -1541,7 +1541,8 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) err =PTR_ERR (skb);if (!IS_ERR_OR_NULL (skb)) err =udp_v6_send_skb (skb, fl6, &cork.base); - goto out; +/* ip6_make_skb steals dst reference */ + goto out_no_dst; }lock_sock (sk);
Signature · 1 line
2.34.1