Re: [PATCH] mm/debug: add a cast to u64 for atomic64_read()

From: Arnd Bergmann
Date: Wed Mar 13 2019 - 09:47:15 EST

On Wed, Mar 13, 2019 at 10:19 AM Peter Zijlstra <peterz@xxxxxxxxxxxxx> wrote:
> On Mon, Mar 11, 2019 at 03:20:04PM +0100, Arnd Bergmann wrote:
> > On Mon, Mar 11, 2019 at 3:00 PM Qian Cai <cai@xxxxxx> wrote:
> >
> > At least the atomic_long part we discussed there has been resolved now
> > as part of commit b5d47ef9ea5c ("locking/atomics: Switch to generated
> > atomic-long").
> >
> > Adding Mark Rutland to Cc, maybe he has some ideas of how to use
> > the infrastructure he added to use consistent types for atomic64()
> > on the remaining 64-bit architectures.
> A quick count shows there's only 5 definitions of atomic64_t in the
> tree, it would be trivial to align them on type.
> $ git grep "} atomic64_t"
> arch/arc/include/asm/atomic.h:} atomic64_t;
> arch/arm/include/asm/atomic.h:} atomic64_t;
> arch/x86/include/asm/atomic64_32.h:} atomic64_t;
> include/asm-generic/atomic64.h:} atomic64_t;
> include/linux/types.h:} atomic64_t;

Right, that would make sense as well.

> Note that the one used in _most_ cases, is the one from linux/types.h,
> and that is using 'long'. The others, all typically on ILP32 platforms,
> obviously must use long long.
> I have no objection to changing the types.h one to long long or all of
> them to s64. It really shouldn't matter at all.

I thiunk it needs an '__attribute__((aligned(8)))' annotation at least on
x86-32, but it should be harmless to do that everywhere. The
32-bit architectures of course already use a 'long long' base type
(unsigned long long on x86 and arc), but we'd still need to
change all the 64-bit architectures to consistently use s64
in their implementation. This would be the majority of the work, e.g.

static __inline__ void atomic64_##op(long a, atomic64_t *v) \

static __always_inline \
c_type atomic##prefix##_fetch_##op(c_type i, atomic##prefix##_t *v) \

long atomic64_##op##_return(long, atomic64_t *);

static inline void atomic64_##op(long i, atomic64_t *v) \

static __inline__ void atomic64_##op(long i, atomic64_t * v) \

static __inline__ long \
ia64_atomic64_##op (__s64 i, atomic64_t *v) \

static __inline__ void atomic64_##op(long i, atomic64_t * v) \

static __inline__ s64 atomic64_##op##_return(s64 i, atomic64_t *v) \

The problem is not that any of those would be hard to change,
it's more that there are so many functions across 10 architectures,
and everything has some subtle differences somewhere.

It would be tempting to use scripts/atomic/* to generate more of
the code in a consistent way, but that is likely to be even more
work and more error-prone at the start.