Commit 51e13685 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller
Browse files

rtnetlink: RCU-annotate both dimensions of rtnl_msg_handlers



We use rcu_assign_pointer to assign both the table and the entries,
but the entries are not marked as __rcu. This generates sparse
warnings.

Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1d608d2e
Loading
Loading
Loading
Loading
+13 −11
Original line number Diff line number Diff line
@@ -139,7 +139,7 @@ bool lockdep_rtnl_is_held(void)
EXPORT_SYMBOL(lockdep_rtnl_is_held);
#endif /* #ifdef CONFIG_PROVE_LOCKING */

static struct rtnl_link *__rcu *rtnl_msg_handlers[RTNL_FAMILY_MAX + 1];
static struct rtnl_link __rcu *__rcu *rtnl_msg_handlers[RTNL_FAMILY_MAX + 1];

static inline int rtm_msgindex(int msgtype)
{
@@ -157,7 +157,7 @@ static inline int rtm_msgindex(int msgtype)

static struct rtnl_link *rtnl_get_link(int protocol, int msgtype)
{
	struct rtnl_link **tab;
	struct rtnl_link __rcu **tab;

	if (protocol >= ARRAY_SIZE(rtnl_msg_handlers))
		protocol = PF_UNSPEC;
@@ -166,7 +166,7 @@ static struct rtnl_link *rtnl_get_link(int protocol, int msgtype)
	if (!tab)
		tab = rcu_dereference_rtnl(rtnl_msg_handlers[PF_UNSPEC]);

	return tab[msgtype];
	return rcu_dereference_rtnl(tab[msgtype]);
}

static int rtnl_register_internal(struct module *owner,
@@ -183,7 +183,7 @@ static int rtnl_register_internal(struct module *owner,
	msgindex = rtm_msgindex(msgtype);

	rtnl_lock();
	tab = rtnl_msg_handlers[protocol];
	tab = rtnl_dereference(rtnl_msg_handlers[protocol]);
	if (tab == NULL) {
		tab = kcalloc(RTM_NR_MSGTYPES, sizeof(void *), GFP_KERNEL);
		if (!tab)
@@ -286,7 +286,8 @@ void rtnl_register(int protocol, int msgtype,
 */
int rtnl_unregister(int protocol, int msgtype)
{
	struct rtnl_link **tab, *link;
	struct rtnl_link __rcu **tab;
	struct rtnl_link *link;
	int msgindex;

	BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX);
@@ -299,7 +300,7 @@ int rtnl_unregister(int protocol, int msgtype)
		return -ENOENT;
	}

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

@@ -318,20 +319,21 @@ EXPORT_SYMBOL_GPL(rtnl_unregister);
 */
void rtnl_unregister_all(int protocol)
{
	struct rtnl_link **tab, *link;
	struct rtnl_link __rcu **tab;
	struct rtnl_link *link;
	int msgindex;

	BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX);

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

@@ -3754,7 +3756,7 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
		s_idx = 1;

	for (idx = 1; idx <= RTNL_FAMILY_MAX; idx++) {
		struct rtnl_link **tab;
		struct rtnl_link __rcu **tab;
		struct rtnl_link *link;
		rtnl_dumpit_func dumpit;

@@ -3768,7 +3770,7 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
		if (!tab)
			continue;

		link = tab[type];
		link = rcu_dereference_rtnl(tab[type]);
		if (!link)
			continue;