[dpdk-dev,2/2] memalloc: keep in mind a failed MAP_FIXED mmap may still perform an unmap

Message ID 1527857469-159391-2-git-send-email-dariuszx.stojaczyk@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/Intel-compilation success Compilation OK

Commit Message

Stojaczyk, DariuszX June 1, 2018, 12:51 p.m. UTC
  This isn't documented in the manuals, but a failed
mmap(..., MAP_FIXED) may still unmap overlapping
regions. In such case, we need to remap these regions
back into our address space to ensure mem contiguity.
We do it unconditionally now on mmap failure just to
be safe.

Verified on Linux 4.9.0-4-amd64. I was getting
ENOMEM when trying to map in hugetlbfs with no space
left, but the previous anonymous mapping was still
being removed.

Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
---
 lib/librte_eal/linuxapp/eal/eal_memalloc.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
  

Comments

Burakov, Anatoly June 1, 2018, 11:08 a.m. UTC | #1
On 01-Jun-18 1:51 PM, Dariusz Stojaczyk wrote:
> This isn't documented in the manuals, but a failed
> mmap(..., MAP_FIXED) may still unmap overlapping
> regions. In such case, we need to remap these regions
> back into our address space to ensure mem contiguity.
> We do it unconditionally now on mmap failure just to
> be safe.
> 
> Verified on Linux 4.9.0-4-amd64. I was getting
> ENOMEM when trying to map in hugetlbfs with no space
> left, but the previous anonymous mapping was still
> being removed.
> 
> Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
> ---

Does this also happen with other error values?
  
Stojaczyk, DariuszX June 1, 2018, 12:41 p.m. UTC | #2
> -----Original Message-----

> From: Burakov, Anatoly

> Sent: Friday, June 1, 2018 1:09 PM

> To: Stojaczyk, DariuszX <dariuszx.stojaczyk@intel.com>; dev@dpdk.org

> Subject: Re: [PATCH 2/2] memalloc: keep in mind a failed MAP_FIXED

> mmap may still perform an unmap

> 

> On 01-Jun-18 1:51 PM, Dariusz Stojaczyk wrote:

> > This isn't documented in the manuals, but a failed mmap(...,

> > MAP_FIXED) may still unmap overlapping regions. In such case, we need

> > to remap these regions back into our address space to ensure mem

> > contiguity.

> > We do it unconditionally now on mmap failure just to be safe.

> >

> > Verified on Linux 4.9.0-4-amd64. I was getting ENOMEM when trying to

> > map in hugetlbfs with no space left, but the previous anonymous

> > mapping was still being removed.

> >

> > Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com>

> > ---

> 

> Does this also happen with other error values?


The man pages aren't clear on this. It could. I know this patch only remaps the region if errrno == ENOMEM, but we could remap it unconditionally after each failed mmap just as well.  It won't hurt if we remap a region unnecessarily. This was my original intent, but apparently I didn't fully commit my changes before publishing patches here. Uhh, sorry.

D.

> 

> --

> Thanks,

> Anatoly
  

Patch

diff --git a/lib/librte_eal/linuxapp/eal/eal_memalloc.c b/lib/librte_eal/linuxapp/eal/eal_memalloc.c
index b959ea5..e59ad6e 100644
--- a/lib/librte_eal/linuxapp/eal/eal_memalloc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_memalloc.c
@@ -527,7 +527,13 @@  alloc_seg(struct rte_memseg *ms, void *addr, int socket_id,
 	if (va == MAP_FAILED) {
 		RTE_LOG(DEBUG, EAL, "%s(): mmap() failed: %s\n", __func__,
 			strerror(errno));
-		goto resized;
+		if (errno == ENOMEM) {
+			/* mmap failed, but the previous region might have
+			 * been unmapped anyway; try to remap it */
+			goto unmapped;
+		} else {
+			goto resized;
+		}
 	}
 	if (va != addr) {
 		RTE_LOG(DEBUG, EAL, "%s(): wrong mmap() address\n", __func__);
@@ -588,6 +594,7 @@  alloc_seg(struct rte_memseg *ms, void *addr, int socket_id,
 
 mapped:
 	munmap(addr, alloc_sz);
+unmapped:
 	flags = MAP_FIXED;
 #ifdef RTE_ARCH_PPC_64
 	flags |= MAP_HUGETLB;