Re: [PATCH] rcu: tree: correctly handle sparse possible CPUs

From: Paul E. McKenney
Date: Wed May 18 2016 - 14:02:00 EST


On Wed, May 18, 2016 at 06:15:23PM +0300, Andrey Ryabinin wrote:
> 2016-05-16 19:48 GMT+03:00 Mark Rutland <mark.rutland@xxxxxxx>:
>
> > /*
> > + * Iterate over all possible CPUs in a leaf RCU node.
> > + */
> > +#define for_each_leaf_node_possible_cpu(rnp, cpu) \
> > + for ((cpu) = rnp->grplo; \
> > + cpu <= rnp->grphi; \
> > + cpu = cpumask_next((cpu), cpu_possible_mask))
> > +
> > +/*
> > + * Iterate over all possible CPUs in a leaf RCU node, at each step providing a
> > + * bit for comparison against rcu_node bitmasks.
> > + */
> > +#define for_each_leaf_node_possible_cpu_bit(rnp, cpu, bit) \
> > + for ((cpu) = rnp->grplo, (bit) = 1; \
> > + cpu <= rnp->grphi; \
> > + cpu = cpumask_next((cpu), cpu_possible_mask), \
> > + (bit) = 1UL << (cpu - rnp->grplo))
> > +
>
> [ 0.163652] UBSAN: Undefined behaviour in ../kernel/rcu/tree.c:2912:3
> [ 0.164000] shift exponent 64 is too large for 64-bit type 'long
> unsigned int'

Ah, dead value, but can happen nevertheless. One fix is to prevent the
assignment to bit when cpu > rnp->grphi.

Any ideas for a better fix? And isn't there some combination of
signedness that makes shifting all the bits out of the value defined
to zero? Or is that only for right shifts?

Thanx, Paul