Hello,On Mon, 18 May 2026, Rosen Penev wrote: > Store the Maglev hash lookup table in the scheduler state > allocation instead of allocating it separately. > > This keeps the lookup table tied to the RCU-freed state lifetime and > simplifies the allocation and cleanup paths. > > Assisted-by: Codex:GPT-5.5 > Signed-off-by: Rosen Penev <[email protected]> > --- > net/netfilter/ipvs/ip_vs_mh.c | 11 ++--------- > 1 file changed, 2 insertions(+), 9 deletions(-) > > diff --git a/net/netfilter/ipvs/ip_vs_mh.c b/net/netfilter/ipvs/ip_vs_mh.c > index 020863047562..d31d3c6d4216 100644 > --- a/net/netfilter/ipvs/ip_vs_mh.c > +++ b/net/netfilter/ipvs/ip_vs_mh.c > @@ -59,11 +59,11 @@ static int primes[] = {251, 509, 1021, 2039, 4093, > > struct ip_vs_mh_state { > struct rcu_head rcu_head; > - struct ip_vs_mh_lookup *lookup; > struct ip_vs_mh_dest_setup *dest_setup; > hsiphash_key_t hash1, hash2; > int gcd; > int rshift; > + struct ip_vs_mh_lookup lookup[]; > }; > > static inline void generate_hash_secret(hsiphash_key_t *hash1, > @@ -372,7 +372,6 @@ static void ip_vs_mh_state_free(struct rcu_head *head) We can even drop this function and replace it with kfree(s) in ip_vs_mh_init_svc() and with kfree_rcu(s, rcu_head) in ip_vs_mh_done_svc(), you can see ip_vs_dh.c for reference... > struct ip_vs_mh_state *s; > > s = container_of(head, struct ip_vs_mh_state, rcu_head); > - kfree(s->lookup); > kfree(s); > } > > @@ -382,16 +381,10 @@ static int ip_vs_mh_init_svc(struct ip_vs_service *svc) > struct ip_vs_mh_state *s; > > /* Allocate the MH table for this service */ > - s = kzalloc_obj(*s); > + s = kzalloc_flex(*s, lookup, IP_VS_MH_TAB_SIZE); > if (!s) > return -ENOMEM; > > - s->lookup = kzalloc_objs(struct ip_vs_mh_lookup, IP_VS_MH_TAB_SIZE); > - if (!s->lookup) { > - kfree(s); > - return -ENOMEM; > - } > - > generate_hash_secret(&s->hash1, &s->hash2); > s->gcd = ip_vs_mh_gcd_weight(svc); > s->rshift = ip_vs_mh_shift_weight(svc, s->gcd); > -- > 2.54.0 Regards -- Julian Anastasov <[email protected]>

