ipv6: some RCU conversions
ICMP and ND are not fast path, but still we can avoid changing idev refcount, using RCU. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
ab1594e92e
commit
cfdf76474e
+10
-15
@@ -490,7 +490,8 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
|
||||
goto out_dst_release;
|
||||
}
|
||||
|
||||
idev = in6_dev_get(skb->dev);
|
||||
rcu_read_lock();
|
||||
idev = __in6_dev_get(skb->dev);
|
||||
|
||||
err = ip6_append_data(sk, icmpv6_getfrag, &msg,
|
||||
len + sizeof(struct icmp6hdr),
|
||||
@@ -500,19 +501,16 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
|
||||
if (err) {
|
||||
ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS);
|
||||
ip6_flush_pending_frames(sk);
|
||||
goto out_put;
|
||||
} else {
|
||||
err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr,
|
||||
len + sizeof(struct icmp6hdr));
|
||||
}
|
||||
err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, len + sizeof(struct icmp6hdr));
|
||||
|
||||
out_put:
|
||||
if (likely(idev != NULL))
|
||||
in6_dev_put(idev);
|
||||
rcu_read_unlock();
|
||||
out_dst_release:
|
||||
dst_release(dst);
|
||||
out:
|
||||
icmpv6_xmit_unlock(sk);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(icmpv6_send);
|
||||
|
||||
static void icmpv6_echo_reply(struct sk_buff *skb)
|
||||
@@ -569,7 +567,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
|
||||
if (hlimit < 0)
|
||||
hlimit = ip6_dst_hoplimit(dst);
|
||||
|
||||
idev = in6_dev_get(skb->dev);
|
||||
idev = __in6_dev_get(skb->dev);
|
||||
|
||||
msg.skb = skb;
|
||||
msg.offset = 0;
|
||||
@@ -583,13 +581,10 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
|
||||
if (err) {
|
||||
ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS);
|
||||
ip6_flush_pending_frames(sk);
|
||||
goto out_put;
|
||||
} else {
|
||||
err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr,
|
||||
skb->len + sizeof(struct icmp6hdr));
|
||||
}
|
||||
err = icmpv6_push_pending_frames(sk, &fl6, &tmp_hdr, skb->len + sizeof(struct icmp6hdr));
|
||||
|
||||
out_put:
|
||||
if (likely(idev != NULL))
|
||||
in6_dev_put(idev);
|
||||
dst_release(dst);
|
||||
out:
|
||||
icmpv6_xmit_unlock(sk);
|
||||
|
||||
Reference in New Issue
Block a user