]> git.baikalelectronics.ru Git - kernel.git/commitdiff
neighbour: switch to standard rcu, instead of rcu_bh
authorEric Dumazet <edumazet@google.com>
Tue, 21 Mar 2023 04:01:14 +0000 (04:01 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 Oct 2023 20:00:42 +0000 (22:00 +0200)
[ Upstream commit 09eed1192cec1755967f2af8394207acdde579a1 ]

rcu_bh is no longer a win, especially for objects freed
with standard call_rcu().

Switch neighbour code to no longer disable BH when not necessary.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 5baa0433a15e ("neighbour: fix data-races around n->output")
Signed-off-by: Sasha Levin <sashal@kernel.org>
13 files changed:
include/net/arp.h
include/net/ndisc.h
include/net/neighbour.h
include/net/nexthop.h
net/core/filter.c
net/core/neighbour.c
net/ipv4/fib_semantics.c
net/ipv4/ip_output.c
net/ipv4/nexthop.c
net/ipv4/route.c
net/ipv6/addrconf.c
net/ipv6/ip6_output.c
net/ipv6/route.c

index d7ef4ec71dfebac562f3ecf965c36547375de78c..e8747e0713c79f6f4934bb8474498f59cc5b189c 100644 (file)
@@ -38,11 +38,11 @@ static inline struct neighbour *__ipv4_neigh_lookup(struct net_device *dev, u32
 {
        struct neighbour *n;
 
-       rcu_read_lock_bh();
+       rcu_read_lock();
        n = __ipv4_neigh_lookup_noref(dev, key);
        if (n && !refcount_inc_not_zero(&n->refcnt))
                n = NULL;
-       rcu_read_unlock_bh();
+       rcu_read_unlock();
 
        return n;
 }
@@ -51,10 +51,10 @@ static inline void __ipv4_confirm_neigh(struct net_device *dev, u32 key)
 {
        struct neighbour *n;
 
-       rcu_read_lock_bh();
+       rcu_read_lock();
        n = __ipv4_neigh_lookup_noref(dev, key);
        neigh_confirm(n);
-       rcu_read_unlock_bh();
+       rcu_read_unlock();
 }
 
 void arp_init(void);
index da7eec8669ec4125b0b238f3af8627cd57a279b4..325a6fb65c89679ddc571d2979331b458c141afd 100644 (file)
@@ -395,11 +395,11 @@ static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, cons
 {
        struct neighbour *n;
 
-       rcu_read_lock_bh();
+       rcu_read_lock();
        n = __ipv6_neigh_lookup_noref(dev, pkey);
        if (n && !refcount_inc_not_zero(&n->refcnt))
                n = NULL;
-       rcu_read_unlock_bh();
+       rcu_read_unlock();
 
        return n;
 }
@@ -409,10 +409,10 @@ static inline void __ipv6_confirm_neigh(struct net_device *dev,
 {
        struct neighbour *n;
 
-       rcu_read_lock_bh();
+       rcu_read_lock();
        n = __ipv6_neigh_lookup_noref(dev, pkey);
        neigh_confirm(n);
-       rcu_read_unlock_bh();
+       rcu_read_unlock();
 }
 
 static inline void __ipv6_confirm_neigh_stub(struct net_device *dev,
@@ -420,10 +420,10 @@ static inline void __ipv6_confirm_neigh_stub(struct net_device *dev,
 {
        struct neighbour *n;
 
-       rcu_read_lock_bh();
+       rcu_read_lock();
        n = __ipv6_neigh_lookup_noref_stub(dev, pkey);
        neigh_confirm(n);
-       rcu_read_unlock_bh();
+       rcu_read_unlock();
 }
 
 /* uses ipv6_stub and is meant for use outside of IPv6 core */
index cd30aac9ec835b97b9debe03e259ae7c0ecc44c8..f6a8ecc6b1fa7cf8cee4eac9193efeae046e75e6 100644 (file)
@@ -299,14 +299,14 @@ static inline struct neighbour *___neigh_lookup_noref(
        const void *pkey,
        struct net_device *dev)
 {
-       struct neigh_hash_table *nht = rcu_dereference_bh(tbl->nht);
+       struct neigh_hash_table *nht = rcu_dereference(tbl->nht);
        struct neighbour *n;
        u32 hash_val;
 
        hash_val = hash(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift);
-       for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]);
+       for (n = rcu_dereference(nht->hash_buckets[hash_val]);
             n != NULL;
-            n = rcu_dereference_bh(n->next)) {
+            n = rcu_dereference(n->next)) {
                if (n->dev == dev && key_eq(n, pkey))
                        return n;
        }
index 28085b995ddcfe2269f1f8524ea747a881d835a4..9fa291a046211e4fc1c7ae56094a124c4ce0a516 100644 (file)
@@ -498,7 +498,7 @@ static inline struct fib6_nh *nexthop_fib6_nh(struct nexthop *nh)
 }
 
 /* Variant of nexthop_fib6_nh().
- * Caller should either hold rcu_read_lock_bh(), or RTNL.
+ * Caller should either hold rcu_read_lock(), or RTNL.
  */
 static inline struct fib6_nh *nexthop_fib6_nh_bh(struct nexthop *nh)
 {
@@ -507,13 +507,13 @@ static inline struct fib6_nh *nexthop_fib6_nh_bh(struct nexthop *nh)
        if (nh->is_group) {
                struct nh_group *nh_grp;
 
-               nh_grp = rcu_dereference_bh_rtnl(nh->nh_grp);
+               nh_grp = rcu_dereference_rtnl(nh->nh_grp);
                nh = nexthop_mpath_select(nh_grp, 0);
                if (!nh)
                        return NULL;
        }
 
-       nhi = rcu_dereference_bh_rtnl(nh->nh_info);
+       nhi = rcu_dereference_rtnl(nh->nh_info);
        if (nhi->family == AF_INET6)
                return &nhi->fib6_nh;
 
index d32c6bd4d579a8af88e7d0629a637bb796901eea..adc327f4af1e91b75ae6b3e827ce9c23387bc949 100644 (file)
@@ -2197,7 +2197,7 @@ static int bpf_out_neigh_v6(struct net *net, struct sk_buff *skb,
                        return -ENOMEM;
        }
 
-       rcu_read_lock_bh();
+       rcu_read_lock();
        if (!nh) {
                dst = skb_dst(skb);
                nexthop = rt6_nexthop(container_of(dst, struct rt6_info, dst),
@@ -2210,10 +2210,12 @@ static int bpf_out_neigh_v6(struct net *net, struct sk_buff *skb,
                int ret;
 
                sock_confirm_neigh(skb, neigh);
+               local_bh_disable();
                dev_xmit_recursion_inc();
                ret = neigh_output(neigh, skb, false);
                dev_xmit_recursion_dec();
-               rcu_read_unlock_bh();
+               local_bh_enable();
+               rcu_read_unlock();
                return ret;
        }
        rcu_read_unlock_bh();
@@ -2295,7 +2297,7 @@ static int bpf_out_neigh_v4(struct net *net, struct sk_buff *skb,
                        return -ENOMEM;
        }
 
-       rcu_read_lock_bh();
+       rcu_read_lock();
        if (!nh) {
                struct dst_entry *dst = skb_dst(skb);
                struct rtable *rt = container_of(dst, struct rtable, dst);
@@ -2307,7 +2309,7 @@ static int bpf_out_neigh_v4(struct net *net, struct sk_buff *skb,
        } else if (nh->nh_family == AF_INET) {
                neigh = ip_neigh_gw4(dev, nh->ipv4_nh);
        } else {
-               rcu_read_unlock_bh();
+               rcu_read_unlock();
                goto out_drop;
        }
 
@@ -2315,13 +2317,15 @@ static int bpf_out_neigh_v4(struct net *net, struct sk_buff *skb,
                int ret;
 
                sock_confirm_neigh(skb, neigh);
+               local_bh_disable();
                dev_xmit_recursion_inc();
                ret = neigh_output(neigh, skb, is_v6gw);
                dev_xmit_recursion_dec();
-               rcu_read_unlock_bh();
+               local_bh_enable();
+               rcu_read_unlock();
                return ret;
        }
-       rcu_read_unlock_bh();
+       rcu_read_unlock();
 out_drop:
        kfree_skb(skb);
        return -ENETDOWN;
index 51393079487ae3bf501089b9faf236498a1078ae..bafd72e5f5886b9311fedece5efb497b455c7c67 100644 (file)
@@ -614,7 +614,7 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
 
        NEIGH_CACHE_STAT_INC(tbl, lookups);
 
-       rcu_read_lock_bh();
+       rcu_read_lock();
        n = __neigh_lookup_noref(tbl, pkey, dev);
        if (n) {
                if (!refcount_inc_not_zero(&n->refcnt))
@@ -622,7 +622,7 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
                NEIGH_CACHE_STAT_INC(tbl, hits);
        }
 
-       rcu_read_unlock_bh();
+       rcu_read_unlock();
        return n;
 }
 EXPORT_SYMBOL(neigh_lookup);
@@ -2176,11 +2176,11 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
                        .ndtc_proxy_qlen        = tbl->proxy_queue.qlen,
                };
 
-               rcu_read_lock_bh();
-               nht = rcu_dereference_bh(tbl->nht);
+               rcu_read_lock();
+               nht = rcu_dereference(tbl->nht);
                ndc.ndtc_hash_rnd = nht->hash_rnd[0];
                ndc.ndtc_hash_mask = ((1 << nht->hash_shift) - 1);
-               rcu_read_unlock_bh();
+               rcu_read_unlock();
 
                if (nla_put(skb, NDTA_CONFIG, sizeof(ndc), &ndc))
                        goto nla_put_failure;
@@ -2695,15 +2695,15 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
        if (filter->dev_idx || filter->master_idx)
                flags |= NLM_F_DUMP_FILTERED;
 
-       rcu_read_lock_bh();
-       nht = rcu_dereference_bh(tbl->nht);
+       rcu_read_lock();
+       nht = rcu_dereference(tbl->nht);
 
        for (h = s_h; h < (1 << nht->hash_shift); h++) {
                if (h > s_h)
                        s_idx = 0;
-               for (n = rcu_dereference_bh(nht->hash_buckets[h]), idx = 0;
+               for (n = rcu_dereference(nht->hash_buckets[h]), idx = 0;
                     n != NULL;
-                    n = rcu_dereference_bh(n->next)) {
+                    n = rcu_dereference(n->next)) {
                        if (idx < s_idx || !net_eq(dev_net(n->dev), net))
                                goto next;
                        if (neigh_ifindex_filtered(n->dev, filter->dev_idx) ||
@@ -2722,7 +2722,7 @@ next:
        }
        rc = skb->len;
 out:
-       rcu_read_unlock_bh();
+       rcu_read_unlock();
        cb->args[1] = h;
        cb->args[2] = idx;
        return rc;
@@ -3067,20 +3067,20 @@ void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void
        int chain;
        struct neigh_hash_table *nht;
 
-       rcu_read_lock_bh();
-       nht = rcu_dereference_bh(tbl->nht);
+       rcu_read_lock();
+       nht = rcu_dereference(tbl->nht);
 
-       read_lock(&tbl->lock); /* avoid resizes */
+       read_lock_bh(&tbl->lock); /* avoid resizes */
        for (chain = 0; chain < (1 << nht->hash_shift); chain++) {
                struct neighbour *n;
 
-               for (n = rcu_dereference_bh(nht->hash_buckets[chain]);
+               for (n = rcu_dereference(nht->hash_buckets[chain]);
                     n != NULL;
-                    n = rcu_dereference_bh(n->next))
+                    n = rcu_dereference(n->next))
                        cb(n, cookie);
        }
-       read_unlock(&tbl->lock);
-       rcu_read_unlock_bh();
+       read_unlock_bh(&tbl->lock);
+       rcu_read_unlock();
 }
 EXPORT_SYMBOL(neigh_for_each);
 
@@ -3130,7 +3130,7 @@ int neigh_xmit(int index, struct net_device *dev,
                tbl = neigh_tables[index];
                if (!tbl)
                        goto out;
-               rcu_read_lock_bh();
+               rcu_read_lock();
                if (index == NEIGH_ARP_TABLE) {
                        u32 key = *((u32 *)addr);
 
@@ -3142,11 +3142,11 @@ int neigh_xmit(int index, struct net_device *dev,
                        neigh = __neigh_create(tbl, addr, dev, false);
                err = PTR_ERR(neigh);
                if (IS_ERR(neigh)) {
-                       rcu_read_unlock_bh();
+                       rcu_read_unlock();
                        goto out_kfree_skb;
                }
                err = neigh->output(neigh, skb);
-               rcu_read_unlock_bh();
+               rcu_read_unlock();
        }
        else if (index == NEIGH_LINK_TABLE) {
                err = dev_hard_header(skb, dev, ntohs(skb->protocol),
@@ -3175,7 +3175,7 @@ static struct neighbour *neigh_get_first(struct seq_file *seq)
 
        state->flags &= ~NEIGH_SEQ_IS_PNEIGH;
        for (bucket = 0; bucket < (1 << nht->hash_shift); bucket++) {
-               n = rcu_dereference_bh(nht->hash_buckets[bucket]);
+               n = rcu_dereference(nht->hash_buckets[bucket]);
 
                while (n) {
                        if (!net_eq(dev_net(n->dev), net))
@@ -3193,7 +3193,7 @@ static struct neighbour *neigh_get_first(struct seq_file *seq)
                        if (READ_ONCE(n->nud_state) & ~NUD_NOARP)
                                break;
 next:
-                       n = rcu_dereference_bh(n->next);
+                       n = rcu_dereference(n->next);
                }
 
                if (n)
@@ -3217,7 +3217,7 @@ static struct neighbour *neigh_get_next(struct seq_file *seq,
                if (v)
                        return n;
        }
-       n = rcu_dereference_bh(n->next);
+       n = rcu_dereference(n->next);
 
        while (1) {
                while (n) {
@@ -3235,7 +3235,7 @@ static struct neighbour *neigh_get_next(struct seq_file *seq,
                        if (READ_ONCE(n->nud_state) & ~NUD_NOARP)
                                break;
 next:
-                       n = rcu_dereference_bh(n->next);
+                       n = rcu_dereference(n->next);
                }
 
                if (n)
@@ -3244,7 +3244,7 @@ next:
                if (++state->bucket >= (1 << nht->hash_shift))
                        break;
 
-               n = rcu_dereference_bh(nht->hash_buckets[state->bucket]);
+               n = rcu_dereference(nht->hash_buckets[state->bucket]);
        }
 
        if (n && pos)
@@ -3346,7 +3346,7 @@ static void *neigh_get_idx_any(struct seq_file *seq, loff_t *pos)
 
 void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl, unsigned int neigh_seq_flags)
        __acquires(tbl->lock)
-       __acquires(rcu_bh)
+       __acquires(rcu)
 {
        struct neigh_seq_state *state = seq->private;
 
@@ -3354,9 +3354,9 @@ void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl
        state->bucket = 0;
        state->flags = (neigh_seq_flags & ~NEIGH_SEQ_IS_PNEIGH);
 
-       rcu_read_lock_bh();
-       state->nht = rcu_dereference_bh(tbl->nht);
-       read_lock(&tbl->lock);
+       rcu_read_lock();
+       state->nht = rcu_dereference(tbl->nht);
+       read_lock_bh(&tbl->lock);
 
        return *pos ? neigh_get_idx_any(seq, pos) : SEQ_START_TOKEN;
 }
@@ -3391,13 +3391,13 @@ EXPORT_SYMBOL(neigh_seq_next);
 
 void neigh_seq_stop(struct seq_file *seq, void *v)
        __releases(tbl->lock)
-       __releases(rcu_bh)
+       __releases(rcu)
 {
        struct neigh_seq_state *state = seq->private;
        struct neigh_table *tbl = state->tbl;
 
-       read_unlock(&tbl->lock);
-       rcu_read_unlock_bh();
+       read_unlock_bh(&tbl->lock);
+       rcu_read_unlock();
 }
 EXPORT_SYMBOL(neigh_seq_stop);
 
index 158ad3c2662f50827724b2f348ed15d922392508..eafa4a033515782b4ade9a81ec12cb22f5e51e35 100644 (file)
@@ -2194,7 +2194,7 @@ static bool fib_good_nh(const struct fib_nh *nh)
        if (nh->fib_nh_scope == RT_SCOPE_LINK) {
                struct neighbour *n;
 
-               rcu_read_lock_bh();
+               rcu_read_lock();
 
                if (likely(nh->fib_nh_gw_family == AF_INET))
                        n = __ipv4_neigh_lookup_noref(nh->fib_nh_dev,
@@ -2207,7 +2207,7 @@ static bool fib_good_nh(const struct fib_nh *nh)
                if (n)
                        state = READ_ONCE(n->nud_state);
 
-               rcu_read_unlock_bh();
+               rcu_read_unlock();
        }
 
        return !!(state & NUD_VALID);
index 66908ce2dd116505ae16065c0e8b2c1b995915f5..493c679ea54f3ca8ad3694f5d33c6744b029b56e 100644 (file)
@@ -218,7 +218,7 @@ static int ip_finish_output2(struct net *net, struct sock *sk, struct sk_buff *s
                        return res;
        }
 
-       rcu_read_lock_bh();
+       rcu_read_lock();
        neigh = ip_neigh_for_gw(rt, skb, &is_v6gw);
        if (!IS_ERR(neigh)) {
                int res;
@@ -226,10 +226,10 @@ static int ip_finish_output2(struct net *net, struct sock *sk, struct sk_buff *s
                sock_confirm_neigh(skb, neigh);
                /* if crossing protocols, can not use the cached header */
                res = neigh_output(neigh, skb, is_v6gw);
-               rcu_read_unlock_bh();
+               rcu_read_unlock();
                return res;
        }
-       rcu_read_unlock_bh();
+       rcu_read_unlock();
 
        net_dbg_ratelimited("%s: No header cache and no neighbour!\n",
                            __func__);
index d699a41c9d9557e691cfd986c03f97bce21986d2..be5498f5dd3192feddf4fbb919bfc9a26f29cb26 100644 (file)
@@ -1124,13 +1124,13 @@ static bool ipv6_good_nh(const struct fib6_nh *nh)
        int state = NUD_REACHABLE;
        struct neighbour *n;
 
-       rcu_read_lock_bh();
+       rcu_read_lock();
 
        n = __ipv6_neigh_lookup_noref_stub(nh->fib_nh_dev, &nh->fib_nh_gw6);
        if (n)
                state = READ_ONCE(n->nud_state);
 
-       rcu_read_unlock_bh();
+       rcu_read_unlock();
 
        return !!(state & NUD_VALID);
 }
@@ -1140,14 +1140,14 @@ static bool ipv4_good_nh(const struct fib_nh *nh)
        int state = NUD_REACHABLE;
        struct neighbour *n;
 
-       rcu_read_lock_bh();
+       rcu_read_lock();
 
        n = __ipv4_neigh_lookup_noref(nh->fib_nh_dev,
                                      (__force u32)nh->fib_nh_gw4);
        if (n)
                state = READ_ONCE(n->nud_state);
 
-       rcu_read_unlock_bh();
+       rcu_read_unlock();
 
        return !!(state & NUD_VALID);
 }
index 8d838b00469002732f52b305c27b6432882a3ee1..608bd9f8dbc861383385e19bbca95d4e3f9f3978 100644 (file)
@@ -408,7 +408,7 @@ static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst,
        struct net_device *dev = dst->dev;
        struct neighbour *n;
 
-       rcu_read_lock_bh();
+       rcu_read_lock();
 
        if (likely(rt->rt_gw_family == AF_INET)) {
                n = ip_neigh_gw4(dev, rt->rt_gw4);
@@ -424,7 +424,7 @@ static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst,
        if (!IS_ERR(n) && !refcount_inc_not_zero(&n->refcnt))
                n = NULL;
 
-       rcu_read_unlock_bh();
+       rcu_read_unlock();
 
        return n;
 }
index 96f4351b55a6f6c69d4ab913c5ceb612a181004f..c63ccd39fc552bbf149effe8d70e724aaf1cd83d 100644 (file)
@@ -1035,7 +1035,7 @@ static int ipv6_add_addr_hash(struct net_device *dev, struct inet6_ifaddr *ifa)
        unsigned int hash = inet6_addr_hash(net, &ifa->addr);
        int err = 0;
 
-       spin_lock(&net->ipv6.addrconf_hash_lock);
+       spin_lock_bh(&net->ipv6.addrconf_hash_lock);
 
        /* Ignore adding duplicate addresses on an interface */
        if (ipv6_chk_same_addr(net, &ifa->addr, dev, hash)) {
@@ -1045,7 +1045,7 @@ static int ipv6_add_addr_hash(struct net_device *dev, struct inet6_ifaddr *ifa)
                hlist_add_head_rcu(&ifa->addr_lst, &net->ipv6.inet6_addr_lst[hash]);
        }
 
-       spin_unlock(&net->ipv6.addrconf_hash_lock);
+       spin_unlock_bh(&net->ipv6.addrconf_hash_lock);
 
        return err;
 }
@@ -1140,15 +1140,15 @@ ipv6_add_addr(struct inet6_dev *idev, struct ifa6_config *cfg,
        /* For caller */
        refcount_set(&ifa->refcnt, 1);
 
-       rcu_read_lock_bh();
+       rcu_read_lock();
 
        err = ipv6_add_addr_hash(idev->dev, ifa);
        if (err < 0) {
-               rcu_read_unlock_bh();
+               rcu_read_unlock();
                goto out;
        }
 
-       write_lock(&idev->lock);
+       write_lock_bh(&idev->lock);
 
        /* Add to inet6_dev unicast addr list. */
        ipv6_link_dev_addr(idev, ifa);
@@ -1159,9 +1159,9 @@ ipv6_add_addr(struct inet6_dev *idev, struct ifa6_config *cfg,
        }
 
        in6_ifa_hold(ifa);
-       write_unlock(&idev->lock);
+       write_unlock_bh(&idev->lock);
 
-       rcu_read_unlock_bh();
+       rcu_read_unlock();
 
        inet6addr_notifier_call_chain(NETDEV_UP, ifa);
 out:
index 5bf15a530fe73c6f74088b478c652d2fa2dc37eb..ce2c5e728745fe0798efab6a0c17e1bc50ac6d10 100644 (file)
@@ -116,7 +116,7 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
                        return res;
        }
 
-       rcu_read_lock_bh();
+       rcu_read_lock();
        nexthop = rt6_nexthop((struct rt6_info *)dst, daddr);
        neigh = __ipv6_neigh_lookup_noref(dev, nexthop);
 
@@ -124,7 +124,7 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
                if (unlikely(!neigh))
                        neigh = __neigh_create(&nd_tbl, nexthop, dev, false);
                if (IS_ERR(neigh)) {
-                       rcu_read_unlock_bh();
+                       rcu_read_unlock();
                        IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTNOROUTES);
                        kfree_skb_reason(skb, SKB_DROP_REASON_NEIGH_CREATEFAIL);
                        return -EINVAL;
@@ -132,7 +132,7 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
        }
        sock_confirm_neigh(skb, neigh);
        ret = neigh_output(neigh, skb, false);
-       rcu_read_unlock_bh();
+       rcu_read_unlock();
        return ret;
 }
 
@@ -1150,11 +1150,11 @@ static int ip6_dst_lookup_tail(struct net *net, const struct sock *sk,
         * dst entry of the nexthop router
         */
        rt = (struct rt6_info *) *dst;
-       rcu_read_lock_bh();
+       rcu_read_lock();
        n = __ipv6_neigh_lookup_noref(rt->dst.dev,
                                      rt6_nexthop(rt, &fl6->daddr));
        err = n && !(READ_ONCE(n->nud_state) & NUD_VALID) ? -EINVAL : 0;
-       rcu_read_unlock_bh();
+       rcu_read_unlock();
 
        if (err) {
                struct inet6_ifaddr *ifp;
index 4f103e7c4ea25f3162bb2cc8f62497aa863f5878..0a9f854bfa50c1ef6d3da6db4c9a8a19eddc141a 100644 (file)
@@ -636,7 +636,7 @@ static void rt6_probe(struct fib6_nh *fib6_nh)
 
        nh_gw = &fib6_nh->fib_nh_gw6;
        dev = fib6_nh->fib_nh_dev;
-       rcu_read_lock_bh();
+       rcu_read_lock();
        last_probe = READ_ONCE(fib6_nh->last_probe);
        idev = __in6_dev_get(dev);
        neigh = __ipv6_neigh_lookup_noref(dev, nh_gw);
@@ -644,7 +644,7 @@ static void rt6_probe(struct fib6_nh *fib6_nh)
                if (READ_ONCE(neigh->nud_state) & NUD_VALID)
                        goto out;
 
-               write_lock(&neigh->lock);
+               write_lock_bh(&neigh->lock);
                if (!(neigh->nud_state & NUD_VALID) &&
                    time_after(jiffies,
                               neigh->updated + idev->cnf.rtr_probe_interval)) {
@@ -652,7 +652,7 @@ static void rt6_probe(struct fib6_nh *fib6_nh)
                        if (work)
                                __neigh_set_probe_once(neigh);
                }
-               write_unlock(&neigh->lock);
+               write_unlock_bh(&neigh->lock);
        } else if (time_after(jiffies, last_probe +
                                       idev->cnf.rtr_probe_interval)) {
                work = kmalloc(sizeof(*work), GFP_ATOMIC);
@@ -670,7 +670,7 @@ static void rt6_probe(struct fib6_nh *fib6_nh)
        }
 
 out:
-       rcu_read_unlock_bh();
+       rcu_read_unlock();
 }
 #else
 static inline void rt6_probe(struct fib6_nh *fib6_nh)
@@ -686,7 +686,7 @@ static enum rt6_nud_state rt6_check_neigh(const struct fib6_nh *fib6_nh)
        enum rt6_nud_state ret = RT6_NUD_FAIL_HARD;
        struct neighbour *neigh;
 
-       rcu_read_lock_bh();
+       rcu_read_lock();
        neigh = __ipv6_neigh_lookup_noref(fib6_nh->fib_nh_dev,
                                          &fib6_nh->fib_nh_gw6);
        if (neigh) {
@@ -704,7 +704,7 @@ static enum rt6_nud_state rt6_check_neigh(const struct fib6_nh *fib6_nh)
                ret = IS_ENABLED(CONFIG_IPV6_ROUTER_PREF) ?
                      RT6_NUD_SUCCEED : RT6_NUD_FAIL_DO_RR;
        }
-       rcu_read_unlock_bh();
+       rcu_read_unlock();
 
        return ret;
 }