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); [...]

