On Mon, Jun 03, 2024 at 10:58:18AM +0200, Toke Høiland-Jørgensen wrote: > Eric Dumazet <edumazet@xxxxxxxxxx> writes: > > > On Mon, Jun 3, 2024 at 9:30 AM Toke Høiland-Jørgensen <toke@xxxxxxxxxx> wrote: > >> > >> Eric Dumazet <edumazet@xxxxxxxxxx> writes: > >> > >> > On Wed, May 29, 2024 at 1:21 PM Petr Machata <petrm@xxxxxxxxxx> wrote: > >> >> > >> >> When calculating hashes for the purpose of multipath forwarding, both IPv4 > >> >> and IPv6 code currently fall back on flow_hash_from_keys(). That uses a > >> >> randomly-generated seed. That's a fine choice by default, but unfortunately > >> >> some deployments may need a tighter control over the seed used. > >> >> > >> >> In this patch, make the seed configurable by adding a new sysctl key, > >> >> net.ipv4.fib_multipath_hash_seed to control the seed. This seed is used > >> >> specifically for multipath forwarding and not for the other concerns that > >> >> flow_hash_from_keys() is used for, such as queue selection. Expose the knob > >> >> as sysctl because other such settings, such as headers to hash, are also > >> >> handled that way. Like those, the multipath hash seed is a per-netns > >> >> variable. > >> >> > >> >> Despite being placed in the net.ipv4 namespace, the multipath seed sysctl > >> >> is used for both IPv4 and IPv6, similarly to e.g. a number of TCP > >> >> variables. > >> >> > >> > ... > >> > > >> >> + rtnl_lock(); > >> >> + old = rcu_replace_pointer_rtnl(net->ipv4.sysctl_fib_multipath_hash_seed, > >> >> + mphs); > >> >> + rtnl_unlock(); > >> >> + > >> > > >> > In case you keep RCU for the next version, please do not use rtnl_lock() here. > >> > > >> > A simple xchg() will work just fine. > >> > > >> > old = xchg((__force struct struct sysctl_fib_multipath_hash_seed > >> > **)&net->ipv4.sysctl_fib_multipath_hash_seed, > >> > mphs); > >> > >> We added a macro to do this kind of thing without triggering any of the > >> RCU type linter warnings, in: > >> > >> 76c8eaafe4f0 ("rcu: Create an unrcu_pointer() to remove __rcu from a pointer") > >> > >> So as an alternative to open-coding the cast, something like this could > >> work - I guess it's mostly a matter of taste: > >> > >> old = unrcu_pointer(xchg(&net->ipv4.sysctl_fib_multipath_hash_seed, RCU_INITIALIZER(mphs))); > > > > Good to know, thanks. > > > > Not sure why __kernel qualifier has been put there. > > Not sure either. Paul, care to enlighten us? :) Because __kernel says "just plain kernel access". Here are the options: # define __kernel __attribute__((address_space(0))) # define __user __attribute__((noderef, address_space(__user))) # define __iomem __attribute__((noderef, address_space(__iomem))) # define __percpu __attribute__((noderef, address_space(__percpu))) # define __rcu __attribute__((noderef, address_space(__rcu))) So casting to __kernel removes the __rcu, thus avoiding the sparse complaint. Thanx, Paul