Skip to content

Commit d4e415f

Browse files
matttbeintel-lab-lkp
authored andcommitted
mptcp: pm: lockless list traversal to dump endpoints
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]>
1 parent 887a8ea commit d4e415f

File tree

1 file changed

+7
-6
lines changed

1 file changed

+7
-6
lines changed

net/mptcp/pm_netlink.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,8 @@ __lookup_addr_by_id(struct pm_nl_pernet *pernet, unsigned int id)
512512
{
513513
struct mptcp_pm_addr_entry *entry;
514514

515-
list_for_each_entry(entry, &pernet->local_addr_list, list) {
515+
list_for_each_entry_rcu(entry, &pernet->local_addr_list, list,
516+
lockdep_is_held(&pernet->lock)) {
516517
if (entry->addr.id == id)
517518
return entry;
518519
}
@@ -1824,7 +1825,7 @@ int mptcp_pm_nl_get_addr(struct sk_buff *skb, struct genl_info *info)
18241825
goto fail;
18251826
}
18261827

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

18391840
genlmsg_end(msg, reply);
18401841
ret = genlmsg_reply(msg, info);
1841-
spin_unlock_bh(&pernet->lock);
1842+
rcu_read_unlock();
18421843
return ret;
18431844

18441845
unlock_fail:
1845-
spin_unlock_bh(&pernet->lock);
1846+
rcu_read_unlock();
18461847

18471848
fail:
18481849
nlmsg_free(msg);
@@ -1866,7 +1867,7 @@ int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
18661867

18671868
pernet = pm_nl_get_pernet(net);
18681869

1869-
spin_lock_bh(&pernet->lock);
1870+
rcu_read_lock();
18701871
for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
18711872
if (test_bit(i, pernet->id_bitmap)) {
18721873
entry = __lookup_addr_by_id(pernet, i);
@@ -1891,7 +1892,7 @@ int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
18911892
genlmsg_end(msg, hdr);
18921893
}
18931894
}
1894-
spin_unlock_bh(&pernet->lock);
1895+
rcu_read_unlock();
18951896

18961897
cb->args[0] = id;
18971898
return msg->len;

0 commit comments

Comments
 (0)