Skip to content

Commit

Permalink
mptcp: pm: lockless list traversal to dump endpoints
Browse files Browse the repository at this point in the history
To return an endpoint to the userspace via Netlink, and to dump all of
them, the endpoint list was iterated while holding the pernet->lock, but
only to read the content of the list.

In these cases, the spin locks can be replaced by RCU read ones, and use
the _rcu variants to iterate over the entries list in a lockless way.

Note that the __lookup_addr_by_id() helper has been modified to use the
_rcu variants of list_for_each_entry(), but with an extra conditions, so
it can be called either while the RCU read lock is held, or when the
associated pernet->lock is held.

Signed-off-by: Matthieu Baerts (NGI0) <[email protected]>
  • Loading branch information
matttbe authored and intel-lab-lkp committed Nov 7, 2024
1 parent 887a8ea commit d4e415f
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions net/mptcp/pm_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,8 @@ __lookup_addr_by_id(struct pm_nl_pernet *pernet, unsigned int id)
{
struct mptcp_pm_addr_entry *entry;

list_for_each_entry(entry, &pernet->local_addr_list, list) {
list_for_each_entry_rcu(entry, &pernet->local_addr_list, list,
lockdep_is_held(&pernet->lock)) {
if (entry->addr.id == id)
return entry;
}
Expand Down Expand Up @@ -1824,7 +1825,7 @@ int mptcp_pm_nl_get_addr(struct sk_buff *skb, struct genl_info *info)
goto fail;
}

spin_lock_bh(&pernet->lock);
rcu_read_lock();
entry = __lookup_addr_by_id(pernet, addr.addr.id);
if (!entry) {
GENL_SET_ERR_MSG(info, "address not found");
Expand All @@ -1838,11 +1839,11 @@ int mptcp_pm_nl_get_addr(struct sk_buff *skb, struct genl_info *info)

genlmsg_end(msg, reply);
ret = genlmsg_reply(msg, info);
spin_unlock_bh(&pernet->lock);
rcu_read_unlock();
return ret;

unlock_fail:
spin_unlock_bh(&pernet->lock);
rcu_read_unlock();

fail:
nlmsg_free(msg);
Expand All @@ -1866,7 +1867,7 @@ int mptcp_pm_nl_dump_addr(struct sk_buff *msg,

pernet = pm_nl_get_pernet(net);

spin_lock_bh(&pernet->lock);
rcu_read_lock();
for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
if (test_bit(i, pernet->id_bitmap)) {
entry = __lookup_addr_by_id(pernet, i);
Expand All @@ -1891,7 +1892,7 @@ int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
genlmsg_end(msg, hdr);
}
}
spin_unlock_bh(&pernet->lock);
rcu_read_unlock();

cb->args[0] = id;
return msg->len;
Expand Down

0 comments on commit d4e415f

Please sign in to comment.