On Thu, Jun 04, 2020 at 07:18:37AM -0700, Guenter Roeck wrote: > On Tue, May 26, 2020 at 06:11:04PM +0200, Peter Zijlstra wrote: > > The recent commit: 90b5363acd47 ("sched: Clean up scheduler_ipi()") > > got smp_call_function_single_async() subtly wrong. Even though it will > > return -EBUSY when trying to re-use a csd, that condition is not > > atomic and still requires external serialization. > > > > The change in ttwu_queue_remote() got this wrong. > > > > While on first reading ttwu_queue_remote() has an atomic test-and-set > > that appears to serialize the use, the matching 'release' is not in > > the right place to actually guarantee this serialization. > > > > The actual race is vs the sched_ttwu_pending() call in the idle loop; > > that can run the wakeup-list without consuming the CSD. > > > > Instead of trying to chain the lists, merge them. > > > > Signed-off-by: Peter Zijlstra (Intel) <pet...@infradead.org> > > --- > ... > > + /* > > + * Assert the CSD_TYPE_TTWU layout is similar enough > > + * for task_struct to be on the @call_single_queue. > > + */ > > + BUILD_BUG_ON(offsetof(struct task_struct, wake_entry_type) - > > offsetof(struct task_struct, wake_entry) != > > + offsetof(struct __call_single_data, flags) - > > offsetof(struct __call_single_data, llist)); > > + > > There is no guarantee in C that > > type1 a; > type2 b; > > in two different data structures means that offsetof(b) - offsetof(a) > is the same in both data structures unless attributes such as > __attribute__((__packed__)) are used. > > As result, this does and will cause a variety of build errors depending > on the compiler version and compile flags. > > Guenter
Yep, this breaks the build for me. CC kernel/smp.o In file included from ./arch/x86/include/asm/atomic.h:5, from ./include/linux/atomic.h:7, from ./include/linux/llist.h:51, from ./include/linux/irq_work.h:5, from kernel/smp.c:10: kernel/smp.c: In function ‘smp_init’: ./include/linux/compiler.h:403:38: error: call to ‘__compiletime_assert_68’ declared with attribute error: BUILD_BUG_ON failed: offsetof(struct task_struct, wake_entry_type) - offsetof(struct task_struct, wake_entry) != offsetof(struct __call_single_data, flags) - offsetof(struct __call_single_data, llist) 403 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) | ^ ./include/linux/compiler.h:384:4: note: in definition of macro ‘__compiletime_assert’ 384 | prefix ## suffix(); \ | ^~~~~~ ./include/linux/compiler.h:403:2: note: in expansion of macro ‘_compiletime_assert’ 403 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) | ^~~~~~~~~~~~~~~~~~~ ./include/linux/build_bug.h:39:37: note: in expansion of macro ‘compiletime_assert’ 39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg) | ^~~~~~~~~~~~~~~~~~ ./include/linux/build_bug.h:50:2: note: in expansion of macro ‘BUILD_BUG_ON_MSG’ 50 | BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition) | ^~~~~~~~~~~~~~~~ kernel/smp.c:687:2: note: in expansion of macro ‘BUILD_BUG_ON’ 687 | BUILD_BUG_ON(offsetof(struct task_struct, wake_entry_type) - offsetof(struct task_struct, wake_entry) != | ^~~~~~~~~~~~ make[1]: *** [scripts/Makefile.build:267: kernel/smp.o] Error 1 make: *** [Makefile:1735: kernel] Error 2