[dpdk-dev,v2,1/2] memalloc: do not leave unmapped holes in EAL virtual memory area

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

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation fail apply issues

Commit Message

Stojaczyk, DariuszX June 1, 2018, 1:39 p.m. UTC
  EAL reserves a huge area in virtual address space
to provide virtual address contiguity for e.g.
future memory extensions (memory hotplug). During
memory hotplug, if the hugepage mmap succeeds but
doesn't suffice EAL's requiriments, the EAL would
unmap this mapping straight away, leaving a hole in
its virtual memory area and making it available
to everyone. As EAL still thinks it owns the entire
region, it may try to mmap it later with MAP_FIXED,
possibly overriding a user's mapping that was made
in the meantime.

This patch ensures each hole is mapped back by EAL,
so that it won't be available to anyone else.

Changes from v1:
 * checkpatch fixes

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

Comments

Stojaczyk, DariuszX June 1, 2018, 10:24 a.m. UTC | #1
The Intel SMTP server keeps dying to me. It's really not fun trying to resend these messages for half an hour without success. I'll resend this series from my private mail in the evening.

D.

> -----Original Message-----
> From: Stojaczyk, DariuszX
> Sent: Friday, June 1, 2018 3:39 PM
> To: dev@dpdk.org; Burakov, Anatoly <anatoly.burakov@intel.com>
> Cc: Stojaczyk, DariuszX <dariuszx.stojaczyk@intel.com>
> Subject: [PATCH v2 1/2] memalloc: do not leave unmapped holes in EAL
> virtual memory area
> 
> EAL reserves a huge area in virtual address space to provide virtual address
> contiguity for e.g.
> future memory extensions (memory hotplug). During memory hotplug, if
> the hugepage mmap succeeds but doesn't suffice EAL's requiriments, the
> EAL would unmap this mapping straight away, leaving a hole in its virtual
> memory area and making it available to everyone. As EAL still thinks it owns
> the entire region, it may try to mmap it later with MAP_FIXED, possibly
> overriding a user's mapping that was made in the meantime.
> 
> This patch ensures each hole is mapped back by EAL, so that it won't be
> available to anyone else.
> 
> Changes from v1:
>  * checkpatch fixes
> 
> Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
> ---
>  lib/librte_eal/linuxapp/eal/eal_memalloc.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/lib/librte_eal/linuxapp/eal/eal_memalloc.c
> b/lib/librte_eal/linuxapp/eal/eal_memalloc.c
> index 8c11f98..2ab3d34 100644
> --- a/lib/librte_eal/linuxapp/eal/eal_memalloc.c
> +++ b/lib/librte_eal/linuxapp/eal/eal_memalloc.c
> @@ -39,6 +39,7 @@
>  #include "eal_filesystem.h"
>  #include "eal_internal_cfg.h"
>  #include "eal_memalloc.h"
> +#include "eal_private.h"
> 
>  /*
>   * not all kernel version support fallocate on hugetlbfs, so fall back to @@ -
> 490,6 +491,8 @@ alloc_seg(struct rte_memseg *ms, void *addr, int
> socket_id,
>  	int ret = 0;
>  	int fd;
>  	size_t alloc_sz;
> +	int flags;
> +	void *new_addr;
> 
>  	/* takes out a read lock on segment or segment list */
>  	fd = get_seg_fd(path, sizeof(path), hi, list_idx, seg_idx); @@ -585,6
> +588,20 @@ alloc_seg(struct rte_memseg *ms, void *addr, int socket_id,
> 
>  mapped:
>  	munmap(addr, alloc_sz);
> +	flags = MAP_FIXED;
> +#ifdef RTE_ARCH_PPC_64
> +	flags |= MAP_HUGETLB;
> +#endif
> +	new_addr = eal_get_virtual_area(addr, &alloc_sz, alloc_sz, 0,
> flags);
> +	if (new_addr != addr) {
> +		if (new_addr != NULL)
> +			munmap(new_addr, alloc_sz);
> +		/* we're leaving a hole in our virtual address space. if
> +		 * somebody else maps this hole now, we could accidentally
> +		 * override it in the future.
> +		 */
> +		rte_panic("can't mmap holes in our virtual address space");
> +	}
>  resized:
>  	if (internal_config.single_file_segments) {
>  		resize_hugefile(fd, path, list_idx, seg_idx, map_offset,
> --
> 2.7.4
  
Anatoly Burakov June 1, 2018, 11:14 a.m. UTC | #2
On 01-Jun-18 11:24 AM, Stojaczyk, DariuszX wrote:
> The Intel SMTP server keeps dying to me. It's really not fun trying to resend these messages for half an hour without success. I'll resend this series from my private mail in the evening.
> 
> D.
> 

Please fix your NTP server, your timestamps appear to be wrong (15:39 +2 
hours).
  

Patch

diff --git a/lib/librte_eal/linuxapp/eal/eal_memalloc.c b/lib/librte_eal/linuxapp/eal/eal_memalloc.c
index 8c11f98..2ab3d34 100644
--- a/lib/librte_eal/linuxapp/eal/eal_memalloc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_memalloc.c
@@ -39,6 +39,7 @@ 
 #include "eal_filesystem.h"
 #include "eal_internal_cfg.h"
 #include "eal_memalloc.h"
+#include "eal_private.h"
 
 /*
  * not all kernel version support fallocate on hugetlbfs, so fall back to
@@ -490,6 +491,8 @@  alloc_seg(struct rte_memseg *ms, void *addr, int socket_id,
 	int ret = 0;
 	int fd;
 	size_t alloc_sz;
+	int flags;
+	void *new_addr;
 
 	/* takes out a read lock on segment or segment list */
 	fd = get_seg_fd(path, sizeof(path), hi, list_idx, seg_idx);
@@ -585,6 +588,20 @@  alloc_seg(struct rte_memseg *ms, void *addr, int socket_id,
 
 mapped:
 	munmap(addr, alloc_sz);
+	flags = MAP_FIXED;
+#ifdef RTE_ARCH_PPC_64
+	flags |= MAP_HUGETLB;
+#endif
+	new_addr = eal_get_virtual_area(addr, &alloc_sz, alloc_sz, 0, flags);
+	if (new_addr != addr) {
+		if (new_addr != NULL)
+			munmap(new_addr, alloc_sz);
+		/* we're leaving a hole in our virtual address space. if
+		 * somebody else maps this hole now, we could accidentally
+		 * override it in the future.
+		 */
+		rte_panic("can't mmap holes in our virtual address space");
+	}
 resized:
 	if (internal_config.single_file_segments) {
 		resize_hugefile(fd, path, list_idx, seg_idx, map_offset,