[PATCH] D72184: [WIP][BPF] support compare-and-exchange instruction

Yonghong Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 3 14:36:30 PST 2020


yonghong-song created this revision.
yonghong-song added a reviewer: ast.
Herald added subscribers: llvm-commits, jfb, hiraditya.
Herald added a project: LLVM.

Implement compare-and-exchange instruction for BPF.

The use case:
During Martin's congestion control work, kernel
data structure is accessed and some fields may be
written. In the kernel, compare-and-exchange is
used to handle race. The same should be done
in bpf program, otherwise, we have a race here.

Interface:
At C level, the following gcc builtin function is used:

  val = __sync_val_compare_and_swap(p, old, new);

The compiler will generate assembly code like:

  dest_reg = cmpxchg_u<8,16,32,64>(base_reg + offset, dest_reg, new_reg);

dest_reg is a read/write register, input is the old value, the result
is written to dest_reg.

Encoding:

  opcode: class: STX, width: B, H, W, DW, opcode: CMPXCHG

Since there are three registers are involved, the "new_reg" is encoded
at 0-3 bits of the inst->imm field.
The current encoding might not be the best, we can iterate on top of it.

An example with +alu32 mode:

  -bash-4.4$ cat xchg.c
  char test1(char *p, char a, char b) { return __sync_val_compare_and_swap(p, a, 5); }
  int  test2(int *p, int a, int b) { return __sync_val_compare_and_swap(p, a, b); }
  typedef unsigned long long __u64;
  __u64 test3(__u64 *p, __u64 a, __u64 b) { return __sync_val_compare_and_swap(p, a, b); }
  
  -bash-4.4$ clang -target bpf -O2 -S -emit-llvm xchg.c
  -bash-4.4$ llc -march=bpf -filetype=obj xchg.ll
  -bash-4.4$ llvm-objdump -d --mattr=+alu32 xchg.o
  0000000000000000 test1:
       0:       bf 20 00 00 00 00 00 00 r0 = r2
       1:       b7 02 00 00 05 00 00 00 r2 = 5 
       2:       f3 01 00 00 02 00 00 00 w0 = cmpxchg32_u8(r1 + 0, w0, w2) 
       3:       67 00 00 00 38 00 00 00 r0 <<= 56
       4:       c7 00 00 00 38 00 00 00 r0 s>>= 56
       5:       95 00 00 00 00 00 00 00 exit
  
  0000000000000030 test2:
       6:       bf 20 00 00 00 00 00 00 r0 = r2
       7:       e3 01 00 00 03 00 00 00 w0 = cmpxchg32_u32(r1 + 0, w0, w3) 
       8:       95 00 00 00 00 00 00 00 exit
  
  0000000000000048 test3:
       9:       bf 20 00 00 00 00 00 00 r0 = r2
      10:       fb 01 00 00 03 00 00 00 r0 = cmpxchg_u64(r1 + 0, r0, r3) 
      11:       95 00 00 00 00 00 00 00 exit


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D72184

Files:
  llvm/lib/Target/BPF/BPFInstrFormats.td
  llvm/lib/Target/BPF/BPFInstrInfo.td
  llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D72184.236130.patch
Type: text/x-patch
Size: 4728 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200103/cf40a2a4/attachment.bin>


More information about the llvm-commits mailing list