mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-06 00:47:56 -04:00
Merge branch 'net-speedup-some-nexthop-handling-when-having-a-lot-of-nexthops'
Christoph Paasch says: ==================== net: Speedup some nexthop handling when having A LOT of nexthops Configuring a very large number of nexthops is fairly possible within a reasonable time-frame. But, certain netlink commands can become extremely slow. This series addresses some of these, namely dumping and removing nexthops. v1: https://lore.kernel.org/20250724-nexthop_dump-v1-1-6b43fffd5bac@openai.com ==================== Link: https://patch.msgid.link/20250816-nexthop_dump-v2-0-491da3462118@openai.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -2087,6 +2087,12 @@ static void remove_nexthop_from_groups(struct net *net, struct nexthop *nh,
|
||||
{
|
||||
struct nh_grp_entry *nhge, *tmp;
|
||||
|
||||
/* If there is nothing to do, let's avoid the costly call to
|
||||
* synchronize_net()
|
||||
*/
|
||||
if (list_empty(&nh->grp_list))
|
||||
return;
|
||||
|
||||
list_for_each_entry_safe(nhge, tmp, &nh->grp_list, nh_list)
|
||||
remove_nh_grp_entry(net, nhge, nlinfo);
|
||||
|
||||
@@ -3511,12 +3517,42 @@ static int rtm_dump_walk_nexthops(struct sk_buff *skb,
|
||||
int err;
|
||||
|
||||
s_idx = ctx->idx;
|
||||
for (node = rb_first(root); node; node = rb_next(node)) {
|
||||
|
||||
/* If this is not the first invocation, ctx->idx will contain the id of
|
||||
* the last nexthop we processed. Instead of starting from the very
|
||||
* first element of the red/black tree again and linearly skipping the
|
||||
* (potentially large) set of nodes with an id smaller than s_idx, walk
|
||||
* the tree and find the left-most node whose id is >= s_idx. This
|
||||
* provides an efficient O(log n) starting point for the dump
|
||||
* continuation.
|
||||
*/
|
||||
if (s_idx != 0) {
|
||||
struct rb_node *tmp = root->rb_node;
|
||||
|
||||
node = NULL;
|
||||
while (tmp) {
|
||||
struct nexthop *nh;
|
||||
|
||||
nh = rb_entry(tmp, struct nexthop, rb_node);
|
||||
if (nh->id < s_idx) {
|
||||
tmp = tmp->rb_right;
|
||||
} else {
|
||||
/* Track current candidate and keep looking on
|
||||
* the left side to find the left-most
|
||||
* (smallest id) that is still >= s_idx.
|
||||
*/
|
||||
node = tmp;
|
||||
tmp = tmp->rb_left;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
node = rb_first(root);
|
||||
}
|
||||
|
||||
for (; node; node = rb_next(node)) {
|
||||
struct nexthop *nh;
|
||||
|
||||
nh = rb_entry(node, struct nexthop, rb_node);
|
||||
if (nh->id < s_idx)
|
||||
continue;
|
||||
|
||||
ctx->idx = nh->id;
|
||||
err = nh_cb(skb, cb, nh, data);
|
||||
|
||||
Reference in New Issue
Block a user