mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 10:04:04 +02:00
ipv6: anycast: Don't use rtnl_dereference().
inet6_dev->ac_list is protected by inet6_dev->lock, so rtnl_dereference() is a bit rough annotation. As done in mcast.c, we can use ac_dereference() that checks if inet6_dev->lock is held. Let's replace rtnl_dereference() with a new helper ac_dereference(). Note that now addrconf_join_solict() / addrconf_leave_solict() in __ipv6_dev_ac_inc() / __ipv6_dev_ac_dec() does not need RTNL, so we can remove ASSERT_RTNL() there. Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20250702230210.3115355-12-kuni1840@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
49b8223fa9
commit
7b6b53a76f
|
|
@ -2252,7 +2252,6 @@ void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr)
|
|||
__ipv6_dev_mc_dec(idev, &maddr);
|
||||
}
|
||||
|
||||
/* caller must hold RTNL */
|
||||
static void addrconf_join_anycast(struct inet6_ifaddr *ifp)
|
||||
{
|
||||
struct in6_addr addr;
|
||||
|
|
@ -2265,7 +2264,6 @@ static void addrconf_join_anycast(struct inet6_ifaddr *ifp)
|
|||
__ipv6_dev_ac_inc(ifp->idev, &addr);
|
||||
}
|
||||
|
||||
/* caller must hold RTNL */
|
||||
static void addrconf_leave_anycast(struct inet6_ifaddr *ifp)
|
||||
{
|
||||
struct in6_addr addr;
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@
|
|||
static struct hlist_head inet6_acaddr_lst[IN6_ADDR_HSIZE];
|
||||
static DEFINE_SPINLOCK(acaddr_hash_lock);
|
||||
|
||||
#define ac_dereference(a, idev) \
|
||||
rcu_dereference_protected(a, lockdep_is_held(&(idev)->lock))
|
||||
|
||||
static int ipv6_dev_ac_dec(struct net_device *dev, const struct in6_addr *addr);
|
||||
|
||||
static u32 inet6_acaddr_hash(const struct net *net,
|
||||
|
|
@ -319,16 +322,14 @@ int __ipv6_dev_ac_inc(struct inet6_dev *idev, const struct in6_addr *addr)
|
|||
struct net *net;
|
||||
int err;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
write_lock_bh(&idev->lock);
|
||||
if (idev->dead) {
|
||||
err = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (aca = rtnl_dereference(idev->ac_list); aca;
|
||||
aca = rtnl_dereference(aca->aca_next)) {
|
||||
for (aca = ac_dereference(idev->ac_list, idev); aca;
|
||||
aca = ac_dereference(aca->aca_next, idev)) {
|
||||
if (ipv6_addr_equal(&aca->aca_addr, addr)) {
|
||||
aca->aca_users++;
|
||||
err = 0;
|
||||
|
|
@ -380,12 +381,10 @@ int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr)
|
|||
{
|
||||
struct ifacaddr6 *aca, *prev_aca;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
write_lock_bh(&idev->lock);
|
||||
prev_aca = NULL;
|
||||
for (aca = rtnl_dereference(idev->ac_list); aca;
|
||||
aca = rtnl_dereference(aca->aca_next)) {
|
||||
for (aca = ac_dereference(idev->ac_list, idev); aca;
|
||||
aca = ac_dereference(aca->aca_next, idev)) {
|
||||
if (ipv6_addr_equal(&aca->aca_addr, addr))
|
||||
break;
|
||||
prev_aca = aca;
|
||||
|
|
@ -429,7 +428,7 @@ void ipv6_ac_destroy_dev(struct inet6_dev *idev)
|
|||
struct ifacaddr6 *aca;
|
||||
|
||||
write_lock_bh(&idev->lock);
|
||||
while ((aca = rtnl_dereference(idev->ac_list)) != NULL) {
|
||||
while ((aca = ac_dereference(idev->ac_list, idev)) != NULL) {
|
||||
rcu_assign_pointer(idev->ac_list, aca->aca_next);
|
||||
write_unlock_bh(&idev->lock);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user