]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ipmr: Convert mr_table.cache_resolve_queue_len to u32.
authorKuniyuki Iwashima <kuniyu@google.com>
Tue, 9 Jun 2026 22:20:04 +0000 (22:20 +0000)
committerJakub Kicinski <kuba@kernel.org>
Thu, 11 Jun 2026 22:17:30 +0000 (15:17 -0700)
mr_table.cache_resolve_queue_len is always updated under
spin_lock_bh(&mfc_unres_lock).

Let's convert it to u32.

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260609222013.1550355-1-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/linux/mroute_base.h
net/ipv4/ipmr.c
net/ipv6/ip6mr.c

index 5d75cc5b057eeead07111d37907833b999fb1ee0..4d55827e970537aff6938503a39ee3306c8fde6d 100644 (file)
@@ -256,7 +256,7 @@ struct mr_table {
        struct rhltable         mfc_hash;
        struct list_head        mfc_cache_list;
        int                     maxvif;
-       atomic_t                cache_resolve_queue_len;
+       u32                     cache_resolve_queue_len;
        bool                    mroute_do_assert;
        bool                    mroute_do_pim;
        bool                    mroute_do_wrvifwhole;
index 78dbeecf71bbcc5a31bae2ff15fb71aa038cab24..1d9a4ac14fcef9cea5e35fc5a71a81f261ddd335 100644 (file)
@@ -761,7 +761,8 @@ static void ipmr_destroy_unres(struct mr_table *mrt, struct mfc_cache *c)
        struct sk_buff *skb;
        struct nlmsgerr *e;
 
-       atomic_dec(&mrt->cache_resolve_queue_len);
+       WRITE_ONCE(mrt->cache_resolve_queue_len,
+                  mrt->cache_resolve_queue_len - 1);
 
        while ((skb = skb_dequeue(&c->_c.mfc_un.unres.unresolved))) {
                if (ip_hdr(skb)->version == 0) {
@@ -1180,11 +1181,12 @@ static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi,
                if (err < 0)
                        goto err;
 
-               atomic_inc(&mrt->cache_resolve_queue_len);
+               WRITE_ONCE(mrt->cache_resolve_queue_len,
+                          mrt->cache_resolve_queue_len + 1);
                list_add(&c->_c.list, &mrt->mfc_unres_queue);
                mroute_netlink_event(mrt, c, RTM_NEWROUTE);
 
-               if (atomic_read(&mrt->cache_resolve_queue_len) == 1)
+               if (mrt->cache_resolve_queue_len == 1)
                        mod_timer(&mrt->ipmr_expire_timer,
                                  c->_c.mfc_un.unres.expires);
        }
@@ -1297,7 +1299,8 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
                if (uc->mfc_origin == c->mfc_origin &&
                    uc->mfc_mcastgrp == c->mfc_mcastgrp) {
                        list_del(&_uc->list);
-                       atomic_dec(&mrt->cache_resolve_queue_len);
+                       WRITE_ONCE(mrt->cache_resolve_queue_len,
+                                  mrt->cache_resolve_queue_len - 1);
                        found = true;
                        break;
                }
@@ -1356,7 +1359,7 @@ static void mroute_clean_tables(struct mr_table *mrt, int flags,
        }
 
        if (flags & MRT_FLUSH_MFC) {
-               if (atomic_read(&mrt->cache_resolve_queue_len) != 0 || !check_net(net)) {
+               if (READ_ONCE(mrt->cache_resolve_queue_len) || !check_net(net)) {
                        spin_lock_bh(&mfc_unres_lock);
                        list_for_each_entry_safe(c, tmp, &mrt->mfc_unres_queue, list) {
                                list_del(&c->list);
@@ -2962,10 +2965,9 @@ static int ipmr_rtm_route(struct sk_buff *skb, struct nlmsghdr *nlh,
 
 static bool ipmr_fill_table(struct mr_table *mrt, struct sk_buff *skb)
 {
-       u32 queue_len = atomic_read(&mrt->cache_resolve_queue_len);
-
        if (nla_put_u32(skb, IPMRA_TABLE_ID, mrt->id) ||
-           nla_put_u32(skb, IPMRA_TABLE_CACHE_RES_QUEUE_LEN, queue_len) ||
+           nla_put_u32(skb, IPMRA_TABLE_CACHE_RES_QUEUE_LEN,
+                       READ_ONCE(mrt->cache_resolve_queue_len)) ||
            nla_put_s32(skb, IPMRA_TABLE_MROUTE_REG_VIF_NUM,
                        READ_ONCE(mrt->mroute_reg_vif_num)) ||
            nla_put_u8(skb, IPMRA_TABLE_MROUTE_DO_ASSERT,
index 5a4816225fb1b9fecb7fca93556ec10654c649d0..604a58838901a74712d08505c6bbbdeafd28149c 100644 (file)
@@ -817,7 +817,8 @@ static void ip6mr_destroy_unres(struct mr_table *mrt, struct mfc6_cache *c)
        struct net *net = read_pnet(&mrt->net);
        struct sk_buff *skb;
 
-       atomic_dec(&mrt->cache_resolve_queue_len);
+       WRITE_ONCE(mrt->cache_resolve_queue_len,
+                  mrt->cache_resolve_queue_len - 1);
 
        while ((skb = skb_dequeue(&c->_c.mfc_un.unres.unresolved)) != NULL) {
                if (ipv6_hdr(skb)->version == 0) {
@@ -1225,7 +1226,8 @@ static int ip6mr_cache_unresolved(struct mr_table *mrt, mifi_t mifi,
                if (err < 0)
                        goto err;
 
-               atomic_inc(&mrt->cache_resolve_queue_len);
+               WRITE_ONCE(mrt->cache_resolve_queue_len,
+                          mrt->cache_resolve_queue_len + 1);
                list_add(&c->_c.list, &mrt->mfc_unres_queue);
                mr6_netlink_event(mrt, c, RTM_NEWROUTE);
 
@@ -1538,7 +1540,8 @@ static int ip6mr_mfc_add(struct net *net, struct mr_table *mrt,
                if (ipv6_addr_equal(&uc->mf6c_origin, &c->mf6c_origin) &&
                    ipv6_addr_equal(&uc->mf6c_mcastgrp, &c->mf6c_mcastgrp)) {
                        list_del(&_uc->list);
-                       atomic_dec(&mrt->cache_resolve_queue_len);
+                       WRITE_ONCE(mrt->cache_resolve_queue_len,
+                                  mrt->cache_resolve_queue_len - 1);
                        found = true;
                        break;
                }
@@ -1599,8 +1602,7 @@ static void mroute_clean_tables(struct mr_table *mrt, int flags,
        }
 
        if (flags & MRT6_FLUSH_MFC) {
-               if (atomic_read(&mrt->cache_resolve_queue_len) != 0 ||
-                   !check_net(net)) {
+               if (READ_ONCE(mrt->cache_resolve_queue_len) || !check_net(net)) {
                        spin_lock_bh(&mfc_unres_lock);
                        list_for_each_entry_safe(c, tmp, &mrt->mfc_unres_queue, list) {
                                list_del(&c->list);