}
 #endif /* CONFIG_PROVE_LOCKING */
 
-/*
- * nfnl_dereference - fetch RCU pointer when updates are prevented by subsys mutex
- *
- * @p: The pointer to read, prior to dereferencing
- * @ss: The nfnetlink subsystem ID
- *
- * Return the value of the specified RCU-protected pointer, but omit
- * the READ_ONCE(), because caller holds the NFNL subsystem mutex.
- */
-#define nfnl_dereference(p, ss)                                        \
-       rcu_dereference_protected(p, lockdep_nfnl_is_held(ss))
-
 #define MODULE_ALIAS_NFNL_SUBSYS(subsys) \
        MODULE_ALIAS("nfnetlink-subsys-" __stringify(subsys))
 
 
                if (nla_put_string(skb, NFTA_CHAIN_TYPE, basechain->type->name))
                        goto nla_put_failure;
 
-               if (basechain->stats && nft_dump_stats(skb, basechain->stats))
+               if (rcu_access_pointer(basechain->stats) &&
+                   nft_dump_stats(skb, rcu_dereference(basechain->stats)))
                        goto nla_put_failure;
        }
 
        return newstats;
 }
 
-static void nft_chain_stats_replace(struct nft_base_chain *chain,
+static void nft_chain_stats_replace(struct net *net,
+                                   struct nft_base_chain *chain,
                                    struct nft_stats __percpu *newstats)
 {
        struct nft_stats __percpu *oldstats;
        if (newstats == NULL)
                return;
 
-       if (chain->stats) {
-               oldstats = nfnl_dereference(chain->stats, NFNL_SUBSYS_NFTABLES);
+       if (rcu_access_pointer(chain->stats)) {
+               oldstats = rcu_dereference_protected(chain->stats,
+                                       lockdep_commit_lock_is_held(net));
                rcu_assign_pointer(chain->stats, newstats);
                synchronize_rcu();
                free_percpu(oldstats);
                struct nft_base_chain *basechain = nft_base_chain(chain);
 
                module_put(basechain->type->owner);
-               free_percpu(basechain->stats);
-               if (basechain->stats)
+               if (rcu_access_pointer(basechain->stats)) {
                        static_branch_dec(&nft_counters_enabled);
+                       free_percpu(rcu_dereference_raw(basechain->stats));
+               }
                kfree(chain->name);
                kfree(basechain);
        } else {
                                kfree(basechain);
                                return PTR_ERR(stats);
                        }
-                       basechain->stats = stats;
+                       rcu_assign_pointer(basechain->stats, stats);
                        static_branch_inc(&nft_counters_enabled);
                }
 
                return;
 
        basechain = nft_base_chain(trans->ctx.chain);
-       nft_chain_stats_replace(basechain, nft_trans_chain_stats(trans));
+       nft_chain_stats_replace(trans->ctx.net, basechain,
+                               nft_trans_chain_stats(trans));
 
        switch (nft_trans_chain_policy(trans)) {
        case NF_DROP: