[PATCH] bpf: smp_wmb before bpf_ringbuf really commit

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux