goto unlock;
        if (dev_boot_phase)
                goto unlock;
+       down_read(&net_rwsem);
        for_each_net(net) {
                for_each_netdev(net, dev) {
                        err = call_netdevice_notifier(nb, NETDEV_REGISTER, dev);
                        call_netdevice_notifier(nb, NETDEV_UP, dev);
                }
        }
+       up_read(&net_rwsem);
 
 unlock:
        rtnl_unlock();
        }
 
 outroll:
+       up_read(&net_rwsem);
        raw_notifier_chain_unregister(&netdev_chain, nb);
        goto unlock;
 }
        if (err)
                goto unlock;
 
+       down_read(&net_rwsem);
        for_each_net(net) {
                for_each_netdev(net, dev) {
                        if (dev->flags & IFF_UP) {
                        call_netdevice_notifier(nb, NETDEV_UNREGISTER, dev);
                }
        }
+       up_read(&net_rwsem);
 unlock:
        rtnl_unlock();
        return err;
 
 LIST_HEAD(net_namespace_list);
 EXPORT_SYMBOL_GPL(net_namespace_list);
 
+/* Protects net_namespace_list. Nests iside rtnl_lock() */
+DECLARE_RWSEM(net_rwsem);
+EXPORT_SYMBOL_GPL(net_rwsem);
+
 struct net init_net = {
        .count          = REFCOUNT_INIT(1),
        .dev_base_head  = LIST_HEAD_INIT(init_net.dev_base_head),
                if (error < 0)
                        goto out_undo;
        }
-       rtnl_lock();
+       down_write(&net_rwsem);
        list_add_tail_rcu(&net->list, &net_namespace_list);
-       rtnl_unlock();
+       up_write(&net_rwsem);
 out:
        return error;
 
         * and this work is the only process, that may delete
         * a net from net_namespace_list. So, when the below
         * is executing, the list may only grow. Thus, we do not
-        * use for_each_net_rcu() or rtnl_lock().
+        * use for_each_net_rcu() or net_rwsem.
         */
        for_each_net(tmp) {
                int id;
        down_read(&pernet_ops_rwsem);
 
        /* Don't let anyone else find us. */
-       rtnl_lock();
+       down_write(&net_rwsem);
        llist_for_each_entry(net, net_kill_list, cleanup_list)
                list_del_rcu(&net->list);
        /* Cache last net. After we unlock rtnl, no one new net
         * useless anyway, as netns_ids are destroyed there.
         */
        last = list_last_entry(&net_namespace_list, struct net, list);
-       rtnl_unlock();
+       up_write(&net_rwsem);
 
        llist_for_each_entry(net, net_kill_list, cleanup_list) {
                unhash_nsid(net, last);
 
        list_add_tail(&ops->list, list);
        if (ops->init || (ops->id && ops->size)) {
+               /* We held write locked pernet_ops_rwsem, and parallel
+                * setup_net() and cleanup_net() are not possible.
+                */
                for_each_net(net) {
                        error = ops_init(ops, net);
                        if (error)
        LIST_HEAD(net_exit_list);
 
        list_del(&ops->list);
+       /* See comment in __register_pernet_operations() */
        for_each_net(net)
                list_add_tail(&net->exit_list, &net_exit_list);
        ops_exit_list(ops, &net_exit_list);