Re: [GIT PULL] NOHZ updates for v4.6

From: Peter Zijlstra
Date: Tue Mar 15 2016 - 04:43:26 EST


On Mon, Mar 14, 2016 at 07:44:14PM -0700, Linus Torvalds wrote:
> On Mon, Mar 14, 2016 at 5:32 AM, Ingo Molnar <mingo@xxxxxxxxxx> wrote:
> > +/**
> > + * fetch_or - perform *ptr |= mask and return old value of *ptr
> > + * @ptr: pointer to value
> > + * @mask: mask to OR on the value
> > + *
> > + * cmpxchg based fetch_or, macro so it works for different integer types
> > + */
> > +#ifndef fetch_or
> > +#define fetch_or(ptr, mask) \
> > +({ typeof(*(ptr)) __old, __val = *(ptr); \
> > + for (;;) { \
> > + __old = cmpxchg((ptr), __val, __val | (mask)); \
> > + if (__old == __val) \
> > + break; \
> > + __val = __old; \
> > + } \
> > + __old; \
> > +})
> > +#endif
>
> This is garbage.
>
> This macro re-uses the "mask" argument potentially many many times, so
> semantically it's very dubious.

So the below cures that; but do we want to maybe pull this back into
sched.c and expose a version that operates on a fixed type instead?

Although with xchg() and cmpxchg() we've already set a precedence for
multi-width operators.

The whole thread_info::flags thing is rather 'special' and I'm not sure
we even want to go clean that up, I can see why 64bit arch would very
much want a 64bit flags word etc. And TIF_flags are very arch specific.

---
include/linux/atomic.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/linux/atomic.h b/include/linux/atomic.h
index 6c502cb13c95..114caf672b11 100644
--- a/include/linux/atomic.h
+++ b/include/linux/atomic.h
@@ -558,8 +558,9 @@ static inline int atomic_dec_if_positive(atomic_t *v)
#ifndef fetch_or
#define fetch_or(ptr, mask) \
({ typeof(*(ptr)) __old, __val = *(ptr); \
+ typeof(mask) __mask = (mask); \
for (;;) { \
- __old = cmpxchg((ptr), __val, __val | (mask)); \
+ __old = cmpxchg((ptr), __val, __val | __mask); \
if (__old == __val) \
break; \
__val = __old; \