Skip to content

Commit

Permalink
mem: fix dynamic hugepage mapping in container
Browse files Browse the repository at this point in the history
[ upstream commit 9bffc92 ]

Since its introduction in 2018, the SIGBUS handler was never registered,
and all related functions were unused.

A SIGBUS can be received by the application when accessing to hugepages
even if mmap() was successful, This happens especially when running
inside containers when there is not enough hugepages. In this case, we
need to recover. A similar scheme can be found in eal_memory.c.

Fixes: 582bed1 ("mem: support mapping hugepages at runtime")

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Acked-by: David Marchand <david.marchand@redhat.com>
  • Loading branch information
olivier-matz-6wind authored and cpaelzer committed Nov 30, 2021
1 parent 13b9c2b commit 480955d
Showing 1 changed file with 9 additions and 4 deletions.
13 changes: 9 additions & 4 deletions lib/librte_eal/linux/eal/eal_memalloc.c
Expand Up @@ -107,7 +107,7 @@ static struct rte_memseg_list local_memsegs[RTE_MAX_MEMSEG_LISTS];

static sigjmp_buf huge_jmpenv;

static void __rte_unused huge_sigbus_handler(int signo __rte_unused)
static void huge_sigbus_handler(int signo __rte_unused)
{
siglongjmp(huge_jmpenv, 1);
}
Expand All @@ -116,15 +116,15 @@ static void __rte_unused huge_sigbus_handler(int signo __rte_unused)
* non-static local variable in the stack frame calling sigsetjmp might be
* clobbered by a call to longjmp.
*/
static int __rte_unused huge_wrap_sigsetjmp(void)
static int huge_wrap_sigsetjmp(void)
{
return sigsetjmp(huge_jmpenv, 1);
}

static struct sigaction huge_action_old;
static int huge_need_recover;

static void __rte_unused
static void
huge_register_sigbus(void)
{
sigset_t mask;
Expand All @@ -139,7 +139,7 @@ huge_register_sigbus(void)
huge_need_recover = !sigaction(SIGBUS, &action, &huge_action_old);
}

static void __rte_unused
static void
huge_recover_sigbus(void)
{
if (huge_need_recover) {
Expand Down Expand Up @@ -565,6 +565,8 @@ alloc_seg(struct rte_memseg *ms, void *addr, int socket_id,
mmap_flags = MAP_SHARED | MAP_POPULATE | MAP_FIXED;
}

huge_register_sigbus();

/*
* map the segment, and populate page tables, the kernel fills
* this segment with zeros if it's a new page.
Expand Down Expand Up @@ -640,6 +642,8 @@ alloc_seg(struct rte_memseg *ms, void *addr, int socket_id,
__func__);
#endif

huge_recover_sigbus();

ms->addr = addr;
ms->hugepage_sz = alloc_sz;
ms->len = alloc_sz;
Expand All @@ -653,6 +657,7 @@ alloc_seg(struct rte_memseg *ms, void *addr, int socket_id,
mapped:
munmap(addr, alloc_sz);
unmapped:
huge_recover_sigbus();
flags = MAP_FIXED;
new_addr = eal_get_virtual_area(addr, &alloc_sz, alloc_sz, 0, flags);
if (new_addr != addr) {
Expand Down

0 comments on commit 480955d

Please sign in to comment.