[PATCH] D72184: [BPF] support atomic instructions

Brendan Jackman via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 23 07:23:30 PST 2020


jackmanb added a comment.

BTW to investigate my previous comment I tried compiling this code:

  // SPDX-License-Identifier: GPL-2.0
  #include <linux/bpf.h>
  #include <bpf/bpf_helpers.h>
  #include <bpf/bpf_tracing.h>
  
  __u64 add64_value = 1;
  __u64 add64_result;
  __u32 add32_value = 1;
  __u32 add32_result;
  __u64 add_stack_value_copy;
  __u64 add_stack_result;
  SEC("fentry/bpf_fentry_test1")
  int BPF_PROG(add, int a)
  {
          __u64 add_stack_value = 1;
  
          add64_result = __sync_fetch_and_add(&add64_value, 2);
          add32_result = __sync_fetch_and_add(&add32_value, 2);
          add_stack_result = __sync_fetch_and_add(&add_stack_value, 2);
          add_stack_value_copy = add_stack_value;
  
          return 0;
  }
  
  __u64 cmpxchg64_value = 1;
  __u64 cmpxchg64_result_fail;
  __u64 cmpxchg64_result_succeed;
  __u32 cmpxchg32_value = 1;
  __u32 cmpxchg32_result_fail;
  __u32 cmpxchg32_result_succeed;
  SEC("fentry/bpf_fentry_test1")
  int BPF_PROG(cmpxchg, int a)
  {
          cmpxchg64_result_fail = __sync_val_compare_and_swap(
                  &cmpxchg64_value, 0, 3);
          cmpxchg64_result_succeed = __sync_val_compare_and_swap(
                  &cmpxchg64_value, 1, 2);
  
          cmpxchg32_result_fail = __sync_val_compare_and_swap(
                  &cmpxchg32_value, 0, 3);
          cmpxchg32_result_succeed = __sync_val_compare_and_swap(
                  &cmpxchg32_value, 1, 2);
  
          return 0;
  }
  
  __u64 xchg64_value = 1;
  __u64 xchg64_result;
  __u32 xchg32_value = 1;
  __u32 xchg32_result;
  SEC("fentry/bpf_fentry_test1")
  int BPF_PROG(xchg, int a)
  {
          __u64 val64 = 2;
          __u32 val32 = 2;
  
          __atomic_exchange(&xchg64_value, &val64, &xchg64_result, __ATOMIC_RELAXED);
          __atomic_exchange(&xchg32_value, &val32, &xchg32_result, __ATOMIC_RELAXED);
          __atomic_store(&xchg64_result, &val64, __ATOMIC_SEQ_CST);
  
          return 0;
  }

(By modifying  this code <https://github.com/bjackman/linux-bpf/commit/286489cd5051442b78705e1e5969b7c56b949e68#diff-b040080f7b5320bf72c70aba5f634616e5d79a5df5a043eea0891e7958d4d375> to add the `__atomic_store` and then running `make -C ~/src/linux/linux/tools/testing/selftests/bpf -j test_progs` from the base of the kernel tree)

And got a crash:

  $ make -C ~/src/linux/linux/tools/testing/selftests/bpf -j test_progs  
  make: Entering directory '/usr/local/google/home/jackmanb/src/linux/linux/tools/testing/selftests/bpf'
    CLNG-LLC [test_maps] atomics_test.o
  LLVM ERROR: Cannot select: 0x5638e9444528: ch = AtomicStore<(store seq_cst 8 into @xchg64_result)> 0x5638e94445f8, 0x5638e9444660, Constant:i64<2>, progs/atomics_test.c:59:2 @[ progs/atomics_test.c:52:5 ]
    0x5638e9444660: i64 = BPFISD::Wrapper TargetGlobalAddress:i64<i64* @xchg64_result> 0, progs/atomics_test.c:57:2 @[ progs/atomics_test.c:52:5 ]
      0x5638e9444b40: i64 = TargetGlobalAddress<i64* @xchg64_result> 0, progs/atomics_test.c:57:2 @[ progs/atomics_test.c:52:5 ]
    0x5638e94628c0: i64 = Constant<2>
  In function: xchg
  PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace.
  Stack dump:
  0.      Program arguments: llc -mattr=dwarfris -march=bpf -mcpu=v4 -mattr=+alu32 -filetype=obj -o /usr/local/google/home/jackmanb/src/linux/linux/tools/testing/selftests/bpf/atomics_test.o
  1.      Running pass 'Function Pass Manager' on module '<stdin>'.
  2.      Running pass 'BPF DAG->DAG Pattern Instruction Selection' on function '@xchg'
   #0 0x00005638e543ae1d llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/usr/local/bin/llc+0x26f4e1d)
   #1 0x00005638e5438c14 llvm::sys::RunSignalHandlers() (/usr/local/bin/llc+0x26f2c14)
   #2 0x00005638e5438d70 SignalHandler(int) (/usr/local/bin/llc+0x26f2d70)
   #3 0x00007ff91703b140 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14140)
   #4 0x00007ff916b1edb1 raise ./signal/../sysdeps/unix/sysv/linux/raise.c:51:1
   #5 0x00007ff916b08537 abort ./stdlib/abort.c:81:7
   #6 0x00005638e53b393c llvm::report_fatal_error(llvm::Twine const&, bool) (/usr/local/bin/llc+0x266d93c)
   #7 0x00005638e53b3a6e (/usr/local/bin/llc+0x266da6e)
   #8 0x00005638e527bac0 llvm::SelectionDAGISel::CannotYetSelect(llvm::SDNode*) (/usr/local/bin/llc+0x2535ac0)
   #9 0x00005638e527c8b1 llvm::SelectionDAGISel::SelectCodeCommon(llvm::SDNode*, unsigned char const*, unsigned int) (/usr/local/bin/llc+0x25368b1)
  #10 0x00005638e527a5d7 llvm::SelectionDAGISel::DoInstructionSelection() (/usr/local/bin/llc+0x25345d7)
  #11 0x00005638e52833f5 llvm::SelectionDAGISel::CodeGenAndEmitDAG() (/usr/local/bin/llc+0x253d3f5)
  #12 0x00005638e5287471 llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) (/usr/local/bin/llc+0x2541471)
  #13 0x00005638e5289dbc llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) (.part.0) (/usr/local/bin/llc+0x2543dbc)
  #14 0x00005638e491a5d4 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (/usr/local/bin/llc+0x1bd45d4)
  #15 0x00005638e4d0a050 llvm::FPPassManager::runOnFunction(llvm::Function&) (/usr/local/bin/llc+0x1fc4050)
  #16 0x00005638e4d0b5dc llvm::FPPassManager::runOnModule(llvm::Module&) (/usr/local/bin/llc+0x1fc55dc)
  #17 0x00005638e4d09208 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/usr/local/bin/llc+0x1fc3208)
  #18 0x00005638e33ba5d7 main (/usr/local/bin/llc+0x6745d7)
  #19 0x00007ff916b09cca __libc_start_main ./csu/../csu/libc-start.c:308:16
  #20 0x00005638e344dd1a _start (/usr/local/bin/llc+0x707d1a)
  make: *** [Makefile:396: /usr/local/google/home/jackmanb/src/linux/linux/tools/testing/selftests/bpf/atomics_test.o] Error 134
  make: Leaving directory '/usr/local/google/home/jackmanb/src/linux/linux/tools/testing/selftests/bpf'


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72184/new/

https://reviews.llvm.org/D72184



More information about the cfe-commits mailing list