On Wed, Aug 26, 2026 at 03:20 PM -05, Chris J Arges wrote:
> rt_flush_dev() currently walks every per-CPU uncached route list for each
> device being removed. This repeatedly examines unrelated routes and makes
> teardown increasingly expensive as the number of devices grows.
>
> Replace each per-CPU list with 64 hash buckets keyed by the route's
> netdevice. Keep the owning-list pointer in dst_entry so route removal
> remains unchanged, while device teardown only walks the matching bucket on
> each CPU. Hash collisions are filtered by the existing device comparison.
>
> Signed-off-by: Chris J Arges <[email protected]>
> ---
>  net/ipv4/route.c | 36 +++++++++++++++++++++++++++++-------
>  1 file changed, 29 insertions(+), 7 deletions(-)
>
> diff --git a/net/ipv4/route.c b/net/ipv4/route.c
> index 604cc51dfd9b..3f9bc1ec72cc 100644
> --- a/net/ipv4/route.c
> +++ b/net/ipv4/route.c
> @@ -74,6 +74,7 @@
>  #include <linux/init.h>
>  #include <linux/skbuff.h>
>  #include <linux/inetdevice.h>
> +#include <linux/hash.h>
>  #include <linux/igmp.h>
>  #include <linux/pkt_sched.h>
>  #include <linux/mroute.h>
> @@ -1552,11 +1553,22 @@ struct uncached_list {
>       struct list_head        head;
>  };
>  
> -static DEFINE_PER_CPU_ALIGNED(struct uncached_list, rt_uncached_list);
> +#define RT_UNCACHED_HASH_BITS        6
> +#define RT_UNCACHED_HASH_SIZE        BIT(RT_UNCACHED_HASH_BITS)


Consider making RT[6]_UNCACHED_HASH_BITS a build time tunable.
We've had a case in the past where we had to carry a custom patch [1]
because hash size was hardcoded.

[1] 
https://lore.kernel.org/netdev/[email protected]/

> +
> +struct uncached_table {
> +     struct uncached_list buckets[RT_UNCACHED_HASH_SIZE];
> +};
> +
> +static DEFINE_PER_CPU_ALIGNED(struct uncached_table, rt_uncached_table);

[...]

Reply via email to