}
 #endif
 
-/* Processing handlers for ipmr_forward */
+/* Processing handlers for ipmr_forward, under rcu_read_lock() */
 
 static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,
                            int in_vifi, struct sk_buff *skb, int vifi)
                WRITE_ONCE(vif->bytes_out, vif->bytes_out + skb->len);
                vif_dev->stats.tx_bytes += skb->len;
                vif_dev->stats.tx_packets++;
-               rcu_read_lock();
                ipmr_cache_report(mrt, skb, vifi, IGMPMSG_WHOLEPKT);
-               rcu_read_unlock();
                goto out_free;
        }
 
 }
 
 /* "local" means that we should preserve one skb (for local delivery) */
+/* Called uner rcu_read_lock() */
 static void ip_mr_forward(struct net *net, struct mr_table *mrt,
                          struct net_device *dev, struct sk_buff *skb,
                          struct mfc_cache *c, int local)
                               c->_c.mfc_un.res.last_assert +
                               MFC_ASSERT_THRESH)) {
                        c->_c.mfc_un.res.last_assert = jiffies;
-                       rcu_read_lock();
                        ipmr_cache_report(mrt, skb, true_vifi, IGMPMSG_WRONGVIF);
                        if (mrt->mroute_do_wrvifwhole)
                                ipmr_cache_report(mrt, skb, true_vifi,
                                                  IGMPMSG_WRVIFWHOLE);
-                       rcu_read_unlock();
                }
                goto dont_forward;
        }
                return -ENODEV;
        }
 
-       read_lock(&mrt_lock);
        ip_mr_forward(net, mrt, dev, skb, cache, local);
-       read_unlock(&mrt_lock);
 
        if (local)
                return ip_local_deliver(skb);