From: zhongjinji <zhongjinji@xxxxxxxxx> To guarantee visibility of writing ringbuffer,it is necessary to call smp_wmb before ringbuffer really commit. for instance, when updating the data of buffer in cpu1, it is not visible for the cpu2 which may be accessing buffer. This may lead to the consumer accessing a incorrect data. using the smp_wmb before commmit will guarantee that the consume can access the correct data. CPU1: struct mem_event_t* data = bpf_ringbuf_reserve(); data->type = MEM_EVENT_KSWAPD_WAKE; data->event_data.kswapd_wake.node_id = args->nid; bpf_ringbuf_commit(data); CPU2: cons_pos = smp_load_acquire(r->consumer_pos); len_ptr = r->data + (cons_pos & r->mask); sample = (void *)len_ptr + BPF_RINGBUF_HDR_SZ; access to sample Signed-off-by: zhongjinji <zhongjinji@xxxxxxxxx> --- kernel/bpf/ringbuf.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/bpf/ringbuf.c b/kernel/bpf/ringbuf.c index e1cfe890e0be..a66059e2b0d6 100644 --- a/kernel/bpf/ringbuf.c +++ b/kernel/bpf/ringbuf.c @@ -508,6 +508,10 @@ static void bpf_ringbuf_commit(void *sample, u64 flags, bool discard) rec_pos = (void *)hdr - (void *)rb->data; cons_pos = smp_load_acquire(&rb->consumer_pos) & rb->mask; + /* Make sure the modification of data is visible on other CPU's + * before consume the event + */ + smp_wmb(); if (flags & BPF_RB_FORCE_WAKEUP) irq_work_queue(&rb->work); else if (cons_pos == rec_pos && !(flags & BPF_RB_NO_WAKEUP)) -- 2.17.1