d975440bf8
This change is similar to e001bbae71
ARM: cmpxchg: avoid warnings from macro-ized cmpxchg() implementations
A recent change in kernel/acct.c added a new warning for many
configurations using generic __xchg() implementation:
In file included from ./arch/nios2/include/asm/cmpxchg.h:12:0,
from include/asm-generic/atomic.h:18,
from arch/nios2/include/generated/asm/atomic.h:1,
from include/linux/atomic.h:4,
from include/linux/spinlock.h:406,
from include/linux/mmzone.h:7,
from include/linux/gfp.h:5,
from include/linux/mm.h:9,
from kernel/acct.c:46:
kernel/acct.c: In function 'acct_pin_kill':
include/asm-generic/cmpxchg.h:94:3: warning: value computed is not used [-Wunused-value]
((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
^
include/asm-generic/cmpxchg.h:102:28: note: in expansion of macro 'cmpxchg_local'
#define cmpxchg(ptr, o, n) cmpxchg_local((ptr), (o), (n))
^
kernel/acct.c:177:2: note: in expansion of macro 'cmpxchg'
cmpxchg(&acct->ns->bacct, pin, NULL);
^
The code is in fact correct, it's just a cmpxchg() call that
intentionally ignores the result, and no other code does that. The
warning does not show up on x86 because of the way that its cmpxchg()
macro is written. This changes the asm-ggeneric implementation to use
a similar construct with a compound expression instead of a typecast,
which causes the compiler to not complain about an unused result.
Fix the other macros in this file in a similar way, and place them
just below their function implementations.
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
108 lines
2.2 KiB
C
108 lines
2.2 KiB
C
/*
|
|
* Generic UP xchg and cmpxchg using interrupt disablement. Does not
|
|
* support SMP.
|
|
*/
|
|
|
|
#ifndef __ASM_GENERIC_CMPXCHG_H
|
|
#define __ASM_GENERIC_CMPXCHG_H
|
|
|
|
#ifdef CONFIG_SMP
|
|
#error "Cannot use generic cmpxchg on SMP"
|
|
#endif
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/irqflags.h>
|
|
|
|
#ifndef xchg
|
|
|
|
/*
|
|
* This function doesn't exist, so you'll get a linker error if
|
|
* something tries to do an invalidly-sized xchg().
|
|
*/
|
|
extern void __xchg_called_with_bad_pointer(void);
|
|
|
|
static inline
|
|
unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
|
|
{
|
|
unsigned long ret, flags;
|
|
|
|
switch (size) {
|
|
case 1:
|
|
#ifdef __xchg_u8
|
|
return __xchg_u8(x, ptr);
|
|
#else
|
|
local_irq_save(flags);
|
|
ret = *(volatile u8 *)ptr;
|
|
*(volatile u8 *)ptr = x;
|
|
local_irq_restore(flags);
|
|
return ret;
|
|
#endif /* __xchg_u8 */
|
|
|
|
case 2:
|
|
#ifdef __xchg_u16
|
|
return __xchg_u16(x, ptr);
|
|
#else
|
|
local_irq_save(flags);
|
|
ret = *(volatile u16 *)ptr;
|
|
*(volatile u16 *)ptr = x;
|
|
local_irq_restore(flags);
|
|
return ret;
|
|
#endif /* __xchg_u16 */
|
|
|
|
case 4:
|
|
#ifdef __xchg_u32
|
|
return __xchg_u32(x, ptr);
|
|
#else
|
|
local_irq_save(flags);
|
|
ret = *(volatile u32 *)ptr;
|
|
*(volatile u32 *)ptr = x;
|
|
local_irq_restore(flags);
|
|
return ret;
|
|
#endif /* __xchg_u32 */
|
|
|
|
#ifdef CONFIG_64BIT
|
|
case 8:
|
|
#ifdef __xchg_u64
|
|
return __xchg_u64(x, ptr);
|
|
#else
|
|
local_irq_save(flags);
|
|
ret = *(volatile u64 *)ptr;
|
|
*(volatile u64 *)ptr = x;
|
|
local_irq_restore(flags);
|
|
return ret;
|
|
#endif /* __xchg_u64 */
|
|
#endif /* CONFIG_64BIT */
|
|
|
|
default:
|
|
__xchg_called_with_bad_pointer();
|
|
return x;
|
|
}
|
|
}
|
|
|
|
#define xchg(ptr, x) ({ \
|
|
((__typeof__(*(ptr))) \
|
|
__xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))); \
|
|
})
|
|
|
|
#endif /* xchg */
|
|
|
|
/*
|
|
* Atomic compare and exchange.
|
|
*/
|
|
#include <asm-generic/cmpxchg-local.h>
|
|
|
|
#ifndef cmpxchg_local
|
|
#define cmpxchg_local(ptr, o, n) ({ \
|
|
((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
|
|
(unsigned long)(n), sizeof(*(ptr)))); \
|
|
})
|
|
#endif
|
|
|
|
#ifndef cmpxchg64_local
|
|
#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
|
|
#endif
|
|
|
|
#define cmpxchg(ptr, o, n) cmpxchg_local((ptr), (o), (n))
|
|
#define cmpxchg64(ptr, o, n) cmpxchg64_local((ptr), (o), (n))
|
|
|
|
#endif /* __ASM_GENERIC_CMPXCHG_H */
|