Skip to content

Commit

Permalink
kcsan: Turn barrier instrumentation into macros
Browse files Browse the repository at this point in the history
Some architectures use barriers in 'extern inline' functions, from which
we should not refer to static inline functions.

For example, building Alpha with gcc and W=1 shows:

./include/asm-generic/barrier.h:70:30: warning: 'kcsan_rmb' is static but used in inline function 'pmd_offset' which is not static
   70 | #define smp_rmb()       do { kcsan_rmb(); __smp_rmb(); } while (0)
      |                              ^~~~~~~~~
./arch/alpha/include/asm/pgtable.h:293:9: note: in expansion of macro 'smp_rmb'
  293 |         smp_rmb(); /* see above */
      |         ^~~~~~~

Which seems to warn about 6.7.4#3 of the C standard:
  "An inline definition of a function with external linkage shall not
   contain a definition of a modifiable object with static or thread
   storage duration, and shall not contain a reference to an identifier
   with internal linkage."

Fix it by turning barrier instrumentation into macros, which matches
definitions in <asm/barrier.h>.

Perhaps we can revert this change in future, when there are no more
'extern inline' users left.

Link: https://lkml.kernel.org/r/202112041334.X44uWZXf-lkp@intel.com
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Marco Elver <elver@google.com>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
  • Loading branch information
Marco Elver authored and Paul E. McKenney committed Dec 10, 2021
1 parent a70d36e commit 80d7476
Showing 1 changed file with 13 additions and 11 deletions.
24 changes: 13 additions & 11 deletions include/linux/kcsan-checks.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,28 +241,30 @@ static inline void __kcsan_disable_current(void) { }
* disabled with the __no_kcsan function attribute.
*
* Also see definition of __tsan_atomic_signal_fence() in kernel/kcsan/core.c.
*
* These are all macros, like <asm/barrier.h>, since some architectures use them
* in non-static inline functions.
*/
#define __KCSAN_BARRIER_TO_SIGNAL_FENCE(name) \
static __always_inline void kcsan_##name(void) \
{ \
do { \
barrier(); \
__atomic_signal_fence(__KCSAN_BARRIER_TO_SIGNAL_FENCE_##name); \
barrier(); \
}
__KCSAN_BARRIER_TO_SIGNAL_FENCE(mb)
__KCSAN_BARRIER_TO_SIGNAL_FENCE(wmb)
__KCSAN_BARRIER_TO_SIGNAL_FENCE(rmb)
__KCSAN_BARRIER_TO_SIGNAL_FENCE(release)
} while (0)
#define kcsan_mb() __KCSAN_BARRIER_TO_SIGNAL_FENCE(mb)
#define kcsan_wmb() __KCSAN_BARRIER_TO_SIGNAL_FENCE(wmb)
#define kcsan_rmb() __KCSAN_BARRIER_TO_SIGNAL_FENCE(rmb)
#define kcsan_release() __KCSAN_BARRIER_TO_SIGNAL_FENCE(release)
#elif defined(CONFIG_KCSAN_WEAK_MEMORY) && defined(__KCSAN_INSTRUMENT_BARRIERS__)
#define kcsan_mb __kcsan_mb
#define kcsan_wmb __kcsan_wmb
#define kcsan_rmb __kcsan_rmb
#define kcsan_release __kcsan_release
#else /* CONFIG_KCSAN_WEAK_MEMORY && ... */
static inline void kcsan_mb(void) { }
static inline void kcsan_wmb(void) { }
static inline void kcsan_rmb(void) { }
static inline void kcsan_release(void) { }
#define kcsan_mb() do { } while (0)
#define kcsan_wmb() do { } while (0)
#define kcsan_rmb() do { } while (0)
#define kcsan_release() do { } while (0)
#endif /* CONFIG_KCSAN_WEAK_MEMORY && ... */

/**
Expand Down

0 comments on commit 80d7476

Please sign in to comment.