Re: [rcu:dev.2017.10.05a 32/34] include/linux/compiler.h:343:2: error: implicit declaration of function 'smp_read_barrier_depends'

From: Will Deacon
Date: Fri Oct 06 2017 - 09:21:44 EST

Hi Paul,

On Fri, Oct 06, 2017 at 07:18:41AM +0800, kbuild test robot wrote:
> tree: dev.2017.10.05a
> head: 39ae2675aa536e6ef9d334fe9097d1e2c6b25fbc
> commit: 7e3675cc18bbf4d84f60bfc02ff563ae3764ad35 [32/34] locking/barriers: Kill lockless_dereference
> config: h8300-h8300h-sim_defconfig (attached as .config)
> compiler: h8300-linux-gcc (GCC) 6.2.0
> reproduce:
> wget -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> git checkout 7e3675cc18bbf4d84f60bfc02ff563ae3764ad35
> # save the attached .config to linux build tree
> make.cross ARCH=h8300
> All error/warnings (new ones prefixed by >>):
> In file included from include/uapi/linux/stddef.h:1:0,
> from include/linux/stddef.h:4,
> from arch/h8300/kernel/asm-offsets.c:11:
> include/linux/list.h: In function 'list_empty':
> >> include/linux/compiler.h:343:2: error: implicit declaration of function 'smp_read_barrier_depends' [-Werror=implicit-function-declaration]
> smp_read_barrier_depends(); /* Enforce dependency ordering from x */ \
> ^
> include/linux/compiler.h:346:22: note: in expansion of macro '__READ_ONCE'
> #define READ_ONCE(x) __READ_ONCE(x, 1)
> ^~~~~~~~~~~
> >> include/linux/list.h:202:9: note: in expansion of macro 'READ_ONCE'
> return READ_ONCE(head->next) == head;
> ^~~~~~~~~
> cc1: some warnings being treated as errors
> make[2]: *** [arch/h8300/kernel/asm-offsets.s] Error 1
> make[2]: Target '__build' not remade because of errors.
> make[1]: *** [prepare0] Error 2
> make[1]: Target 'prepare' not remade because of errors.
> make: *** [sub-make] Error 2

Ok, I dug into this and the problem is as follows:

arch/h8300/kernel/asm-offsets.c includes linux/stddef.h for offsetof
linux/stddef.h includes uapi/linux/stddef.h
uapi/linux/stddef.h includes linux/compiler.h

arch/h8300/kernel/asm-offsets.c also includes linux/sched.h for task_struct
linux/sched.h includes linux/pid.h
linux/pid.h includes linux/rculist.h
linux/rculist.h includes linux/list.h

linux/list.h then tries to instantiate some static inline functions
that use READ_ONCE (e.g. list_empty), but nobody has included asm/barrier.h
so the build fails.

Ideally, we'd just include <asm/barrier.h> in linux/compiler.h (since
lockless_dereference uses smp_read_barrier_depends in mainline today),
but it's not quite that simple because compiler.h is also used by
linux/types.h, so we don't even have a definition for "bool" at this stage!

The best fix I could come up with involves splitting compiler.h into two
headers: one for the type annotations and definitions, and the other for
macros such as READ_ONCE. Patch below.

Note that even with this change I'm unable to build h8300. The assembler
chokes on a bunch of unrelated errors and the compiler eventually ICEs.