Commit b8b7ed1e authored by Kuniyuki Iwashima's avatar Kuniyuki Iwashima Committed by Jakub Kicinski
Browse files

neighbour: Drop read_lock_bh(&tbl->lock) in pneigh_lookup().



Now, all callers of pneigh_lookup() are under RCU, and the read
lock there is no longer needed.

Let's drop the lock, inline __pneigh_lookup_1() to pneigh_lookup(),
and call it from pneigh_create().

The next patch will remove tbl->lock from pneigh_create().

Signed-off-by: default avatarKuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20250716221221.442239-14-kuniyu@google.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent dd103c9a
Loading
Loading
Loading
Loading
+16 −27
Original line number Diff line number Diff line
@@ -720,23 +720,6 @@ static u32 pneigh_hash(const void *pkey, unsigned int key_len)
	return hash_val;
}

static struct pneigh_entry *__pneigh_lookup_1(struct pneigh_entry *n,
					      struct net *net,
					      const void *pkey,
					      unsigned int key_len,
					      struct net_device *dev)
{
	while (n) {
		if (!memcmp(n->key, pkey, key_len) &&
		    net_eq(pneigh_net(n), net) &&
		    (n->dev == dev || !n->dev))
			return n;

		n = rcu_dereference_protected(n->next, 1);
	}
	return NULL;
}

struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl,
				   struct net *net, const void *pkey,
				   struct net_device *dev)
@@ -747,13 +730,19 @@ struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl,

	key_len = tbl->key_len;
	hash_val = pneigh_hash(pkey, key_len);
	n = rcu_dereference_check(tbl->phash_buckets[hash_val],
				  lockdep_is_held(&tbl->lock));

	read_lock_bh(&tbl->lock);
	n = __pneigh_lookup_1(rcu_dereference_protected(tbl->phash_buckets[hash_val], 1),
			      net, pkey, key_len, dev);
	read_unlock_bh(&tbl->lock);

	while (n) {
		if (!memcmp(n->key, pkey, key_len) &&
		    net_eq(pneigh_net(n), net) &&
		    (n->dev == dev || !n->dev))
			return n;

		n = rcu_dereference_check(n->next, lockdep_is_held(&tbl->lock));
	}

	return NULL;
}
EXPORT_IPV6_MOD(pneigh_lookup);

@@ -762,19 +751,18 @@ struct pneigh_entry *pneigh_create(struct neigh_table *tbl,
				   struct net_device *dev)
{
	struct pneigh_entry *n;
	unsigned int key_len = tbl->key_len;
	u32 hash_val = pneigh_hash(pkey, key_len);
	unsigned int key_len;
	u32 hash_val;

	ASSERT_RTNL();

	read_lock_bh(&tbl->lock);
	n = __pneigh_lookup_1(rcu_dereference_protected(tbl->phash_buckets[hash_val], 1),
			      net, pkey, key_len, dev);
	n = pneigh_lookup(tbl, net, pkey, dev);
	read_unlock_bh(&tbl->lock);

	if (n)
		goto out;

	key_len = tbl->key_len;
	n = kzalloc(sizeof(*n) + key_len, GFP_KERNEL);
	if (!n)
		goto out;
@@ -791,6 +779,7 @@ struct pneigh_entry *pneigh_create(struct neigh_table *tbl,
		goto out;
	}

	hash_val = pneigh_hash(pkey, key_len);
	write_lock_bh(&tbl->lock);
	n->next = tbl->phash_buckets[hash_val];
	rcu_assign_pointer(tbl->phash_buckets[hash_val], n);