ipv6: convert fib6_ref to refcount_t
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 <edumazet@google.com> Cc: Wei Wang <weiwan@google.com> Acked-by: Wei Wang <weiwan@google.com> Reviewed-by: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
5ea715289a
commit
f05713e091
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue