Commit 610a689d authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'rtnl-rcu'



Pedro Tammela says:

====================
net: rtnl: introduce rcu_replace_pointer_rtnl

Introduce the rcu_replace_pointer_rtnl helper to lockdep check rtnl lock
rcu replacements, alongside the already existing helpers.

Patch 2 uses the new helper in the rtnl_unregister_* functions.

Originally this change was part of the P4TC series, as it's a recurrent
pattern there, but since it has a use case in mainline we are pushing it
separately.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 54f4c257 17452347
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -79,6 +79,18 @@ static inline bool lockdep_rtnl_is_held(void)
#define rtnl_dereference(p)					\
	rcu_dereference_protected(p, lockdep_rtnl_is_held())

/**
 * rcu_replace_pointer_rtnl - replace an RCU pointer under rtnl_lock, returning
 * its old value
 * @rp: RCU pointer, whose value is returned
 * @p: regular pointer
 *
 * Perform a replacement under rtnl_lock, where @rp is an RCU-annotated
 * pointer. The old value of @rp is returned, and @rp is set to @p
 */
#define rcu_replace_pointer_rtnl(rp, p)			\
	rcu_replace_pointer(rp, p, lockdep_rtnl_is_held())

static inline struct netdev_queue *dev_ingress_queue(struct net_device *dev)
{
	return rtnl_dereference(dev->ingress_queue);
+3 −9
Original line number Diff line number Diff line
@@ -342,8 +342,7 @@ int rtnl_unregister(int protocol, int msgtype)
		return -ENOENT;
	}

	link = rtnl_dereference(tab[msgindex]);
	RCU_INIT_POINTER(tab[msgindex], NULL);
	link = rcu_replace_pointer_rtnl(tab[msgindex], NULL);
	rtnl_unlock();

	kfree_rcu(link, rcu);
@@ -368,18 +367,13 @@ void rtnl_unregister_all(int protocol)
	BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX);

	rtnl_lock();
	tab = rtnl_dereference(rtnl_msg_handlers[protocol]);
	tab = rcu_replace_pointer_rtnl(rtnl_msg_handlers[protocol], NULL);
	if (!tab) {
		rtnl_unlock();
		return;
	}
	RCU_INIT_POINTER(rtnl_msg_handlers[protocol], NULL);
	for (msgindex = 0; msgindex < RTM_NR_MSGTYPES; msgindex++) {
		link = rtnl_dereference(tab[msgindex]);
		if (!link)
			continue;

		RCU_INIT_POINTER(tab[msgindex], NULL);
		link = rcu_replace_pointer_rtnl(tab[msgindex], NULL);
		kfree_rcu(link, rcu);
	}
	rtnl_unlock();