diff mbox series

[V8,07/10] riscv: Add qspinlock support

Message ID 20220724122517.1019187-8-guoren@kernel.org (mailing list archive)
State New, archived
Headers show
Series arch: Add qspinlock support with combo style | expand

Commit Message

Guo Ren July 24, 2022, 12:25 p.m. UTC
From: Guo Ren <guoren@linux.alibaba.com>

Enable qspinlock by the requirements mentioned in a8ad07e5240c9
("asm-generic: qspinlock: Indicate the use of mixed-size atomics").

 - RISC-V atomic_*_release()/atomic_*_acquire() are implemented with
   own relaxed version plus acquire/release_fence for RCsc
   synchronization.

 - RISC-V LR/SC pairs could provide a strong/weak forward guarantee
   that depends on micro-architecture. And RISC-V ISA spec has given
   out several limitations to let hardware support strict forward
   guarantee (RISC-V User ISA - 8.3 Eventual Success of
   Store-Conditional Instructions). Some riscv cores such as BOOMv3
   & XiangShan could provide strict & strong forward guarantee (The
   cache line would be kept in an exclusive state for Backoff cycles,
   and only this core's interrupt could break the LR/SC pair).

 - RISC-V provides cheap atomic_fetch_or_acquire() with RCsc.

 - RISC-V only provides relaxed xchg16 to support qspinlock.

Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
 arch/riscv/Kconfig               | 16 ++++++++++++++++
 arch/riscv/include/asm/Kbuild    |  2 ++
 arch/riscv/include/asm/cmpxchg.h | 17 +++++++++++++++++
 3 files changed, 35 insertions(+)

Comments

kernel test robot July 28, 2022, 12:04 a.m. UTC | #1
Hi,

I love your patch! Perhaps something to improve:

[auto build test WARNING on arnd-asm-generic/master]
[also build test WARNING on linus/master v5.19-rc8 next-20220727]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/guoren-kernel-org/arch-Add-qspinlock-support-with-combo-style/20220724-202743
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git master
config: riscv-randconfig-r026-20220727 (https://download.01.org/0day-ci/archive/20220728/202207280822.VHS6qieH-lkp@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 8dfaecc4c24494337933aff9d9166486ca0949f1)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/intel-lab-lkp/linux/commit/980c0acb7f432777e3473ab9a5696044e03b3f3d
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review guoren-kernel-org/arch-Add-qspinlock-support-with-combo-style/20220724-202743
        git checkout 980c0acb7f432777e3473ab9a5696044e03b3f3d
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash drivers/net/wireguard/

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from drivers/net/wireguard/queueing.c:6:
   In file included from drivers/net/wireguard/queueing.h:9:
   In file included from drivers/net/wireguard/peer.h:9:
   In file included from drivers/net/wireguard/device.h:9:
   In file included from drivers/net/wireguard/noise.h:8:
   In file included from drivers/net/wireguard/messages.h:10:
   In file included from include/crypto/chacha20poly1305.h:10:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __raw_readb(PCI_IOBASE + addr);
                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu'
   #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
                                                     ^
   In file included from drivers/net/wireguard/queueing.c:6:
   In file included from drivers/net/wireguard/queueing.h:9:
   In file included from drivers/net/wireguard/peer.h:9:
   In file included from drivers/net/wireguard/device.h:9:
   In file included from drivers/net/wireguard/noise.h:8:
   In file included from drivers/net/wireguard/messages.h:10:
   In file included from include/crypto/chacha20poly1305.h:10:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
                                                     ^
   In file included from drivers/net/wireguard/queueing.c:6:
   In file included from drivers/net/wireguard/queueing.h:9:
   In file included from drivers/net/wireguard/peer.h:9:
   In file included from drivers/net/wireguard/device.h:9:
   In file included from drivers/net/wireguard/noise.h:8:
   In file included from drivers/net/wireguard/messages.h:10:
   In file included from include/crypto/chacha20poly1305.h:10:
   In file included from include/linux/scatterlist.h:9:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writeb(value, PCI_IOBASE + addr);
                               ~~~~~~~~~~ ^
   include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:1107:55: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           return (port > MMIO_UPPER_LIMIT) ? NULL : PCI_IOBASE + port;
                                                     ~~~~~~~~~~ ^
>> drivers/net/wireguard/queueing.c:68:18: warning: cast to smaller integer type 'u32' (aka 'unsigned int') from 'typeof (_x_)' (aka 'struct sk_buff *') [-Wpointer-to-int-cast]
           WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
           arch_xchg_release(__ai_ptr, __VA_ARGS__); \
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
           __atomic_op_release(arch_xchg, __VA_ARGS__)
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
           op##_relaxed(args);                                             \
           ^~~~~~~~~~~~~~~~~~
   note: (skipping 7 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                               ^~~~~~~~~
   include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
                                ^~~~~~~~~
   include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
                   if (!(condition))                                       \
                         ^~~~~~~~~
>> drivers/net/wireguard/queueing.c:68:18: warning: cast to 'typeof (*((__ai_ptr)))' (aka 'struct sk_buff *') from smaller integer type 'unsigned int' [-Wint-to-pointer-cast]
           WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
           ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
           arch_xchg_release(__ai_ptr, __VA_ARGS__); \
           ^
   include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
           __atomic_op_release(arch_xchg, __VA_ARGS__)
           ^
   include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
           op##_relaxed(args);                                             \
           ^
   note: (skipping 7 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
           ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
           ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
                   if (!(condition))                                       \
                         ^~~~~~~~~
>> drivers/net/wireguard/queueing.c:68:18: warning: cast to smaller integer type 'u32' (aka 'unsigned int') from 'typeof (_x_)' (aka 'struct sk_buff *') [-Wpointer-to-int-cast]
           WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
           arch_xchg_release(__ai_ptr, __VA_ARGS__); \
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
           __atomic_op_release(arch_xchg, __VA_ARGS__)
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
           op##_relaxed(args);                                             \
           ^~~~~~~~~~~~~~~~~~
   note: (skipping 7 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                               ^~~~~~~~~
   include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
                                ^~~~~~~~~
   include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
                   if (!(condition))                                       \
                         ^~~~~~~~~
>> drivers/net/wireguard/queueing.c:68:18: warning: cast to 'typeof (*((__ai_ptr)))' (aka 'struct sk_buff *') from smaller integer type 'unsigned int' [-Wint-to-pointer-cast]
           WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
           ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
           arch_xchg_release(__ai_ptr, __VA_ARGS__); \
           ^
   include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
           __atomic_op_release(arch_xchg, __VA_ARGS__)
           ^
   include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
           op##_relaxed(args);                                             \
           ^
   note: (skipping 7 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
           ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
           ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
                   if (!(condition))                                       \
                         ^~~~~~~~~
>> drivers/net/wireguard/queueing.c:68:18: warning: cast to smaller integer type 'u32' (aka 'unsigned int') from 'typeof (_x_)' (aka 'struct sk_buff *') [-Wpointer-to-int-cast]
           WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
           arch_xchg_release(__ai_ptr, __VA_ARGS__); \
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
           __atomic_op_release(arch_xchg, __VA_ARGS__)
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
           op##_relaxed(args);                                             \
           ^~~~~~~~~~~~~~~~~~
   note: (skipping 7 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                               ^~~~~~~~~
   include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
                                ^~~~~~~~~
   include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
                   if (!(condition))                                       \
                         ^~~~~~~~~
>> drivers/net/wireguard/queueing.c:68:18: warning: cast to 'typeof (*((__ai_ptr)))' (aka 'struct sk_buff *') from smaller integer type 'unsigned int' [-Wint-to-pointer-cast]
           WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
           ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
           arch_xchg_release(__ai_ptr, __VA_ARGS__); \
           ^
   include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
           __atomic_op_release(arch_xchg, __VA_ARGS__)
           ^
   include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
           op##_relaxed(args);                                             \
           ^
   note: (skipping 7 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
           ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
           ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
                   if (!(condition))                                       \
                         ^~~~~~~~~
>> drivers/net/wireguard/queueing.c:68:18: warning: cast to smaller integer type 'u32' (aka 'unsigned int') from 'typeof (_x_)' (aka 'struct sk_buff *') [-Wpointer-to-int-cast]
           WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
           arch_xchg_release(__ai_ptr, __VA_ARGS__); \
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
           __atomic_op_release(arch_xchg, __VA_ARGS__)
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
           op##_relaxed(args);                                             \
           ^~~~~~~~~~~~~~~~~~
   note: (skipping 7 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                               ^~~~~~~~~
   include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
                                ^~~~~~~~~
   include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
                   if (!(condition))                                       \
                         ^~~~~~~~~
>> drivers/net/wireguard/queueing.c:68:18: warning: cast to 'typeof (*((__ai_ptr)))' (aka 'struct sk_buff *') from smaller integer type 'unsigned int' [-Wint-to-pointer-cast]
           WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
           ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
           arch_xchg_release(__ai_ptr, __VA_ARGS__); \
           ^
   include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
           __atomic_op_release(arch_xchg, __VA_ARGS__)
           ^
   include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
           op##_relaxed(args);                                             \
           ^
   note: (skipping 7 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
           ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
           ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
                   if (!(condition))                                       \
                         ^~~~~~~~~
>> drivers/net/wireguard/queueing.c:68:18: warning: cast to smaller integer type 'u32' (aka 'unsigned int') from 'typeof (_x_)' (aka 'struct sk_buff *') [-Wpointer-to-int-cast]
           WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
           arch_xchg_release(__ai_ptr, __VA_ARGS__); \
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
           __atomic_op_release(arch_xchg, __VA_ARGS__)
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
           op##_relaxed(args);                                             \
           ^~~~~~~~~~~~~~~~~~
   note: (skipping 6 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
                               ^~~~~~~~~
   include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
                                ^~~~~~~~~
   include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
                   if (!(condition))                                       \
                         ^~~~~~~~~
>> drivers/net/wireguard/queueing.c:68:18: warning: cast to 'typeof (*((__ai_ptr)))' (aka 'struct sk_buff *') from smaller integer type 'unsigned int' [-Wint-to-pointer-cast]
           WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
           ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
           arch_xchg_release(__ai_ptr, __VA_ARGS__); \
           ^
   include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
           __atomic_op_release(arch_xchg, __VA_ARGS__)
           ^
   include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
           op##_relaxed(args);                                             \
           ^
   note: (skipping 6 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
           ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
           ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
                   if (!(condition))                                       \
                         ^~~~~~~~~
>> drivers/net/wireguard/queueing.c:68:18: warning: cast to smaller integer type 'u32' (aka 'unsigned int') from 'typeof (_x_)' (aka 'struct sk_buff *') [-Wpointer-to-int-cast]
           WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
           arch_xchg_release(__ai_ptr, __VA_ARGS__); \
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
           __atomic_op_release(arch_xchg, __VA_ARGS__)
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
           op##_relaxed(args);                                             \
           ^~~~~~~~~~~~~~~~~~
   note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   drivers/net/wireguard/queueing.c:49:21: note: expanded from macro 'NEXT'
   #define NEXT(skb) ((skb)->prev)
                       ^~~
   include/asm-generic/rwonce.h:61:15: note: expanded from macro 'WRITE_ONCE'
           __WRITE_ONCE(x, val);                                           \
                        ^
   include/asm-generic/rwonce.h:55:20: note: expanded from macro '__WRITE_ONCE'
           *(volatile typeof(x) *)&(x) = (val);                            \
                             ^
>> drivers/net/wireguard/queueing.c:68:18: warning: cast to 'typeof (*((__ai_ptr)))' (aka 'struct sk_buff *') from smaller integer type 'unsigned int' [-Wint-to-pointer-cast]
           WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
           ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
           arch_xchg_release(__ai_ptr, __VA_ARGS__); \
           ^
   include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
           __atomic_op_release(arch_xchg, __VA_ARGS__)
           ^
   include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
           op##_relaxed(args);                                             \
           ^
   note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   drivers/net/wireguard/queueing.c:49:21: note: expanded from macro 'NEXT'
   #define NEXT(skb) ((skb)->prev)
                       ^
   include/asm-generic/rwonce.h:61:15: note: expanded from macro 'WRITE_ONCE'
           __WRITE_ONCE(x, val);                                           \
           ~~~~~~~~~~~~~^~~~~~~
   include/asm-generic/rwonce.h:55:20: note: expanded from macro '__WRITE_ONCE'
           *(volatile typeof(x) *)&(x) = (val);                            \
                             ^
>> drivers/net/wireguard/queueing.c:68:18: warning: cast to smaller integer type 'u32' (aka 'unsigned int') from 'typeof (_x_)' (aka 'struct sk_buff *') [-Wpointer-to-int-cast]
           WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
           arch_xchg_release(__ai_ptr, __VA_ARGS__); \
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
           __atomic_op_release(arch_xchg, __VA_ARGS__)
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
           op##_relaxed(args);                                             \
           ^~~~~~~~~~~~~~~~~~
   note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   drivers/net/wireguard/queueing.c:49:21: note: expanded from macro 'NEXT'
   #define NEXT(skb) ((skb)->prev)
                       ^~~
   include/asm-generic/rwonce.h:61:15: note: expanded from macro 'WRITE_ONCE'
           __WRITE_ONCE(x, val);                                           \
                        ^
   include/asm-generic/rwonce.h:55:27: note: expanded from macro '__WRITE_ONCE'
           *(volatile typeof(x) *)&(x) = (val);                            \
                                    ^
>> drivers/net/wireguard/queueing.c:68:18: warning: cast to 'typeof (*((__ai_ptr)))' (aka 'struct sk_buff *') from smaller integer type 'unsigned int' [-Wint-to-pointer-cast]
           WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
           ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
           arch_xchg_release(__ai_ptr, __VA_ARGS__); \
           ^
   include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
           __atomic_op_release(arch_xchg, __VA_ARGS__)
           ^
   include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
           op##_relaxed(args);                                             \
           ^
   note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   drivers/net/wireguard/queueing.c:49:21: note: expanded from macro 'NEXT'
   #define NEXT(skb) ((skb)->prev)
                       ^
   include/asm-generic/rwonce.h:61:15: note: expanded from macro 'WRITE_ONCE'
           __WRITE_ONCE(x, val);                                           \
           ~~~~~~~~~~~~~^~~~~~~
   include/asm-generic/rwonce.h:55:27: note: expanded from macro '__WRITE_ONCE'
           *(volatile typeof(x) *)&(x) = (val);                            \
                                    ^
   21 warnings generated.


vim +68 drivers/net/wireguard/queueing.c

8b5553ace83cced7 Jason A. Donenfeld 2021-02-22  64  
8b5553ace83cced7 Jason A. Donenfeld 2021-02-22  65  static void __wg_prev_queue_enqueue(struct prev_queue *queue, struct sk_buff *skb)
8b5553ace83cced7 Jason A. Donenfeld 2021-02-22  66  {
8b5553ace83cced7 Jason A. Donenfeld 2021-02-22  67  	WRITE_ONCE(NEXT(skb), NULL);
8b5553ace83cced7 Jason A. Donenfeld 2021-02-22 @68  	WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
8b5553ace83cced7 Jason A. Donenfeld 2021-02-22  69  }
8b5553ace83cced7 Jason A. Donenfeld 2021-02-22  70
Guo Ren July 28, 2022, 3:35 a.m. UTC | #2
Hi Palmer,

The warning is from a clang problem.

drivers/net/wireguard/queueing.c:
static void __wg_prev_queue_enqueue(struct prev_queue *queue, struct
sk_buff *skb)
{
        WRITE_ONCE(NEXT(skb), NULL);
        WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
}

The queue->head is 64bit pointer size.

#define __xchg_relaxed(ptr, new, size)                                  \
({                                                                      \
        __typeof__(ptr) __ptr = (ptr);                                  \
        __typeof__(new) __new = (new);                                  \
        __typeof__(*(ptr)) __ret;                                       \
        switch (size) {                                                 \
        case 2: {                                                       \
... Clang shouldn't give warning from here, because code won't enter the path.
                break;                                                  \
        }                                                               \
        case 4:                                                         \
...
                break;                                                  \
        case 8:                                                         \
... The case would enter this path.
                break;                                                  \
        default:                                                        \
                BUILD_BUG();                                            \
        }                                                               \
        __ret;                                                          \
})

On Thu, Jul 28, 2022 at 8:05 AM kernel test robot <lkp@intel.com> wrote:
>
> Hi,
>
> I love your patch! Perhaps something to improve:
>
> [auto build test WARNING on arnd-asm-generic/master]
> [also build test WARNING on linus/master v5.19-rc8 next-20220727]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
>
> url:    https://github.com/intel-lab-lkp/linux/commits/guoren-kernel-org/arch-Add-qspinlock-support-with-combo-style/20220724-202743
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git master
> config: riscv-randconfig-r026-20220727 (https://download.01.org/0day-ci/archive/20220728/202207280822.VHS6qieH-lkp@intel.com/config)
> compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 8dfaecc4c24494337933aff9d9166486ca0949f1)
> reproduce (this is a W=1 build):
>         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # install riscv cross compiling tool for clang build
>         # apt-get install binutils-riscv64-linux-gnu
>         # https://github.com/intel-lab-lkp/linux/commit/980c0acb7f432777e3473ab9a5696044e03b3f3d
>         git remote add linux-review https://github.com/intel-lab-lkp/linux
>         git fetch --no-tags linux-review guoren-kernel-org/arch-Add-qspinlock-support-with-combo-style/20220724-202743
>         git checkout 980c0acb7f432777e3473ab9a5696044e03b3f3d
>         # save the config file
>         mkdir build_dir && cp config build_dir/.config
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash drivers/net/wireguard/
>
> If you fix the issue, kindly add following tag where applicable
> Reported-by: kernel test robot <lkp@intel.com>
>
> All warnings (new ones prefixed by >>):
>
>    In file included from drivers/net/wireguard/queueing.c:6:
>    In file included from drivers/net/wireguard/queueing.h:9:
>    In file included from drivers/net/wireguard/peer.h:9:
>    In file included from drivers/net/wireguard/device.h:9:
>    In file included from drivers/net/wireguard/noise.h:8:
>    In file included from drivers/net/wireguard/messages.h:10:
>    In file included from include/crypto/chacha20poly1305.h:10:
>    In file included from include/linux/scatterlist.h:9:
>    In file included from arch/riscv/include/asm/io.h:136:
>    include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
>            val = __raw_readb(PCI_IOBASE + addr);
>                              ~~~~~~~~~~ ^
>    include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
>            val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
>                                                            ~~~~~~~~~~ ^
>    include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu'
>    #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
>                                                      ^
>    In file included from drivers/net/wireguard/queueing.c:6:
>    In file included from drivers/net/wireguard/queueing.h:9:
>    In file included from drivers/net/wireguard/peer.h:9:
>    In file included from drivers/net/wireguard/device.h:9:
>    In file included from drivers/net/wireguard/noise.h:8:
>    In file included from drivers/net/wireguard/messages.h:10:
>    In file included from include/crypto/chacha20poly1305.h:10:
>    In file included from include/linux/scatterlist.h:9:
>    In file included from arch/riscv/include/asm/io.h:136:
>    include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
>            val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
>                                                            ~~~~~~~~~~ ^
>    include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu'
>    #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
>                                                      ^
>    In file included from drivers/net/wireguard/queueing.c:6:
>    In file included from drivers/net/wireguard/queueing.h:9:
>    In file included from drivers/net/wireguard/peer.h:9:
>    In file included from drivers/net/wireguard/device.h:9:
>    In file included from drivers/net/wireguard/noise.h:8:
>    In file included from drivers/net/wireguard/messages.h:10:
>    In file included from include/crypto/chacha20poly1305.h:10:
>    In file included from include/linux/scatterlist.h:9:
>    In file included from arch/riscv/include/asm/io.h:136:
>    include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
>            __raw_writeb(value, PCI_IOBASE + addr);
>                                ~~~~~~~~~~ ^
>    include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
>            __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
>                                                          ~~~~~~~~~~ ^
>    include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
>            __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
>                                                          ~~~~~~~~~~ ^
>    include/asm-generic/io.h:1107:55: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
>            return (port > MMIO_UPPER_LIMIT) ? NULL : PCI_IOBASE + port;
>                                                      ~~~~~~~~~~ ^
> >> drivers/net/wireguard/queueing.c:68:18: warning: cast to smaller integer type 'u32' (aka 'unsigned int') from 'typeof (_x_)' (aka 'struct sk_buff *') [-Wpointer-to-int-cast]
>            WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
>                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
>            arch_xchg_release(__ai_ptr, __VA_ARGS__); \
>            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
>            __atomic_op_release(arch_xchg, __VA_ARGS__)
>            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
>            op##_relaxed(args);                                             \
>            ^~~~~~~~~~~~~~~~~~
>    note: (skipping 7 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
>    include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
>            _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
>                                ^~~~~~~~~
>    include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
>            __compiletime_assert(condition, msg, prefix, suffix)
>                                 ^~~~~~~~~
>    include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
>                    if (!(condition))                                       \
>                          ^~~~~~~~~
> >> drivers/net/wireguard/queueing.c:68:18: warning: cast to 'typeof (*((__ai_ptr)))' (aka 'struct sk_buff *') from smaller integer type 'unsigned int' [-Wint-to-pointer-cast]
>            WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
>            ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
>            arch_xchg_release(__ai_ptr, __VA_ARGS__); \
>            ^
>    include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
>            __atomic_op_release(arch_xchg, __VA_ARGS__)
>            ^
>    include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
>            op##_relaxed(args);                                             \
>            ^
>    note: (skipping 7 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
>    include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
>            _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
>            ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
>            __compiletime_assert(condition, msg, prefix, suffix)
>            ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
>                    if (!(condition))                                       \
>                          ^~~~~~~~~
> >> drivers/net/wireguard/queueing.c:68:18: warning: cast to smaller integer type 'u32' (aka 'unsigned int') from 'typeof (_x_)' (aka 'struct sk_buff *') [-Wpointer-to-int-cast]
>            WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
>                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
>            arch_xchg_release(__ai_ptr, __VA_ARGS__); \
>            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
>            __atomic_op_release(arch_xchg, __VA_ARGS__)
>            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
>            op##_relaxed(args);                                             \
>            ^~~~~~~~~~~~~~~~~~
>    note: (skipping 7 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
>    include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
>            _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
>                                ^~~~~~~~~
>    include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
>            __compiletime_assert(condition, msg, prefix, suffix)
>                                 ^~~~~~~~~
>    include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
>                    if (!(condition))                                       \
>                          ^~~~~~~~~
> >> drivers/net/wireguard/queueing.c:68:18: warning: cast to 'typeof (*((__ai_ptr)))' (aka 'struct sk_buff *') from smaller integer type 'unsigned int' [-Wint-to-pointer-cast]
>            WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
>            ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
>            arch_xchg_release(__ai_ptr, __VA_ARGS__); \
>            ^
>    include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
>            __atomic_op_release(arch_xchg, __VA_ARGS__)
>            ^
>    include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
>            op##_relaxed(args);                                             \
>            ^
>    note: (skipping 7 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
>    include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
>            _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
>            ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
>            __compiletime_assert(condition, msg, prefix, suffix)
>            ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
>                    if (!(condition))                                       \
>                          ^~~~~~~~~
> >> drivers/net/wireguard/queueing.c:68:18: warning: cast to smaller integer type 'u32' (aka 'unsigned int') from 'typeof (_x_)' (aka 'struct sk_buff *') [-Wpointer-to-int-cast]
>            WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
>                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
>            arch_xchg_release(__ai_ptr, __VA_ARGS__); \
>            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
>            __atomic_op_release(arch_xchg, __VA_ARGS__)
>            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
>            op##_relaxed(args);                                             \
>            ^~~~~~~~~~~~~~~~~~
>    note: (skipping 7 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
>    include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
>            _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
>                                ^~~~~~~~~
>    include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
>            __compiletime_assert(condition, msg, prefix, suffix)
>                                 ^~~~~~~~~
>    include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
>                    if (!(condition))                                       \
>                          ^~~~~~~~~
> >> drivers/net/wireguard/queueing.c:68:18: warning: cast to 'typeof (*((__ai_ptr)))' (aka 'struct sk_buff *') from smaller integer type 'unsigned int' [-Wint-to-pointer-cast]
>            WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
>            ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
>            arch_xchg_release(__ai_ptr, __VA_ARGS__); \
>            ^
>    include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
>            __atomic_op_release(arch_xchg, __VA_ARGS__)
>            ^
>    include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
>            op##_relaxed(args);                                             \
>            ^
>    note: (skipping 7 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
>    include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
>            _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
>            ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
>            __compiletime_assert(condition, msg, prefix, suffix)
>            ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
>                    if (!(condition))                                       \
>                          ^~~~~~~~~
> >> drivers/net/wireguard/queueing.c:68:18: warning: cast to smaller integer type 'u32' (aka 'unsigned int') from 'typeof (_x_)' (aka 'struct sk_buff *') [-Wpointer-to-int-cast]
>            WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
>                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
>            arch_xchg_release(__ai_ptr, __VA_ARGS__); \
>            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
>            __atomic_op_release(arch_xchg, __VA_ARGS__)
>            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
>            op##_relaxed(args);                                             \
>            ^~~~~~~~~~~~~~~~~~
>    note: (skipping 7 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
>    include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
>            _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
>                                ^~~~~~~~~
>    include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
>            __compiletime_assert(condition, msg, prefix, suffix)
>                                 ^~~~~~~~~
>    include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
>                    if (!(condition))                                       \
>                          ^~~~~~~~~
> >> drivers/net/wireguard/queueing.c:68:18: warning: cast to 'typeof (*((__ai_ptr)))' (aka 'struct sk_buff *') from smaller integer type 'unsigned int' [-Wint-to-pointer-cast]
>            WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
>            ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
>            arch_xchg_release(__ai_ptr, __VA_ARGS__); \
>            ^
>    include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
>            __atomic_op_release(arch_xchg, __VA_ARGS__)
>            ^
>    include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
>            op##_relaxed(args);                                             \
>            ^
>    note: (skipping 7 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
>    include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
>            _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
>            ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
>            __compiletime_assert(condition, msg, prefix, suffix)
>            ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
>                    if (!(condition))                                       \
>                          ^~~~~~~~~
> >> drivers/net/wireguard/queueing.c:68:18: warning: cast to smaller integer type 'u32' (aka 'unsigned int') from 'typeof (_x_)' (aka 'struct sk_buff *') [-Wpointer-to-int-cast]
>            WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
>                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
>            arch_xchg_release(__ai_ptr, __VA_ARGS__); \
>            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
>            __atomic_op_release(arch_xchg, __VA_ARGS__)
>            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
>            op##_relaxed(args);                                             \
>            ^~~~~~~~~~~~~~~~~~
>    note: (skipping 6 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
>    include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
>            _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
>                                ^~~~~~~~~
>    include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
>            __compiletime_assert(condition, msg, prefix, suffix)
>                                 ^~~~~~~~~
>    include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
>                    if (!(condition))                                       \
>                          ^~~~~~~~~
> >> drivers/net/wireguard/queueing.c:68:18: warning: cast to 'typeof (*((__ai_ptr)))' (aka 'struct sk_buff *') from smaller integer type 'unsigned int' [-Wint-to-pointer-cast]
>            WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
>            ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
>            arch_xchg_release(__ai_ptr, __VA_ARGS__); \
>            ^
>    include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
>            __atomic_op_release(arch_xchg, __VA_ARGS__)
>            ^
>    include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
>            op##_relaxed(args);                                             \
>            ^
>    note: (skipping 6 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
>    include/linux/compiler_types.h:352:22: note: expanded from macro 'compiletime_assert'
>            _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
>            ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/compiler_types.h:340:23: note: expanded from macro '_compiletime_assert'
>            __compiletime_assert(condition, msg, prefix, suffix)
>            ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/compiler_types.h:332:9: note: expanded from macro '__compiletime_assert'
>                    if (!(condition))                                       \
>                          ^~~~~~~~~
> >> drivers/net/wireguard/queueing.c:68:18: warning: cast to smaller integer type 'u32' (aka 'unsigned int') from 'typeof (_x_)' (aka 'struct sk_buff *') [-Wpointer-to-int-cast]
>            WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
>                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
>            arch_xchg_release(__ai_ptr, __VA_ARGS__); \
>            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
>            __atomic_op_release(arch_xchg, __VA_ARGS__)
>            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
>            op##_relaxed(args);                                             \
>            ^~~~~~~~~~~~~~~~~~
>    note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
>    drivers/net/wireguard/queueing.c:49:21: note: expanded from macro 'NEXT'
>    #define NEXT(skb) ((skb)->prev)
>                        ^~~
>    include/asm-generic/rwonce.h:61:15: note: expanded from macro 'WRITE_ONCE'
>            __WRITE_ONCE(x, val);                                           \
>                         ^
>    include/asm-generic/rwonce.h:55:20: note: expanded from macro '__WRITE_ONCE'
>            *(volatile typeof(x) *)&(x) = (val);                            \
>                              ^
> >> drivers/net/wireguard/queueing.c:68:18: warning: cast to 'typeof (*((__ai_ptr)))' (aka 'struct sk_buff *') from smaller integer type 'unsigned int' [-Wint-to-pointer-cast]
>            WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
>            ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
>            arch_xchg_release(__ai_ptr, __VA_ARGS__); \
>            ^
>    include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
>            __atomic_op_release(arch_xchg, __VA_ARGS__)
>            ^
>    include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
>            op##_relaxed(args);                                             \
>            ^
>    note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
>    drivers/net/wireguard/queueing.c:49:21: note: expanded from macro 'NEXT'
>    #define NEXT(skb) ((skb)->prev)
>                        ^
>    include/asm-generic/rwonce.h:61:15: note: expanded from macro 'WRITE_ONCE'
>            __WRITE_ONCE(x, val);                                           \
>            ~~~~~~~~~~~~~^~~~~~~
>    include/asm-generic/rwonce.h:55:20: note: expanded from macro '__WRITE_ONCE'
>            *(volatile typeof(x) *)&(x) = (val);                            \
>                              ^
> >> drivers/net/wireguard/queueing.c:68:18: warning: cast to smaller integer type 'u32' (aka 'unsigned int') from 'typeof (_x_)' (aka 'struct sk_buff *') [-Wpointer-to-int-cast]
>            WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
>                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
>            arch_xchg_release(__ai_ptr, __VA_ARGS__); \
>            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
>            __atomic_op_release(arch_xchg, __VA_ARGS__)
>            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
>            op##_relaxed(args);                                             \
>            ^~~~~~~~~~~~~~~~~~
>    note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
>    drivers/net/wireguard/queueing.c:49:21: note: expanded from macro 'NEXT'
>    #define NEXT(skb) ((skb)->prev)
>                        ^~~
>    include/asm-generic/rwonce.h:61:15: note: expanded from macro 'WRITE_ONCE'
>            __WRITE_ONCE(x, val);                                           \
>                         ^
>    include/asm-generic/rwonce.h:55:27: note: expanded from macro '__WRITE_ONCE'
>            *(volatile typeof(x) *)&(x) = (val);                            \
>                                     ^
> >> drivers/net/wireguard/queueing.c:68:18: warning: cast to 'typeof (*((__ai_ptr)))' (aka 'struct sk_buff *') from smaller integer type 'unsigned int' [-Wint-to-pointer-cast]
>            WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
>            ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>    include/linux/atomic/atomic-instrumented.h:1901:2: note: expanded from macro 'xchg_release'
>            arch_xchg_release(__ai_ptr, __VA_ARGS__); \
>            ^
>    include/linux/atomic/atomic-arch-fallback.h:24:2: note: expanded from macro 'arch_xchg_release'
>            __atomic_op_release(arch_xchg, __VA_ARGS__)
>            ^
>    include/linux/atomic.h:68:2: note: expanded from macro '__atomic_op_release'
>            op##_relaxed(args);                                             \
>            ^
>    note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
>    drivers/net/wireguard/queueing.c:49:21: note: expanded from macro 'NEXT'
>    #define NEXT(skb) ((skb)->prev)
>                        ^
>    include/asm-generic/rwonce.h:61:15: note: expanded from macro 'WRITE_ONCE'
>            __WRITE_ONCE(x, val);                                           \
>            ~~~~~~~~~~~~~^~~~~~~
>    include/asm-generic/rwonce.h:55:27: note: expanded from macro '__WRITE_ONCE'
>            *(volatile typeof(x) *)&(x) = (val);                            \
>                                     ^
>    21 warnings generated.
>
>
> vim +68 drivers/net/wireguard/queueing.c
>
> 8b5553ace83cced7 Jason A. Donenfeld 2021-02-22  64
> 8b5553ace83cced7 Jason A. Donenfeld 2021-02-22  65  static void __wg_prev_queue_enqueue(struct prev_queue *queue, struct sk_buff *skb)
> 8b5553ace83cced7 Jason A. Donenfeld 2021-02-22  66  {
> 8b5553ace83cced7 Jason A. Donenfeld 2021-02-22  67      WRITE_ONCE(NEXT(skb), NULL);
> 8b5553ace83cced7 Jason A. Donenfeld 2021-02-22 @68      WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
> 8b5553ace83cced7 Jason A. Donenfeld 2021-02-22  69  }
> 8b5553ace83cced7 Jason A. Donenfeld 2021-02-22  70
>
> --
> 0-DAY CI Kernel Test Service
> https://01.org/lkp
Arnd Bergmann July 28, 2022, 8:14 a.m. UTC | #3
On Thu, Jul 28, 2022 at 5:35 AM Guo Ren <guoren@kernel.org> wrote:
>
> Hi Palmer,
>
> The warning is from a clang problem.
>
> drivers/net/wireguard/queueing.c:
> static void __wg_prev_queue_enqueue(struct prev_queue *queue, struct
> sk_buff *skb)
> {
>         WRITE_ONCE(NEXT(skb), NULL);
>         WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
> }
>
> The queue->head is 64bit pointer size.
>
> #define __xchg_relaxed(ptr, new, size)                                  \
> ({                                                                      \
>         __typeof__(ptr) __ptr = (ptr);                                  \
>         __typeof__(new) __new = (new);                                  \
>         __typeof__(*(ptr)) __ret;                                       \
>         switch (size) {                                                 \
>         case 2: {                                                       \
> ... Clang shouldn't give warning from here, because code won't enter the path.
>                 break;                                                  \
>         }                                                               \
>         case 4:                                                         \
> ...
>                 break;                                                  \
>         case 8:                                                         \
> ... The case would enter this path.
>                 break;                                                  \
>         default:                                                        \
>                 BUILD_BUG();                                            \
>         }                                                               \
>         __ret;                                                          \
> })

I assume it's this warning you are referring to?

>> drivers/net/wireguard/queueing.c:68:18: warning: cast to 'typeof (*((__ai_ptr)))' (aka 'struct sk_buff *') from smaller integer type 'unsigned int' [-Wint-to-pointer-cast]
           WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);

I don't consider this a bug in clang, it just performs the normal type checking
before dead code elimination and complains about code that clearly violates
the type rules.

I would suggest you split out the 16-bit xchg() into a properly typed inline
function and add type casts when calling it. In fact, I would love to
completely eliminate the 8-bit and 16-bit cases from the regular xchg()
and cmpxchg() interface and require all callers to explicitly call the
xchg16()/cmpxchg16() instead, as we require for cmpxchg64() on 32-bit
architectures already. This is something to do for another time though.

> >    include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
> >            val = __raw_readb(PCI_IOBASE + addr);
> >                              ~~~~~~~~~~ ^
> >    include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
> >            val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));

Not your bug, but I see that CONFIG_MMU=n risc-v has the same bug that s390 has
with missing I/O space support.  The correct workaround for this is to mark all
drivers using PCI I/O space as 'depends on HAS_IO_PORT' or similar and then
leaving out the definitions from the asm-generic header. Niklas Schnelle has
spent a lot of time working on patches for this, but they are somewhat stuck
in review. If RISC-V has the same problem, I hope we can get more people
interested in it. I think OpenRISC and C-Sky have this as well, but I'm not
sure if there is any plan to upstream clang support for those.

        Arnd
Guo Ren July 28, 2022, 8:34 a.m. UTC | #4
On Thu, Jul 28, 2022 at 4:14 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Thu, Jul 28, 2022 at 5:35 AM Guo Ren <guoren@kernel.org> wrote:
> >
> > Hi Palmer,
> >
> > The warning is from a clang problem.
> >
> > drivers/net/wireguard/queueing.c:
> > static void __wg_prev_queue_enqueue(struct prev_queue *queue, struct
> > sk_buff *skb)
> > {
> >         WRITE_ONCE(NEXT(skb), NULL);
> >         WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
> > }
> >
> > The queue->head is 64bit pointer size.
> >
> > #define __xchg_relaxed(ptr, new, size)                                  \
> > ({                                                                      \
> >         __typeof__(ptr) __ptr = (ptr);                                  \
> >         __typeof__(new) __new = (new);                                  \
> >         __typeof__(*(ptr)) __ret;                                       \
> >         switch (size) {                                                 \
> >         case 2: {                                                       \
> > ... Clang shouldn't give warning from here, because code won't enter the path.
> >                 break;                                                  \
> >         }                                                               \
> >         case 4:                                                         \
> > ...
> >                 break;                                                  \
> >         case 8:                                                         \
> > ... The case would enter this path.
> >                 break;                                                  \
> >         default:                                                        \
> >                 BUILD_BUG();                                            \
> >         }                                                               \
> >         __ret;                                                          \
> > })
>
> I assume it's this warning you are referring to?
>
> >> drivers/net/wireguard/queueing.c:68:18: warning: cast to 'typeof (*((__ai_ptr)))' (aka 'struct sk_buff *') from smaller integer type 'unsigned int' [-Wint-to-pointer-cast]
>            WRITE_ONCE(NEXT(xchg_release(&queue->head, skb)), skb);
>
> I don't consider this a bug in clang, it just performs the normal type checking
> before dead code elimination and complains about code that clearly violates
> the type rules.
>
> I would suggest you split out the 16-bit xchg() into a properly typed inline
> function and add type casts when calling it.
Okay, I would try that style.

> In fact, I would love to
> completely eliminate the 8-bit and 16-bit cases from the regular xchg()
> and cmpxchg() interface and require all callers to explicitly call the
> xchg16()/cmpxchg16() instead, as we require for cmpxchg64() on 32-bit
> architectures already. This is something to do for another time though.
>
> > >    include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
> > >            val = __raw_readb(PCI_IOBASE + addr);
> > >                              ~~~~~~~~~~ ^
> > >    include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
> > >            val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
>
> Not your bug, but I see that CONFIG_MMU=n risc-v has the same bug that s390 has
> with missing I/O space support.  The correct workaround for this is to mark all
> drivers using PCI I/O space as 'depends on HAS_IO_PORT' or similar and then
> leaving out the definitions from the asm-generic header. Niklas Schnelle has
> spent a lot of time working on patches for this, but they are somewhat stuck
> in review. If RISC-V has the same problem, I hope we can get more people
> interested in it. I think OpenRISC and C-Sky have this as well, but I'm not
> sure if there is any plan to upstream clang support for those.
C-SKY hasn't any plan to support clang, as I know.

>
>         Arnd
diff mbox series

Patch

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index bff04916a6c5..721f098228a8 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -359,6 +359,22 @@  config NODES_SHIFT
 	  Specify the maximum number of NUMA Nodes available on the target
 	  system.  Increases memory reserved to accommodate various tables.
 
+choice
+	prompt "RISC-V spinlock type"
+	default RISCV_TICKET_SPINLOCKS
+
+config RISCV_TICKET_SPINLOCKS
+	bool "Using ticket spinlock"
+
+config RISCV_QUEUED_SPINLOCKS
+	bool "Using queued spinlock"
+	depends on SMP && MMU
+	select ARCH_USE_QUEUED_SPINLOCKS
+	help
+	  Make sure your micro arch LL/SC has a strong forward progress guarantee.
+	  Otherwise, stay at ticket-lock/combo-lock.
+endchoice
+
 config RISCV_ALTERNATIVE
 	bool
 	depends on !XIP_KERNEL
diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild
index 504f8b7e72d4..2cce98c7b653 100644
--- a/arch/riscv/include/asm/Kbuild
+++ b/arch/riscv/include/asm/Kbuild
@@ -2,7 +2,9 @@ 
 generic-y += early_ioremap.h
 generic-y += flat.h
 generic-y += kvm_para.h
+generic-y += mcs_spinlock.h
 generic-y += parport.h
+generic-y += qspinlock.h
 generic-y += spinlock.h
 generic-y += spinlock_types.h
 generic-y += qrwlock.h
diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
index 67ab6375b650..6bf2726d4500 100644
--- a/arch/riscv/include/asm/cmpxchg.h
+++ b/arch/riscv/include/asm/cmpxchg.h
@@ -17,6 +17,23 @@ 
 	__typeof__(new) __new = (new);					\
 	__typeof__(*(ptr)) __ret;					\
 	switch (size) {							\
+	case 2: { 							\
+		u32 tmp, ret;						\
+		u32 shif = ((ulong)__ptr & 2) ? 16 : 0;			\
+		u32 mask = 0xffff << shif;				\
+		__ptr = (__typeof__(ptr))((ulong)__ptr & ~2);		\
+		__asm__ __volatile__ (					\
+			"0:	lr.w %0, %2\n"				\
+			"	and  %1, %0, %z3\n"			\
+			"	or   %1, %1, %z4\n"			\
+			"	sc.w %1, %1, %2\n"			\
+			"	bnez %1, 0b\n"				\
+			: "=&r" (ret), "=&r" (tmp), "+A" (*__ptr)	\
+			: "rJ" (~mask), "rJ" ((u32)__new << shif)	\
+			: "memory");					\
+		__ret = (__typeof__(*(ptr)))((ret & mask) >> shif);	\
+		break;							\
+	}								\
 	case 4:								\
 		__asm__ __volatile__ (					\
 			"	amoswap.w %0, %2, %1\n"			\