On Mon, Mar 08, 2021 at 07:47:31PM -0700, David Ahern wrote: > [ cc Ido and Petr ] > > On 3/8/21 12:21 PM, Wei Wang wrote: > > diff --git a/include/net/nexthop.h b/include/net/nexthop.h > > index 7bc057aee40b..48956b144689 100644 > > --- a/include/net/nexthop.h > > +++ b/include/net/nexthop.h > > @@ -410,31 +410,39 @@ static inline struct fib_nh *fib_info_nh(struct > > fib_info *fi, int nhsel) > > int fib6_check_nexthop(struct nexthop *nh, struct fib6_config *cfg, > > struct netlink_ext_ack *extack); > > > > -static inline struct fib6_nh *nexthop_fib6_nh(struct nexthop *nh) > > +static inline struct fib6_nh *nexthop_fib6_nh(struct nexthop *nh, > > + bool bh_disabled) > > Hi Wei: I would prefer not to have a second argument to nexthop_fib6_nh > for 1 code path, and a control path at that. > > > { > > struct nh_info *nhi; > > > > if (nh->is_group) { > > struct nh_group *nh_grp; > > > > - nh_grp = rcu_dereference_rtnl(nh->nh_grp); > > + if (bh_disabled) > > + nh_grp = rcu_dereference_bh_rtnl(nh->nh_grp); > > + else > > + nh_grp = rcu_dereference_rtnl(nh->nh_grp); > > nh = nexthop_mpath_select(nh_grp, 0); > > if (!nh) > > return NULL; > > } > > > > - nhi = rcu_dereference_rtnl(nh->nh_info); > > + if (bh_disabled) > > + nhi = rcu_dereference_bh_rtnl(nh->nh_info); > > + else > > + nhi = rcu_dereference_rtnl(nh->nh_info); > > if (nhi->family == AF_INET6) > > return &nhi->fib6_nh; > > > > return NULL; > > } > > > > I am wary of duplicating code, but this helper is simple enough that it > should be ok with proper documentation. > > Ido/Petr: I think your resilient hashing patch set touches this helper. > How ugly does it get to have a second version?
It actually doesn't touch this helper. Looks fine to me: diff --git a/include/net/nexthop.h b/include/net/nexthop.h index ba94868a21d5..6df9c12546fd 100644 --- a/include/net/nexthop.h +++ b/include/net/nexthop.h @@ -496,6 +496,26 @@ static inline struct fib6_nh *nexthop_fib6_nh(struct nexthop *nh) return NULL; } +static inline struct fib6_nh *nexthop_fib6_nh_bh(struct nexthop *nh) +{ + struct nh_info *nhi; + + if (nh->is_group) { + struct nh_group *nh_grp; + + nh_grp = rcu_dereference_bh(nh->nh_grp); + nh = nexthop_mpath_select(nh_grp, 0); + if (!nh) + return NULL; + } + + nhi = rcu_dereference_bh(nh->nh_info); + if (nhi->family == AF_INET6) + return &nhi->fib6_nh; + + return NULL; +} + static inline struct net_device *fib6_info_nh_dev(struct fib6_info *f6i) { struct fib6_nh *fib6_nh; diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index ef9d022e693f..679699e953f1 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -2486,7 +2486,7 @@ static int ipv6_route_native_seq_show(struct seq_file *seq, void *v) const struct net_device *dev; if (rt->nh) - fib6_nh = nexthop_fib6_nh(rt->nh); + fib6_nh = nexthop_fib6_nh_bh(rt->nh); seq_printf(seq, "%pi6 %02x ", &rt->fib6_dst.addr, rt->fib6_dst.plen);