Search code examples
ebpfbpflibbpf

atomic operations in bpf kernel program (does bpf support linux kernel native atomic operations)


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

Solution

  • 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);