0

Does bpf support atomic_t and atomic_{add,inc,read} variants of linux kernel.

Variable gets modified by diff bpf kernel handler. Tried following kernel bpf, some compiler error which i dont understand. Any limitations are there on bpf atomic operations use ?

#include <linux/skbuff.h>                                                                                                                                    #include <linux/netdevice.h>                                                                                                                                 #include <uapi/linux/bpf.h>                                                                                                                                  #include <linux/version.h>                                                                                                                                   #include <bpf/bpf_helpers.h>
 #include <bpf/bpf_tracing.h>

 //static volatile __u64 fcount;
 //#define ATOMIC_INC(v)  __atomic_add_fetch((v), 1, __ATOMIC_SEQ_CST)
 //#define ATOMIC_READ(v) __atomic_fetch_add((v), 0, __ATOMIC_SEQ_CST)
 //#define ATOMIC_READ(v) __sync_fetch_and_add_N((v), 0)

 atomic64_t fcount;

 SEC("tp/syscalls/sys_enter_execve")
 int handle_execve(void *ctx)
 {
  //   ATOMIC_INC(&fcount);
    // atomic_inc(&fcount);
    atomic64_inc(&fcount);
     atomic64_read(&fcount);
     bpf_printk("Exec Called\n");
     return 0;
 }

 char _license[] SEC("license") = "GPL";
 u32 _version SEC("version") = LINUX_VERSION_CODE;


Compilation error

<inline asm>:6:2: error: too few operands for instruction
        lock; incq (r1 + 0)
        ^
note: !srcloc = 2149115239
<inline asm>:6:8: error: invalid register/token name
        lock; incq (r1 + 0)
              ^
note: !srcloc = 2149115239
make: *** [Makefile:51: tracex1_kern.o] Error 1
nullptr
  • 5
  • 3

2 Answers2

0

Any limitations are there on bpf atomic operations use ?

The BPF instruction set has a more limited set of atomic operations then you might find on actual processor. Incrementing atomically is one that isn't supported instructions, you would have to use atomic addition.

Sticking to the builtin atomics functions has the best result but only for those that can be translated into BPF instuctions.

Dylan Reimerink
  • 5,874
  • 2
  • 15
  • 21
0

for llvm/clang compiler, you can use below atomic operations in the ebpf program:

__sync_fetch_and_add (32, 64)
__sync_fetch_and_sub (32, 64)
__sync_fetch_and_and (32, 64)
__sync_fetch_and_or  (32, 64) 
__sync_fetch_and_xor (32, 64)
__sync_lock_test_and_set (32, 64)
__sync_val_compare_and_swap (32, 64)

for example:

__u32 number = 0;
__u32 ret = 0;
ret = __sync_fetch_and_add(&number, 1);
mozillazg
  • 542
  • 4
  • 9