On Wed, Aug 7, 2024 at 4:58 PM Kui-Feng Lee <thinker.li@xxxxxxxxx> wrote: > + > + user_data_mmap = mmap(NULL, sizeof(*user_data_mmap), PROT_READ | PROT_WRITE, > + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); > + if (!ASSERT_NEQ(user_data_mmap, MAP_FAILED, "mmap")) > + return; > + > + memcpy(user_data_mmap, &user_data_mmap_v, sizeof(*user_data_mmap)); > + value.udata_mmap = user_data_mmap; > + value.udata = &user_data; There shouldn't be a need to do mmap(). It's too much memory overhead. The user should be able to write: static __thread struct user_data udata; value.udata = &udata; bpf_map_update_elem(map_fd, my_task_fd, &value) and do it once. Later multi thread user code will just access "udata". No map lookups. If sizeof(udata) is small enough the kernel will pin either one or two pages (if udata crosses page boundary). So no extra memory consumption by the user process while the kernel pins a page or two. In a good case it's one page and no extra vmap. I wonder whether we should enforce that one page case. It's not hard for users to write: static __thread struct user_data udata __attribute__((aligned(sizeof(udata))));