Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'mptcp-pm-lockless-list-traversal-and-cleanup'

Matthieu Baerts says:

====================
mptcp: pm: lockless list traversal and cleanup

Here are two patches improving the MPTCP in-kernel path-manager.

- Patch 1: the get and dump endpoints operations are iterating over the
endpoints list in a lockless way.

- Patch 2: reduce the code duplication to lookup an endpoint.
====================

Link: https://patch.msgid.link/20241115-net-next-mptcp-pm-lockless-dump-v1-0-f4a1bcb4ca2c@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+13 -20
+13 -20
net/mptcp/pm_netlink.c
··· 512 512 { 513 513 struct mptcp_pm_addr_entry *entry; 514 514 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)) { 516 517 if (entry->addr.id == id) 517 518 return entry; 518 519 } ··· 1143 1142 { 1144 1143 struct mptcp_pm_addr_entry *entry; 1145 1144 struct pm_nl_pernet *pernet; 1146 - int ret = -1; 1145 + int ret; 1147 1146 1148 1147 pernet = pm_nl_get_pernet_from_msk(msk); 1149 1148 1150 1149 rcu_read_lock(); 1151 - list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) { 1152 - if (mptcp_addresses_equal(&entry->addr, skc, entry->addr.port)) { 1153 - ret = entry->addr.id; 1154 - break; 1155 - } 1156 - } 1150 + entry = __lookup_addr(pernet, skc); 1151 + ret = entry ? entry->addr.id : -1; 1157 1152 rcu_read_unlock(); 1158 1153 if (ret >= 0) 1159 1154 return ret; ··· 1176 1179 { 1177 1180 struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk); 1178 1181 struct mptcp_pm_addr_entry *entry; 1179 - bool backup = false; 1182 + bool backup; 1180 1183 1181 1184 rcu_read_lock(); 1182 - list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) { 1183 - if (mptcp_addresses_equal(&entry->addr, skc, entry->addr.port)) { 1184 - backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP); 1185 - break; 1186 - } 1187 - } 1185 + entry = __lookup_addr(pernet, skc); 1186 + backup = entry && !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP); 1188 1187 rcu_read_unlock(); 1189 1188 1190 1189 return backup; ··· 1817 1824 goto fail; 1818 1825 } 1819 1826 1820 - spin_lock_bh(&pernet->lock); 1827 + rcu_read_lock(); 1821 1828 entry = __lookup_addr_by_id(pernet, addr.addr.id); 1822 1829 if (!entry) { 1823 1830 GENL_SET_ERR_MSG(info, "address not found"); ··· 1831 1838 1832 1839 genlmsg_end(msg, reply); 1833 1840 ret = genlmsg_reply(msg, info); 1834 - spin_unlock_bh(&pernet->lock); 1841 + rcu_read_unlock(); 1835 1842 return ret; 1836 1843 1837 1844 unlock_fail: 1838 - spin_unlock_bh(&pernet->lock); 1845 + rcu_read_unlock(); 1839 1846 1840 1847 fail: 1841 1848 nlmsg_free(msg); ··· 1859 1866 1860 1867 pernet = pm_nl_get_pernet(net); 1861 1868 1862 - spin_lock_bh(&pernet->lock); 1869 + rcu_read_lock(); 1863 1870 for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) { 1864 1871 if (test_bit(i, pernet->id_bitmap)) { 1865 1872 entry = __lookup_addr_by_id(pernet, i); ··· 1884 1891 genlmsg_end(msg, hdr); 1885 1892 } 1886 1893 } 1887 - spin_unlock_bh(&pernet->lock); 1894 + rcu_read_unlock(); 1888 1895 1889 1896 cb->args[0] = id; 1890 1897 return msg->len;