Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ab6e3feb authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

net: No dst refcounting in ip_queue_xmit()



TCP outgoing packets can avoid two atomic ops, and dirtying
of previously higly contended cache line using new refdst
infrastructure.

Note 1: loopback device excluded because of !IFF_XMIT_DST_RELEASE
Note 2: UDP packets dsts are built before ip_queue_xmit().

Signed-off-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4a94445c
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -318,10 +318,12 @@ int ip_queue_xmit(struct sk_buff *skb)
	struct ip_options *opt = inet->opt;
	struct rtable *rt;
	struct iphdr *iph;
	int res;

	/* Skip all of this if the packet is already routed,
	 * f.e. by something like SCTP.
	 */
	rcu_read_lock();
	rt = skb_rtable(skb);
	if (rt != NULL)
		goto packet_routed;
@@ -359,7 +361,7 @@ int ip_queue_xmit(struct sk_buff *skb)
		}
		sk_setup_caps(sk, &rt->u.dst);
	}
	skb_dst_set(skb, dst_clone(&rt->u.dst));
	skb_dst_set_noref(skb, &rt->u.dst);

packet_routed:
	if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
@@ -391,9 +393,12 @@ int ip_queue_xmit(struct sk_buff *skb)
	skb->priority = sk->sk_priority;
	skb->mark = sk->sk_mark;

	return ip_local_out(skb);
	res = ip_local_out(skb);
	rcu_read_unlock();
	return res;

no_route:
	rcu_read_unlock();
	IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
	kfree_skb(skb);
	return -EHOSTUNREACH;