On Mon, Apr 22, 2019 at 6:35 PM Eric Dumazet <eduma...@google.com> wrote: > > We suspect some issues involving fib6_ref 0 -> 1 transitions might > cause strange syzbot reports. > > Lets convert fib6_ref to refcount_t to catch them earlier. > > Signed-off-by: Eric Dumazet <eduma...@google.com> > Cc: Wei Wang <wei...@google.com> > --- Acked-by: Wei Wang <wei...@google.com>
Thanks Eric. > include/net/ip6_fib.h | 8 ++++---- > net/ipv6/ip6_fib.c | 6 +++--- > net/ipv6/route.c | 2 +- > 3 files changed, 8 insertions(+), 8 deletions(-) > > diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h > index > 6b7557b71c8caef7785dd0c8c52dfb92cf4e8c52..355a47bfc452aa150f537522dfb77ffa50bcb9ec > 100644 > --- a/include/net/ip6_fib.h > +++ b/include/net/ip6_fib.h > @@ -146,7 +146,7 @@ struct fib6_info { > struct list_head fib6_siblings; > unsigned int fib6_nsiblings; > > - atomic_t fib6_ref; > + refcount_t fib6_ref; > unsigned long expires; > struct dst_metrics *fib6_metrics; > #define fib6_pmtu fib6_metrics->metrics[RTAX_MTU-1] > @@ -284,17 +284,17 @@ void fib6_info_destroy_rcu(struct rcu_head *head); > > static inline void fib6_info_hold(struct fib6_info *f6i) > { > - atomic_inc(&f6i->fib6_ref); > + refcount_inc(&f6i->fib6_ref); > } > > static inline bool fib6_info_hold_safe(struct fib6_info *f6i) > { > - return atomic_inc_not_zero(&f6i->fib6_ref); > + return refcount_inc_not_zero(&f6i->fib6_ref); > } > > static inline void fib6_info_release(struct fib6_info *f6i) > { > - if (f6i && atomic_dec_and_test(&f6i->fib6_ref)) > + if (f6i && refcount_dec_and_test(&f6i->fib6_ref)) > call_rcu(&f6i->rcu, fib6_info_destroy_rcu); > } > > diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c > index > a5e83593e0e45c2762eca85d04757f9d8e118e0f..a8919c217cc214821e039786492ed284552cb0b4 > 100644 > --- a/net/ipv6/ip6_fib.c > +++ b/net/ipv6/ip6_fib.c > @@ -162,7 +162,7 @@ struct fib6_info *fib6_info_alloc(gfp_t gfp_flags) > } > > INIT_LIST_HEAD(&f6i->fib6_siblings); > - atomic_set(&f6i->fib6_ref, 1); > + refcount_set(&f6i->fib6_ref, 1); > > return f6i; > } > @@ -929,7 +929,7 @@ static void fib6_purge_rt(struct fib6_info *rt, struct > fib6_node *fn, > { > struct fib6_table *table = rt->fib6_table; > > - if (atomic_read(&rt->fib6_ref) != 1) { > + if (refcount_read(&rt->fib6_ref) != 1) { > /* This route is used as dummy address holder in some split > * nodes. It is not leaked, but it still holds other > resources, > * which must be released in time. So, scan ascendant nodes > @@ -2311,7 +2311,7 @@ static int ipv6_route_seq_show(struct seq_file *seq, > void *v) > > dev = rt->fib6_nh.fib_nh_dev; > seq_printf(seq, " %08x %08x %08x %08x %8s\n", > - rt->fib6_metric, atomic_read(&rt->fib6_ref), 0, > + rt->fib6_metric, refcount_read(&rt->fib6_ref), 0, > flags, dev ? dev->name : ""); > iter->w.leaf = NULL; > return 0; > diff --git a/net/ipv6/route.c b/net/ipv6/route.c > index > e8c73b7782cdc5a2c4ca5ef50aca4c8d8556c7be..7ce14a4c3d89955d6e6468bb3cdac5efa394839b > 100644 > --- a/net/ipv6/route.c > +++ b/net/ipv6/route.c > @@ -296,7 +296,7 @@ static const struct fib6_info fib6_null_entry_template = { > .fib6_flags = (RTF_REJECT | RTF_NONEXTHOP), > .fib6_protocol = RTPROT_KERNEL, > .fib6_metric = ~(u32)0, > - .fib6_ref = ATOMIC_INIT(1), > + .fib6_ref = REFCOUNT_INIT(1), > .fib6_type = RTN_UNREACHABLE, > .fib6_metrics = (struct dst_metrics *)&dst_default_metrics, > }; > -- > 2.21.0.593.g511ec345e18-goog >