2019-08-16 21:12:34

by kernel test robot

[permalink] [raw]
Subject: [rcu:from-joel.2019.08.16a 143/172] kernel/rcu/tree.c:2808:6: note: in expansion of macro 'xchg'

tree: https://kernel.googlesource.com/pub/scm/linux/kernel/git/paulmck/linux-rcu.git from-joel.2019.08.16a
head: 01b0e4d3e0ac279b295bc06a3591f0b810b9908f
commit: bda80ba9decc7a32413e88d2f070de180c4b76ab [143/172] rcu/tree: Add basic support for kfree_rcu() batching
config: riscv-defconfig (attached as .config)
compiler: riscv64-linux-gcc (GCC) 7.4.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
git checkout bda80ba9decc7a32413e88d2f070de180c4b76ab
# save the attached .config to linux build tree
GCC_VERSION=7.4.0 make.cross ARCH=riscv

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <[email protected]>

All error/warnings (new ones prefixed by >>):

In file included from arch/riscv/include/asm/atomic.h:19:0,
from include/linux/atomic.h:7,
from include/linux/spinlock.h:445,
from kernel/rcu/tree.c:23:
kernel/rcu/tree.c: In function 'kfree_rcu_monitor':
>> arch/riscv/include/asm/cmpxchg.h:140:2: warning: '__ret' is used uninitialized in this function [-Wuninitialized]
__ret; \
^~~~~
arch/riscv/include/asm/cmpxchg.h:121:21: note: '__ret' was declared here
__typeof__(*(ptr)) __ret; \
^
>> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
(__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
^~~~~~
>> kernel/rcu/tree.c:2808:6: note: in expansion of macro 'xchg'
if (xchg(&krcp->monitor_todo, false))
^~~~
In file included from include/linux/kernel.h:11:0,
from kernel/rcu/tree.c:21:
>> include/linux/compiler.h:350:38: error: call to '__compiletime_assert_2808' declared with attribute error: BUILD_BUG failed
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^
include/linux/compiler.h:331:4: note: in definition of macro '__compiletime_assert'
prefix ## suffix(); \
^~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
^~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:59:21: note: in expansion of macro 'BUILD_BUG_ON_MSG'
#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
^~~~~~~~~~~~~~~~
>> arch/riscv/include/asm/cmpxchg.h:138:3: note: in expansion of macro 'BUILD_BUG'
BUILD_BUG(); \
^~~~~~~~~
>> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
(__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
^~~~~~
>> kernel/rcu/tree.c:2808:6: note: in expansion of macro 'xchg'
if (xchg(&krcp->monitor_todo, false))
^~~~
In function 'kfree_rcu_drain_unlock',
inlined from 'kfree_rcu_monitor' at kernel/rcu/tree.c:2809:3:
include/linux/compiler.h:350:38: error: call to '__compiletime_assert_2792' declared with attribute error: BUILD_BUG failed
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^
include/linux/compiler.h:331:4: note: in definition of macro '__compiletime_assert'
prefix ## suffix(); \
^~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
^~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:59:21: note: in expansion of macro 'BUILD_BUG_ON_MSG'
#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
^~~~~~~~~~~~~~~~
>> arch/riscv/include/asm/cmpxchg.h:138:3: note: in expansion of macro 'BUILD_BUG'
BUILD_BUG(); \
^~~~~~~~~
>> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
(__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
^~~~~~
kernel/rcu/tree.c:2792:7: note: in expansion of macro 'xchg'
if (!xchg(&krcp->monitor_todo, true))
^~~~
kernel/rcu/tree.c: In function 'kfree_call_rcu':
>> kernel/rcu/tree.c:2860:5: warning: '__ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
if (!xchg(&krcp->monitor_todo, true))
^
In file included from include/linux/kernel.h:11:0,
from kernel/rcu/tree.c:21:
include/linux/compiler.h:350:38: error: call to '__compiletime_assert_2860' declared with attribute error: BUILD_BUG failed
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^
include/linux/compiler.h:331:4: note: in definition of macro '__compiletime_assert'
prefix ## suffix(); \
^~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
^~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:59:21: note: in expansion of macro 'BUILD_BUG_ON_MSG'
#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
^~~~~~~~~~~~~~~~
>> arch/riscv/include/asm/cmpxchg.h:138:3: note: in expansion of macro 'BUILD_BUG'
BUILD_BUG(); \
^~~~~~~~~
>> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
(__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
^~~~~~
kernel/rcu/tree.c:2860:7: note: in expansion of macro 'xchg'
if (!xchg(&krcp->monitor_todo, true))
^~~~
--
In file included from arch/riscv/include/asm/atomic.h:19:0,
from include/linux/atomic.h:7,
from include/linux/spinlock.h:445,
from kernel//rcu/tree.c:23:
kernel//rcu/tree.c: In function 'kfree_rcu_monitor':
>> arch/riscv/include/asm/cmpxchg.h:140:2: warning: '__ret' is used uninitialized in this function [-Wuninitialized]
__ret; \
^~~~~
arch/riscv/include/asm/cmpxchg.h:121:21: note: '__ret' was declared here
__typeof__(*(ptr)) __ret; \
^
>> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
(__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
^~~~~~
kernel//rcu/tree.c:2808:6: note: in expansion of macro 'xchg'
if (xchg(&krcp->monitor_todo, false))
^~~~
In file included from include/linux/kernel.h:11:0,
from kernel//rcu/tree.c:21:
>> include/linux/compiler.h:350:38: error: call to '__compiletime_assert_2808' declared with attribute error: BUILD_BUG failed
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^
include/linux/compiler.h:331:4: note: in definition of macro '__compiletime_assert'
prefix ## suffix(); \
^~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
^~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:59:21: note: in expansion of macro 'BUILD_BUG_ON_MSG'
#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
^~~~~~~~~~~~~~~~
>> arch/riscv/include/asm/cmpxchg.h:138:3: note: in expansion of macro 'BUILD_BUG'
BUILD_BUG(); \
^~~~~~~~~
>> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
(__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
^~~~~~
kernel//rcu/tree.c:2808:6: note: in expansion of macro 'xchg'
if (xchg(&krcp->monitor_todo, false))
^~~~
In function 'kfree_rcu_drain_unlock',
inlined from 'kfree_rcu_monitor' at kernel//rcu/tree.c:2809:3:
include/linux/compiler.h:350:38: error: call to '__compiletime_assert_2792' declared with attribute error: BUILD_BUG failed
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^
include/linux/compiler.h:331:4: note: in definition of macro '__compiletime_assert'
prefix ## suffix(); \
^~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
^~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:59:21: note: in expansion of macro 'BUILD_BUG_ON_MSG'
#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
^~~~~~~~~~~~~~~~
>> arch/riscv/include/asm/cmpxchg.h:138:3: note: in expansion of macro 'BUILD_BUG'
BUILD_BUG(); \
^~~~~~~~~
>> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
(__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
^~~~~~
kernel//rcu/tree.c:2792:7: note: in expansion of macro 'xchg'
if (!xchg(&krcp->monitor_todo, true))
^~~~
kernel//rcu/tree.c: In function 'kfree_call_rcu':
kernel//rcu/tree.c:2860:5: warning: '__ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
if (!xchg(&krcp->monitor_todo, true))
^
In file included from include/linux/kernel.h:11:0,
from kernel//rcu/tree.c:21:
include/linux/compiler.h:350:38: error: call to '__compiletime_assert_2860' declared with attribute error: BUILD_BUG failed
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^
include/linux/compiler.h:331:4: note: in definition of macro '__compiletime_assert'
prefix ## suffix(); \
^~~~~~
include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
^~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:59:21: note: in expansion of macro 'BUILD_BUG_ON_MSG'
#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
^~~~~~~~~~~~~~~~
>> arch/riscv/include/asm/cmpxchg.h:138:3: note: in expansion of macro 'BUILD_BUG'
BUILD_BUG(); \
^~~~~~~~~
>> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
(__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
^~~~~~
kernel//rcu/tree.c:2860:7: note: in expansion of macro 'xchg'
if (!xchg(&krcp->monitor_todo, true))
^~~~

vim +/xchg +2808 kernel/rcu/tree.c

2776
2777 static inline void kfree_rcu_drain_unlock(struct kfree_rcu_cpu *krcp,
2778 unsigned long flags)
2779 {
2780 /* Flush ->head to ->head_free, all objects on ->head_free will be
2781 * kfree'd after a grace period.
2782 */
2783 if (queue_kfree_rcu_work(krcp)) {
2784 /* Success! Our job is done here. */
2785 spin_unlock_irqrestore(&krcp->lock, flags);
2786 return;
2787 }
2788
2789 /* Previous batch that was queued to RCU did not get free yet, let us
2790 * try again soon.
2791 */
> 2792 if (!xchg(&krcp->monitor_todo, true))
2793 schedule_delayed_work(&krcp->monitor_work, KFREE_DRAIN_JIFFIES);
2794 spin_unlock_irqrestore(&krcp->lock, flags);
2795 }
2796
2797 /*
2798 * This function is invoked after the KFREE_DRAIN_JIFFIES timeout has elapsed,
2799 * and it drains the specified kfree_rcu_cpu structure's ->head list.
2800 */
2801 static void kfree_rcu_monitor(struct work_struct *work)
2802 {
2803 unsigned long flags;
2804 struct kfree_rcu_cpu *krcp = container_of(work, struct kfree_rcu_cpu,
2805 monitor_work.work);
2806
2807 spin_lock_irqsave(&krcp->lock, flags);
> 2808 if (xchg(&krcp->monitor_todo, false))
2809 kfree_rcu_drain_unlock(krcp, flags);
2810 else
2811 spin_unlock_irqrestore(&krcp->lock, flags);
2812 }
2813
2814 /*
2815 * This version of kfree_call_rcu does not do batching of kfree_rcu() requests.
2816 * Used only by rcuperf torture test for comparison with kfree_rcu_batch().
2817 */
2818 void kfree_call_rcu_nobatch(struct rcu_head *head, rcu_callback_t func)
2819 {
2820 __call_rcu(head, func, 1);
2821 }
2822 EXPORT_SYMBOL_GPL(kfree_call_rcu_nobatch);
2823
2824 /*
2825 * Queue a request for lazy invocation of kfree() after a grace period.
2826 *
2827 * Each kfree_call_rcu() request is added to a batch. The batch will be drained
2828 * every KFREE_DRAIN_JIFFIES number of jiffies. All the objects in the batch
2829 * will be kfree'd in workqueue context. This allows us to:
2830 *
2831 * 1. Batch requests together to reduce the number of grace periods during
2832 * heavy kfree_rcu() load.
2833 *
2834 * 2. In the future, makes it possible to use kfree_bulk() on a large number of
2835 * kfree_rcu() requests thus reducing the per-object overhead of kfree() and
2836 * also reducing cache misses.
2837 */
2838 void kfree_call_rcu(struct rcu_head *head, rcu_callback_t func)
2839 {
2840 unsigned long flags;
2841 struct kfree_rcu_cpu *krcp;
2842
2843 /* kfree_call_rcu() batching requires timers to be up. If the scheduler
2844 * is not yet up, just skip batching and do the non-batched version.
2845 */
2846 if (rcu_scheduler_active != RCU_SCHEDULER_RUNNING)
2847 return kfree_call_rcu_nobatch(head, func);
2848
2849 head->func = func;
2850
2851 local_irq_save(flags); /* For safely calling this_cpu_ptr(). */
2852 krcp = this_cpu_ptr(&krc);
2853 spin_lock(&krcp->lock);
2854
2855 /* Queue the kfree but don't yet schedule the batch. */
2856 head->next = krcp->head;
2857 krcp->head = head;
2858
2859 /* Schedule monitor for timely drain after KFREE_DRAIN_JIFFIES. */
> 2860 if (!xchg(&krcp->monitor_todo, true))
2861 schedule_delayed_work(&krcp->monitor_work, KFREE_DRAIN_JIFFIES);
2862
2863 spin_unlock(&krcp->lock);
2864 local_irq_restore(flags);
2865 }
2866 EXPORT_SYMBOL_GPL(kfree_call_rcu);
2867

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation


Attachments:
(No filename) (15.61 kB)
.config.gz (17.93 kB)
Download all attachments

2019-08-17 01:06:53

by Joel Fernandes

[permalink] [raw]
Subject: Re: [rcu:from-joel.2019.08.16a 143/172] kernel/rcu/tree.c:2808:6: note: in expansion of macro 'xchg'

On Sat, Aug 17, 2019 at 05:10:59AM +0800, kbuild test robot wrote:
> tree: https://kernel.googlesource.com/pub/scm/linux/kernel/git/paulmck/linux-rcu.git from-joel.2019.08.16a
> head: 01b0e4d3e0ac279b295bc06a3591f0b810b9908f
> commit: bda80ba9decc7a32413e88d2f070de180c4b76ab [143/172] rcu/tree: Add basic support for kfree_rcu() batching
> config: riscv-defconfig (attached as .config)
> compiler: riscv64-linux-gcc (GCC) 7.4.0
> reproduce:
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> git checkout bda80ba9decc7a32413e88d2f070de180c4b76ab
> # save the attached .config to linux build tree
> GCC_VERSION=7.4.0 make.cross ARCH=riscv

This seems to be a riscv issue:

A call to '__compiletime_assert_2792' declared with attribute error:
BUILD_BUG failed

Could riscv folks take a look at it? Why is using xchg() causing issues? The
xchg() is being done on a bool.

thanks,

- Joel


> If you fix the issue, kindly add following tag
> Reported-by: kbuild test robot <[email protected]>
>
> All error/warnings (new ones prefixed by >>):
>
> In file included from arch/riscv/include/asm/atomic.h:19:0,
> from include/linux/atomic.h:7,
> from include/linux/spinlock.h:445,
> from kernel/rcu/tree.c:23:
> kernel/rcu/tree.c: In function 'kfree_rcu_monitor':
> >> arch/riscv/include/asm/cmpxchg.h:140:2: warning: '__ret' is used uninitialized in this function [-Wuninitialized]
> __ret; \
> ^~~~~
> arch/riscv/include/asm/cmpxchg.h:121:21: note: '__ret' was declared here
> __typeof__(*(ptr)) __ret; \
> ^
> >> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
> (__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
> ^~~~~~
> >> kernel/rcu/tree.c:2808:6: note: in expansion of macro 'xchg'
> if (xchg(&krcp->monitor_todo, false))
> ^~~~
> In file included from include/linux/kernel.h:11:0,
> from kernel/rcu/tree.c:21:
> >> include/linux/compiler.h:350:38: error: call to '__compiletime_assert_2808' declared with attribute error: BUILD_BUG failed
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^
> include/linux/compiler.h:331:4: note: in definition of macro '__compiletime_assert'
> prefix ## suffix(); \
> ^~~~~~
> include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^~~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
> #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
> ^~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:59:21: note: in expansion of macro 'BUILD_BUG_ON_MSG'
> #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
> ^~~~~~~~~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:138:3: note: in expansion of macro 'BUILD_BUG'
> BUILD_BUG(); \
> ^~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
> (__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
> ^~~~~~
> >> kernel/rcu/tree.c:2808:6: note: in expansion of macro 'xchg'
> if (xchg(&krcp->monitor_todo, false))
> ^~~~
> In function 'kfree_rcu_drain_unlock',
> inlined from 'kfree_rcu_monitor' at kernel/rcu/tree.c:2809:3:
> include/linux/compiler.h:350:38: error: call to '__compiletime_assert_2792' declared with attribute error: BUILD_BUG failed
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^
> include/linux/compiler.h:331:4: note: in definition of macro '__compiletime_assert'
> prefix ## suffix(); \
> ^~~~~~
> include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^~~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
> #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
> ^~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:59:21: note: in expansion of macro 'BUILD_BUG_ON_MSG'
> #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
> ^~~~~~~~~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:138:3: note: in expansion of macro 'BUILD_BUG'
> BUILD_BUG(); \
> ^~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
> (__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
> ^~~~~~
> kernel/rcu/tree.c:2792:7: note: in expansion of macro 'xchg'
> if (!xchg(&krcp->monitor_todo, true))
> ^~~~
> kernel/rcu/tree.c: In function 'kfree_call_rcu':
> >> kernel/rcu/tree.c:2860:5: warning: '__ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
> if (!xchg(&krcp->monitor_todo, true))
> ^
> In file included from include/linux/kernel.h:11:0,
> from kernel/rcu/tree.c:21:
> include/linux/compiler.h:350:38: error: call to '__compiletime_assert_2860' declared with attribute error: BUILD_BUG failed
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^
> include/linux/compiler.h:331:4: note: in definition of macro '__compiletime_assert'
> prefix ## suffix(); \
> ^~~~~~
> include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^~~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
> #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
> ^~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:59:21: note: in expansion of macro 'BUILD_BUG_ON_MSG'
> #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
> ^~~~~~~~~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:138:3: note: in expansion of macro 'BUILD_BUG'
> BUILD_BUG(); \
> ^~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
> (__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
> ^~~~~~
> kernel/rcu/tree.c:2860:7: note: in expansion of macro 'xchg'
> if (!xchg(&krcp->monitor_todo, true))
> ^~~~
> --
> In file included from arch/riscv/include/asm/atomic.h:19:0,
> from include/linux/atomic.h:7,
> from include/linux/spinlock.h:445,
> from kernel//rcu/tree.c:23:
> kernel//rcu/tree.c: In function 'kfree_rcu_monitor':
> >> arch/riscv/include/asm/cmpxchg.h:140:2: warning: '__ret' is used uninitialized in this function [-Wuninitialized]
> __ret; \
> ^~~~~
> arch/riscv/include/asm/cmpxchg.h:121:21: note: '__ret' was declared here
> __typeof__(*(ptr)) __ret; \
> ^
> >> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
> (__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
> ^~~~~~
> kernel//rcu/tree.c:2808:6: note: in expansion of macro 'xchg'
> if (xchg(&krcp->monitor_todo, false))
> ^~~~
> In file included from include/linux/kernel.h:11:0,
> from kernel//rcu/tree.c:21:
> >> include/linux/compiler.h:350:38: error: call to '__compiletime_assert_2808' declared with attribute error: BUILD_BUG failed
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^
> include/linux/compiler.h:331:4: note: in definition of macro '__compiletime_assert'
> prefix ## suffix(); \
> ^~~~~~
> include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^~~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
> #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
> ^~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:59:21: note: in expansion of macro 'BUILD_BUG_ON_MSG'
> #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
> ^~~~~~~~~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:138:3: note: in expansion of macro 'BUILD_BUG'
> BUILD_BUG(); \
> ^~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
> (__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
> ^~~~~~
> kernel//rcu/tree.c:2808:6: note: in expansion of macro 'xchg'
> if (xchg(&krcp->monitor_todo, false))
> ^~~~
> In function 'kfree_rcu_drain_unlock',
> inlined from 'kfree_rcu_monitor' at kernel//rcu/tree.c:2809:3:
> include/linux/compiler.h:350:38: error: call to '__compiletime_assert_2792' declared with attribute error: BUILD_BUG failed
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^
> include/linux/compiler.h:331:4: note: in definition of macro '__compiletime_assert'
> prefix ## suffix(); \
> ^~~~~~
> include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^~~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
> #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
> ^~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:59:21: note: in expansion of macro 'BUILD_BUG_ON_MSG'
> #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
> ^~~~~~~~~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:138:3: note: in expansion of macro 'BUILD_BUG'
> BUILD_BUG(); \
> ^~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
> (__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
> ^~~~~~
> kernel//rcu/tree.c:2792:7: note: in expansion of macro 'xchg'
> if (!xchg(&krcp->monitor_todo, true))
> ^~~~
> kernel//rcu/tree.c: In function 'kfree_call_rcu':
> kernel//rcu/tree.c:2860:5: warning: '__ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
> if (!xchg(&krcp->monitor_todo, true))
> ^
> In file included from include/linux/kernel.h:11:0,
> from kernel//rcu/tree.c:21:
> include/linux/compiler.h:350:38: error: call to '__compiletime_assert_2860' declared with attribute error: BUILD_BUG failed
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^
> include/linux/compiler.h:331:4: note: in definition of macro '__compiletime_assert'
> prefix ## suffix(); \
> ^~~~~~
> include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^~~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
> #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
> ^~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:59:21: note: in expansion of macro 'BUILD_BUG_ON_MSG'
> #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
> ^~~~~~~~~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:138:3: note: in expansion of macro 'BUILD_BUG'
> BUILD_BUG(); \
> ^~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
> (__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
> ^~~~~~
> kernel//rcu/tree.c:2860:7: note: in expansion of macro 'xchg'
> if (!xchg(&krcp->monitor_todo, true))
> ^~~~
>
> vim +/xchg +2808 kernel/rcu/tree.c
>
> 2776
> 2777 static inline void kfree_rcu_drain_unlock(struct kfree_rcu_cpu *krcp,
> 2778 unsigned long flags)
> 2779 {
> 2780 /* Flush ->head to ->head_free, all objects on ->head_free will be
> 2781 * kfree'd after a grace period.
> 2782 */
> 2783 if (queue_kfree_rcu_work(krcp)) {
> 2784 /* Success! Our job is done here. */
> 2785 spin_unlock_irqrestore(&krcp->lock, flags);
> 2786 return;
> 2787 }
> 2788
> 2789 /* Previous batch that was queued to RCU did not get free yet, let us
> 2790 * try again soon.
> 2791 */
> > 2792 if (!xchg(&krcp->monitor_todo, true))
> 2793 schedule_delayed_work(&krcp->monitor_work, KFREE_DRAIN_JIFFIES);
> 2794 spin_unlock_irqrestore(&krcp->lock, flags);
> 2795 }
> 2796
> 2797 /*
> 2798 * This function is invoked after the KFREE_DRAIN_JIFFIES timeout has elapsed,
> 2799 * and it drains the specified kfree_rcu_cpu structure's ->head list.
> 2800 */
> 2801 static void kfree_rcu_monitor(struct work_struct *work)
> 2802 {
> 2803 unsigned long flags;
> 2804 struct kfree_rcu_cpu *krcp = container_of(work, struct kfree_rcu_cpu,
> 2805 monitor_work.work);
> 2806
> 2807 spin_lock_irqsave(&krcp->lock, flags);
> > 2808 if (xchg(&krcp->monitor_todo, false))
> 2809 kfree_rcu_drain_unlock(krcp, flags);
> 2810 else
> 2811 spin_unlock_irqrestore(&krcp->lock, flags);
> 2812 }
> 2813
> 2814 /*
> 2815 * This version of kfree_call_rcu does not do batching of kfree_rcu() requests.
> 2816 * Used only by rcuperf torture test for comparison with kfree_rcu_batch().
> 2817 */
> 2818 void kfree_call_rcu_nobatch(struct rcu_head *head, rcu_callback_t func)
> 2819 {
> 2820 __call_rcu(head, func, 1);
> 2821 }
> 2822 EXPORT_SYMBOL_GPL(kfree_call_rcu_nobatch);
> 2823
> 2824 /*
> 2825 * Queue a request for lazy invocation of kfree() after a grace period.
> 2826 *
> 2827 * Each kfree_call_rcu() request is added to a batch. The batch will be drained
> 2828 * every KFREE_DRAIN_JIFFIES number of jiffies. All the objects in the batch
> 2829 * will be kfree'd in workqueue context. This allows us to:
> 2830 *
> 2831 * 1. Batch requests together to reduce the number of grace periods during
> 2832 * heavy kfree_rcu() load.
> 2833 *
> 2834 * 2. In the future, makes it possible to use kfree_bulk() on a large number of
> 2835 * kfree_rcu() requests thus reducing the per-object overhead of kfree() and
> 2836 * also reducing cache misses.
> 2837 */
> 2838 void kfree_call_rcu(struct rcu_head *head, rcu_callback_t func)
> 2839 {
> 2840 unsigned long flags;
> 2841 struct kfree_rcu_cpu *krcp;
> 2842
> 2843 /* kfree_call_rcu() batching requires timers to be up. If the scheduler
> 2844 * is not yet up, just skip batching and do the non-batched version.
> 2845 */
> 2846 if (rcu_scheduler_active != RCU_SCHEDULER_RUNNING)
> 2847 return kfree_call_rcu_nobatch(head, func);
> 2848
> 2849 head->func = func;
> 2850
> 2851 local_irq_save(flags); /* For safely calling this_cpu_ptr(). */
> 2852 krcp = this_cpu_ptr(&krc);
> 2853 spin_lock(&krcp->lock);
> 2854
> 2855 /* Queue the kfree but don't yet schedule the batch. */
> 2856 head->next = krcp->head;
> 2857 krcp->head = head;
> 2858
> 2859 /* Schedule monitor for timely drain after KFREE_DRAIN_JIFFIES. */
> > 2860 if (!xchg(&krcp->monitor_todo, true))
> 2861 schedule_delayed_work(&krcp->monitor_work, KFREE_DRAIN_JIFFIES);
> 2862
> 2863 spin_unlock(&krcp->lock);
> 2864 local_irq_restore(flags);
> 2865 }
> 2866 EXPORT_SYMBOL_GPL(kfree_call_rcu);
> 2867
>
> ---
> 0-DAY kernel test infrastructure Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all Intel Corporation


2019-08-17 01:10:33

by Joel Fernandes

[permalink] [raw]
Subject: Re: [rcu:from-joel.2019.08.16a 143/172] kernel/rcu/tree.c:2808:6: note: in expansion of macro 'xchg'

Resending with more folks added.

On Sat, Aug 17, 2019 at 05:10:59AM +0800, kbuild test robot wrote:
> tree: https://kernel.googlesource.com/pub/scm/linux/kernel/git/paulmck/linux-rcu.git from-joel.2019.08.16a
> head: 01b0e4d3e0ac279b295bc06a3591f0b810b9908f
> commit: bda80ba9decc7a32413e88d2f070de180c4b76ab [143/172] rcu/tree: Add basic support for kfree_rcu() batching
> config: riscv-defconfig (attached as .config)
> compiler: riscv64-linux-gcc (GCC) 7.4.0
> reproduce:
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> git checkout bda80ba9decc7a32413e88d2f070de180c4b76ab
> # save the attached .config to linux build tree
> GCC_VERSION=7.4.0 make.cross ARCH=riscv

This seems to be a riscv issue:

A call to '__compiletime_assert_2792' declared with attribute error:
BUILD_BUG failed

Could riscv folks take a look at it? Why is using xchg() causing issues? The
xchg() is being done on a bool.

thanks,

- Joel


> If you fix the issue, kindly add following tag
> Reported-by: kbuild test robot <[email protected]>
>
> All error/warnings (new ones prefixed by >>):
>
> In file included from arch/riscv/include/asm/atomic.h:19:0,
> from include/linux/atomic.h:7,
> from include/linux/spinlock.h:445,
> from kernel/rcu/tree.c:23:
> kernel/rcu/tree.c: In function 'kfree_rcu_monitor':
> >> arch/riscv/include/asm/cmpxchg.h:140:2: warning: '__ret' is used uninitialized in this function [-Wuninitialized]
> __ret; \
> ^~~~~
> arch/riscv/include/asm/cmpxchg.h:121:21: note: '__ret' was declared here
> __typeof__(*(ptr)) __ret; \
> ^
> >> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
> (__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
> ^~~~~~
> >> kernel/rcu/tree.c:2808:6: note: in expansion of macro 'xchg'
> if (xchg(&krcp->monitor_todo, false))
> ^~~~
> In file included from include/linux/kernel.h:11:0,
> from kernel/rcu/tree.c:21:
> >> include/linux/compiler.h:350:38: error: call to '__compiletime_assert_2808' declared with attribute error: BUILD_BUG failed
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^
> include/linux/compiler.h:331:4: note: in definition of macro '__compiletime_assert'
> prefix ## suffix(); \
> ^~~~~~
> include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^~~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
> #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
> ^~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:59:21: note: in expansion of macro 'BUILD_BUG_ON_MSG'
> #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
> ^~~~~~~~~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:138:3: note: in expansion of macro 'BUILD_BUG'
> BUILD_BUG(); \
> ^~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
> (__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
> ^~~~~~
> >> kernel/rcu/tree.c:2808:6: note: in expansion of macro 'xchg'
> if (xchg(&krcp->monitor_todo, false))
> ^~~~
> In function 'kfree_rcu_drain_unlock',
> inlined from 'kfree_rcu_monitor' at kernel/rcu/tree.c:2809:3:
> include/linux/compiler.h:350:38: error: call to '__compiletime_assert_2792' declared with attribute error: BUILD_BUG failed
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^
> include/linux/compiler.h:331:4: note: in definition of macro '__compiletime_assert'
> prefix ## suffix(); \
> ^~~~~~
> include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^~~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
> #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
> ^~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:59:21: note: in expansion of macro 'BUILD_BUG_ON_MSG'
> #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
> ^~~~~~~~~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:138:3: note: in expansion of macro 'BUILD_BUG'
> BUILD_BUG(); \
> ^~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
> (__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
> ^~~~~~
> kernel/rcu/tree.c:2792:7: note: in expansion of macro 'xchg'
> if (!xchg(&krcp->monitor_todo, true))
> ^~~~
> kernel/rcu/tree.c: In function 'kfree_call_rcu':
> >> kernel/rcu/tree.c:2860:5: warning: '__ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
> if (!xchg(&krcp->monitor_todo, true))
> ^
> In file included from include/linux/kernel.h:11:0,
> from kernel/rcu/tree.c:21:
> include/linux/compiler.h:350:38: error: call to '__compiletime_assert_2860' declared with attribute error: BUILD_BUG failed
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^
> include/linux/compiler.h:331:4: note: in definition of macro '__compiletime_assert'
> prefix ## suffix(); \
> ^~~~~~
> include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^~~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
> #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
> ^~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:59:21: note: in expansion of macro 'BUILD_BUG_ON_MSG'
> #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
> ^~~~~~~~~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:138:3: note: in expansion of macro 'BUILD_BUG'
> BUILD_BUG(); \
> ^~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
> (__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
> ^~~~~~
> kernel/rcu/tree.c:2860:7: note: in expansion of macro 'xchg'
> if (!xchg(&krcp->monitor_todo, true))
> ^~~~
> --
> In file included from arch/riscv/include/asm/atomic.h:19:0,
> from include/linux/atomic.h:7,
> from include/linux/spinlock.h:445,
> from kernel//rcu/tree.c:23:
> kernel//rcu/tree.c: In function 'kfree_rcu_monitor':
> >> arch/riscv/include/asm/cmpxchg.h:140:2: warning: '__ret' is used uninitialized in this function [-Wuninitialized]
> __ret; \
> ^~~~~
> arch/riscv/include/asm/cmpxchg.h:121:21: note: '__ret' was declared here
> __typeof__(*(ptr)) __ret; \
> ^
> >> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
> (__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
> ^~~~~~
> kernel//rcu/tree.c:2808:6: note: in expansion of macro 'xchg'
> if (xchg(&krcp->monitor_todo, false))
> ^~~~
> In file included from include/linux/kernel.h:11:0,
> from kernel//rcu/tree.c:21:
> >> include/linux/compiler.h:350:38: error: call to '__compiletime_assert_2808' declared with attribute error: BUILD_BUG failed
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^
> include/linux/compiler.h:331:4: note: in definition of macro '__compiletime_assert'
> prefix ## suffix(); \
> ^~~~~~
> include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^~~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
> #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
> ^~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:59:21: note: in expansion of macro 'BUILD_BUG_ON_MSG'
> #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
> ^~~~~~~~~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:138:3: note: in expansion of macro 'BUILD_BUG'
> BUILD_BUG(); \
> ^~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
> (__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
> ^~~~~~
> kernel//rcu/tree.c:2808:6: note: in expansion of macro 'xchg'
> if (xchg(&krcp->monitor_todo, false))
> ^~~~
> In function 'kfree_rcu_drain_unlock',
> inlined from 'kfree_rcu_monitor' at kernel//rcu/tree.c:2809:3:
> include/linux/compiler.h:350:38: error: call to '__compiletime_assert_2792' declared with attribute error: BUILD_BUG failed
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^
> include/linux/compiler.h:331:4: note: in definition of macro '__compiletime_assert'
> prefix ## suffix(); \
> ^~~~~~
> include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^~~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
> #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
> ^~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:59:21: note: in expansion of macro 'BUILD_BUG_ON_MSG'
> #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
> ^~~~~~~~~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:138:3: note: in expansion of macro 'BUILD_BUG'
> BUILD_BUG(); \
> ^~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
> (__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
> ^~~~~~
> kernel//rcu/tree.c:2792:7: note: in expansion of macro 'xchg'
> if (!xchg(&krcp->monitor_todo, true))
> ^~~~
> kernel//rcu/tree.c: In function 'kfree_call_rcu':
> kernel//rcu/tree.c:2860:5: warning: '__ret' may be used uninitialized in this function [-Wmaybe-uninitialized]
> if (!xchg(&krcp->monitor_todo, true))
> ^
> In file included from include/linux/kernel.h:11:0,
> from kernel//rcu/tree.c:21:
> include/linux/compiler.h:350:38: error: call to '__compiletime_assert_2860' declared with attribute error: BUILD_BUG failed
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^
> include/linux/compiler.h:331:4: note: in definition of macro '__compiletime_assert'
> prefix ## suffix(); \
> ^~~~~~
> include/linux/compiler.h:350:2: note: in expansion of macro '_compiletime_assert'
> _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
> ^~~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
> #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
> ^~~~~~~~~~~~~~~~~~
> include/linux/build_bug.h:59:21: note: in expansion of macro 'BUILD_BUG_ON_MSG'
> #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
> ^~~~~~~~~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:138:3: note: in expansion of macro 'BUILD_BUG'
> BUILD_BUG(); \
> ^~~~~~~~~
> >> arch/riscv/include/asm/cmpxchg.h:146:23: note: in expansion of macro '__xchg'
> (__typeof__(*(ptr))) __xchg((ptr), _x_, sizeof(*(ptr))); \
> ^~~~~~
> kernel//rcu/tree.c:2860:7: note: in expansion of macro 'xchg'
> if (!xchg(&krcp->monitor_todo, true))
> ^~~~
>
> vim +/xchg +2808 kernel/rcu/tree.c
>
> 2776
> 2777 static inline void kfree_rcu_drain_unlock(struct kfree_rcu_cpu *krcp,
> 2778 unsigned long flags)
> 2779 {
> 2780 /* Flush ->head to ->head_free, all objects on ->head_free will be
> 2781 * kfree'd after a grace period.
> 2782 */
> 2783 if (queue_kfree_rcu_work(krcp)) {
> 2784 /* Success! Our job is done here. */
> 2785 spin_unlock_irqrestore(&krcp->lock, flags);
> 2786 return;
> 2787 }
> 2788
> 2789 /* Previous batch that was queued to RCU did not get free yet, let us
> 2790 * try again soon.
> 2791 */
> > 2792 if (!xchg(&krcp->monitor_todo, true))
> 2793 schedule_delayed_work(&krcp->monitor_work, KFREE_DRAIN_JIFFIES);
> 2794 spin_unlock_irqrestore(&krcp->lock, flags);
> 2795 }
> 2796
> 2797 /*
> 2798 * This function is invoked after the KFREE_DRAIN_JIFFIES timeout has elapsed,
> 2799 * and it drains the specified kfree_rcu_cpu structure's ->head list.
> 2800 */
> 2801 static void kfree_rcu_monitor(struct work_struct *work)
> 2802 {
> 2803 unsigned long flags;
> 2804 struct kfree_rcu_cpu *krcp = container_of(work, struct kfree_rcu_cpu,
> 2805 monitor_work.work);
> 2806
> 2807 spin_lock_irqsave(&krcp->lock, flags);
> > 2808 if (xchg(&krcp->monitor_todo, false))
> 2809 kfree_rcu_drain_unlock(krcp, flags);
> 2810 else
> 2811 spin_unlock_irqrestore(&krcp->lock, flags);
> 2812 }
> 2813
> 2814 /*
> 2815 * This version of kfree_call_rcu does not do batching of kfree_rcu() requests.
> 2816 * Used only by rcuperf torture test for comparison with kfree_rcu_batch().
> 2817 */
> 2818 void kfree_call_rcu_nobatch(struct rcu_head *head, rcu_callback_t func)
> 2819 {
> 2820 __call_rcu(head, func, 1);
> 2821 }
> 2822 EXPORT_SYMBOL_GPL(kfree_call_rcu_nobatch);
> 2823
> 2824 /*
> 2825 * Queue a request for lazy invocation of kfree() after a grace period.
> 2826 *
> 2827 * Each kfree_call_rcu() request is added to a batch. The batch will be drained
> 2828 * every KFREE_DRAIN_JIFFIES number of jiffies. All the objects in the batch
> 2829 * will be kfree'd in workqueue context. This allows us to:
> 2830 *
> 2831 * 1. Batch requests together to reduce the number of grace periods during
> 2832 * heavy kfree_rcu() load.
> 2833 *
> 2834 * 2. In the future, makes it possible to use kfree_bulk() on a large number of
> 2835 * kfree_rcu() requests thus reducing the per-object overhead of kfree() and
> 2836 * also reducing cache misses.
> 2837 */
> 2838 void kfree_call_rcu(struct rcu_head *head, rcu_callback_t func)
> 2839 {
> 2840 unsigned long flags;
> 2841 struct kfree_rcu_cpu *krcp;
> 2842
> 2843 /* kfree_call_rcu() batching requires timers to be up. If the scheduler
> 2844 * is not yet up, just skip batching and do the non-batched version.
> 2845 */
> 2846 if (rcu_scheduler_active != RCU_SCHEDULER_RUNNING)
> 2847 return kfree_call_rcu_nobatch(head, func);
> 2848
> 2849 head->func = func;
> 2850
> 2851 local_irq_save(flags); /* For safely calling this_cpu_ptr(). */
> 2852 krcp = this_cpu_ptr(&krc);
> 2853 spin_lock(&krcp->lock);
> 2854
> 2855 /* Queue the kfree but don't yet schedule the batch. */
> 2856 head->next = krcp->head;
> 2857 krcp->head = head;
> 2858
> 2859 /* Schedule monitor for timely drain after KFREE_DRAIN_JIFFIES. */
> > 2860 if (!xchg(&krcp->monitor_todo, true))
> 2861 schedule_delayed_work(&krcp->monitor_work, KFREE_DRAIN_JIFFIES);
> 2862
> 2863 spin_unlock(&krcp->lock);
> 2864 local_irq_restore(flags);
> 2865 }
> 2866 EXPORT_SYMBOL_GPL(kfree_call_rcu);
> 2867
>
> ---
> 0-DAY kernel test infrastructure Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all Intel Corporation


2019-08-17 03:11:33

by Paul Walmsley

[permalink] [raw]
Subject: Re: [rcu:from-joel.2019.08.16a 143/172] kernel/rcu/tree.c:2808:6: note: in expansion of macro 'xchg'

On Fri, 16 Aug 2019, Joel Fernandes wrote:

> On Sat, Aug 17, 2019 at 05:10:59AM +0800, kbuild test robot wrote:
> > tree: https://kernel.googlesource.com/pub/scm/linux/kernel/git/paulmck/linux-rcu.git from-joel.2019.08.16a
> > head: 01b0e4d3e0ac279b295bc06a3591f0b810b9908f
> > commit: bda80ba9decc7a32413e88d2f070de180c4b76ab [143/172] rcu/tree: Add basic support for kfree_rcu() batching
> > config: riscv-defconfig (attached as .config)
> > compiler: riscv64-linux-gcc (GCC) 7.4.0
> > reproduce:
> > wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> > chmod +x ~/bin/make.cross
> > git checkout bda80ba9decc7a32413e88d2f070de180c4b76ab
> > # save the attached .config to linux build tree
> > GCC_VERSION=7.4.0 make.cross ARCH=riscv
>
> This seems to be a riscv issue:
>
> A call to '__compiletime_assert_2792' declared with attribute error:
> BUILD_BUG failed
>
> Could riscv folks take a look at it? Why is using xchg() causing issues? The
> xchg() is being done on a bool.

sizeof(bool) = 1, and the only xchg() implementation that's currently
present on all RISC-V in Linux is usable only on 32-bit types. SPARC,
Microblaze, C-SKY, and Hexagon all look like they have the same
limitation. You'll probably see similar build breakage for those
platforms too.

MIPS, OpenRISC, Xtensa, and SuperH have compatibility functions for the
8-bit and 16-bit cases. We could add those for RISC-V. However, they'll
be slower than the 4- and 8-byte cases. This is both because there's more
code involved, and because there's an increased risk of false-sharing.

Can you use a u32 instead for xchg/cmpxchg operations like struct
kfree_rcu_cpu.monitor_todo that are intended to be cross-platform? Based
on a cursory glance through the tree, it looks like there's only one
cross-platform driver that uses 'true' or 'false' with the kernel
xchg/cmpxchg, and it uses an int as the underlying data type.

I suppose one could typedef "xchg_bool" on a per-architecture basis, to be
smallest type that makes sense to use in an xchg() or cmpxchg(). That
might save some memory on architectures that have a fast 1-byte
xchg()/cmpxchg(). But given the lack of users in the tree, I'm not sure
it's worth the effort.


- Paul