Cong Wang <xiyou.wangcong@xxxxxxxxx> 于2021年11月27日周六 上午4:25写道: > > On Thu, Nov 25, 2021 at 04:34:48PM +0800, Yahui Chen wrote: > > Suppose we have a map, MAP_A, and the user program does the following: > > > > 1. bpf_map_lookup_elem(MAP_A, key, value) > > 2. change the value > > 3. bpf_map_update_elem(MAP_A, key, value, FLAG) > > > > At the same time, the kernel's BPF program may also be modifying the value. > > > > Then we have concurrency problems. > > > > This is why we have bpf spinlock. ;) > I get a bpf_spinlock example from https://patchwork.ozlabs.org/project/netdev/patch/20190124041403.2100609-2-ast@xxxxxxxxxx/: ``` Example: struct hash_elem { int cnt; struct bpf_spin_lock lock; }; struct hash_elem * val = bpf_map_lookup_elem(&hash_map, &key); if (val) { bpf_spin_lock(&val->lock); val->cnt++; bpf_spin_unlock(&val->lock); } ``` But, I think bpf_spinlock cannot be used in user mode. > > > Therefore, can we add a helper function like compare and swap? > > > > I don't think you can atomically compare and swap values larger than > CPU word size. > Yep, you are right. So I imagined adding something code like `memcmp` to the kernel before update bpf map element. If memcmp success then update the element, otherwise return fail. New helper function looks like: bpf_map_compare_and_update_elem(MAP_A, key, old_value, new_value, FLAG) > > Thanks.