Allow using virtio without hugepages
cover Allow using virtio without hugepages
It is already possible to use both DPDK in general and virtio specifically, without hugetlbfs mounts, but currently virtio cannot be used without hugepage memory (i.e. with a --no-huge EAL switch) due to the fact that it needs to share memory with the backend.
This patchset uses memfd to create actual files backing anonymous memory. This enabled virtio to work not only without hugetlbfs, but without hugepages altogether, which could be useful in Cloud Native scenarios.
Anatoly Burakov (2):
memalloc: allow setting up segment list fd's
mem: use memfd for no-huge mode
lib/librte_eal/bsdapp/eal/eal_memalloc.c | 6 +++ lib/librte_eal/common/eal_memalloc.h | 4 ++ lib/librte_eal/linuxapp/eal/eal_memalloc.c | 16 ++++++++ lib/librte_eal/linuxapp/eal/eal_memory.c | 46 +++++++++++++++++++++- 4 files changed, 70 insertions(+), 2 deletions(-)
Signature · 1 line
2.17.1
PATCH 1/2 memalloc: allow setting up segment list fd's
Currently, only segment fd's for multi-file segments are supported, while for memfd-backed no-huge memory we need single-file segments mode. Add support for single-file segments in the internal API.
--- lib/librte_eal/bsdapp/eal/eal_memalloc.c | 6 ++++++ lib/librte_eal/common/eal_memalloc.h | 4 ++++ lib/librte_eal/linuxapp/eal/eal_memalloc.c | 16 ++++++++++++++++ 3 files changed, 26 insertions(+)
lib/librte_eal/bsdapp/eal/eal_memalloc.c +6 -0
@@ -61,6 +61,12 @@ eal_memalloc_set_seg_fd(int list_idx __rte_unused, int seg_idx __rte_unused,return -ENOTSUP ; } +int +eal_memalloc_set_seg_list_fd(int list_idx __rte_unused, int fd __rte_unused) +{ +return -ENOTSUP ; +} +int eal_memalloc_get_seg_fd_offset(int list_idx __rte_unused, int seg_idx __rte_unused, size_t *offset __rte_unused)
lib/librte_eal/common/eal_memalloc.h +4 -0
@@ -84,6 +84,10 @@ eal_memalloc_get_seg_fd(int list_idx, int seg_idx);int eal_memalloc_set_seg_fd (int list_idx,int seg_idx,int fd); +/* returns 0 or -errno */ +int +eal_memalloc_set_seg_list_fd (int list_idx,int fd); +int eal_memalloc_get_seg_fd_offset (int list_idx,int seg_idx,size_t *offset);
lib/librte_eal/linuxapp/eal/eal_memalloc.c +16 -0
@@ -1529,6 +1529,10 @@ eal_memalloc_set_seg_fd(int list_idx, int seg_idx, int fd) {struct rte_mem_config *mcfg =rte_eal_get_configuration ()->mem_config; +/* single file segments mode doesn't support individual segment fd's */ +if (internal_config.single_file_segments) +return -ENOTSUP ; +/* if list is not allocated, allocate it */ if (fd_list[list_idx].len ==0 ) {int len = mcfg->memsegs[list_idx].memseg_arr.len;
@@ -1541,6 +1545,18 @@ eal_memalloc_set_seg_fd(int list_idx, int seg_idx, int fd)return 0 ; } +int +eal_memalloc_set_seg_list_fd (int list_idx,int fd) +{ +/* non-single file segment mode doesn't support segment list fd's */ +if (!internal_config.single_file_segments) +return -ENOTSUP ; + + fd_list[list_idx].memseg_list_fd = fd; + +return 0 ; +} +int eal_memalloc_get_seg_fd (int list_idx,int seg_idx) {
Signature · 1 line
2.17.1
PATCH 2/2 mem: use memfd for no-huge mode
In reply to Anatoly BurakovWhen running in no-huge mode, we anonymously allocate our memory. While this works for regular NICs and vdev's, it's not suitable for memory sharing scenarios such as virtio with vhost_user backend.
To fix this, allocate no-huge memory using memfd, and register it with memalloc just like any other memseg fd. This will enable using rte_memseg_get_fd() API with --no-huge EAL flag.
--- lib/librte_eal/linuxapp/eal/eal_memory.c | 46 ++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-)
lib/librte_eal/linuxapp/eal/eal_memory.c +44 -2
@@ -25,6 +25,7 @@#include <sys/time.h> #include <signal.h> #include <setjmp.h> +#include <linux/memfd.h> #ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES #include <numa.h> #include <numaif.h>
@@ -1345,12 +1346,15 @@ eal_legacy_hugepage_init(void)/* hugetlbfs can be disabled */ if (internal_config.no_hugetlbfs) {struct rte_memseg_list *msl; +int n_segs, cur_seg, fd, memfd, flags;uint64_t page_sz; -int n_segs, cur_seg;/* nohuge mode is legacy mode */ internal_config.legacy_mem =1 ; +/* nohuge mode is single-file segments mode */ + internal_config.single_file_segments =1 ; +/* create a memseg list */ msl = &mcfg->memsegs[0 ];
@@ -1363,8 +1367,36 @@ eal_legacy_hugepage_init(void)return -1 ; } +/* set up parameters for anonymous mmap */ + fd =-1 ; + flags =MAP_PRIVATE |MAP_ANONYMOUS ; + +/* create a memfd and store it in the segment fd table */ + memfd =memfd_create ("nohuge" ,0 ); +if (memfd <0 ) { +RTE_LOG (ERR ,EAL ,"Cannot create memfd: %s\n" , +strerror (errno)); +RTE_LOG (ERR ,EAL ,"Falling back to anonymous map\n" ); + }else { +/* we got an fd - now resize it */ +if (ftruncate (memfd, internal_config.memory) <0 ) { +RTE_LOG (ERR ,EAL ,"Cannot resize memfd: %s\n" , +strerror (errno)); +RTE_LOG (ERR ,EAL ,"Falling back to anonymous map\n" ); +close (memfd); + }else { +/* creating memfd-backed file was successful. +* we want changes to memfd to be visible to +* other processes (such as vhost backend), so +* map it as shared memory. +*/ +RTE_LOG (DEBUG ,EAL ,"Using memfd for anonymous memory\n" ); + fd = memfd; + flags =MAP_SHARED ; + } + } addr =mmap (NULL , internal_config.memory,PROT_READ |PROT_WRITE , -MAP_PRIVATE |MAP_ANONYMOUS ,-1 ,0 ); + flags, fd,0 );if (addr ==MAP_FAILED ) {RTE_LOG (ERR ,EAL ,"%s: mmap() failed: %s\n" , __func__,strerror (errno));
@@ -1375,6 +1407,16 @@ eal_legacy_hugepage_init(void) msl->socket_id =0 ; msl->len = internal_config.memory; +/* we're in single-file segments mode, so only the segment list +* fd needs to be set up. +*/ +if (fd !=-1 ) { +if (eal_memalloc_set_seg_list_fd (0 , fd) <0 ) { +RTE_LOG (ERR ,EAL ,"Cannot set up segment list fd\n" ); +/* not a serious error, proceed */ + } + } +/* populate memsegs. each memseg is one page long */ for (cur_seg =0 ; cur_seg < n_segs; cur_seg++) { arr = &msl->memseg_arr;
Signature · 1 line
2.17.1
Re: [PATCH 19.02 2/2] mem: use memfd for no-huge mode
Quoted 84 lines · Anatoly Burakov
When running in no-huge mode, we anonymously allocate our memory. While this works for regular NICs and vdev's, it's not suitable for memory sharing scenarios such as virtio with
vhost_userbackend.To fix this, allocate no-huge memory using memfd, and register it with memalloc just like any other memseg fd. This will enable using
rte_memseg_get_fd()API with --no-huge EAL flag.Signed-off-by Anatoly Burakov <[email protected]>--- lib/librte_eal/linuxapp/eal/eal_memory.c | 46 ++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-)lib/librte_eal/linuxapp/eal/eal_memory.c +34
-2@@ -25,6 +25,7 @@#include <sys/time.h> #include <signal.h> #include <setjmp.h> +#include <linux/memfd.h> #ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES #include <numa.h> #include <numaif.h> @@ -1345,12 +1346,15 @@ eal_legacy_hugepage_init(void)/* hugetlbfs can be disabled */ if (internal_config.no_hugetlbfs) {struct rte_memseg_list *msl; +int n_segs, cur_seg, fd, memfd, flags;uint64_t page_sz; -int n_segs, cur_seg;/* nohuge mode is legacy mode */ internal_config.legacy_mem =1 ; +/* nohuge mode is single-file segments mode */ + internal_config.single_file_segments =1 ; +/* create a memseg list */ msl = &mcfg->memsegs[0 ];@@ -1363,8 +1367,36 @@ eal_legacy_hugepage_init(void)return -1 ; } +/* set up parameters for anonymous mmap */ + fd =-1 ; + flags =MAP_PRIVATE |MAP_ANONYMOUS ; + +/* create a memfd and store it in the segment fd table */ + memfd =memfd_create ("nohuge" ,0 ); +if (memfd <0 ) { +RTE_LOG (ERR ,EAL ,"Cannot create memfd: %s\n" , +strerror (errno)); +RTE_LOG (ERR ,EAL ,"Falling back to anonymous map\n" ); + }else { +/* we got an fd - now resize it */ +if (ftruncate (memfd, internal_config.memory) <0 ) { +RTE_LOG (ERR ,EAL ,"Cannot resize memfd: %s\n" , +strerror (errno)); +RTE_LOG (ERR ,EAL ,"Falling back to anonymous map\n" ); +close (memfd); + }else { +/* creating memfd-backed file was successful. +* we want changes to memfd to be visible to +* other processes (such as vhost backend), so +* map it as shared memory. +*/ +RTE_LOG (DEBUG ,EAL ,"Using memfd for anonymous memory\n" ); + fd = memfd; + flags =MAP_SHARED ; + } + } addr =mmap (NULL , internal_config.memory,PROT_READ |PROT_WRITE , -MAP_PRIVATE |MAP_ANONYMOUS ,-1 ,0 ); + flags, fd,0 );if (addr ==MAP_FAILED ) {RTE_LOG (ERR ,EAL ,"%s: mmap() failed: %s\n" , __func__,strerror (errno));@@ -1375,6 +1407,16 @@ eal_legacy_hugepage_init(void) msl->socket_id =0 ; msl->len = internal_config.memory;
lib/librte_eal/linuxapp/eal/eal_memory.c eal_legacy_hugepage_init(void) · line 1418
Quoted 10 lines
lib/librte_eal/linuxapp/eal/eal_memory.c +9
-0+/* we're in single-file segments mode, so only the segment list +* fd needs to be set up. +*/ +if (fd !=-1 ) { +if (eal_memalloc_set_seg_list_fd (0 , fd) <0 ) { +RTE_LOG (ERR ,EAL ,"Cannot set up segment list fd\n" ); +/* not a serious error, proceed */ + } + }
Hi Anatoly,
Thanks for the work!
It seems the support for getting fd offset is missing in no-huge mode. I got below error in virtio-user while trying this series with --no-huge:
update_memory_region(): Failed to get offset, ms=0x10002e000 rte_errno=19
Thanks
Quoted 6 lines
lib/librte_eal/linuxapp/eal/eal_memory.c +1
-0+/* populate memsegs. each memseg is one page long */ for (cur_seg =0 ; cur_seg < n_segs; cur_seg++) { arr = &msl->memseg_arr;Signature · 1 line
2.17.1
Re: [PATCH 19.02 2/2] mem: use memfd for no-huge mode
Quoted 98 lines · Tiwei Bie
Quoted 84 lines · Anatoly Burakov
When running in no-huge mode, we anonymously allocate our memory. While this works for regular NICs and vdev's, it's not suitable for memory sharing scenarios such as virtio with
vhost_userbackend.To fix this, allocate no-huge memory using memfd, and register it with memalloc just like any other memseg fd. This will enable using
rte_memseg_get_fd()API with --no-huge EAL flag.Signed-off-by Anatoly Burakov <[email protected]>--- lib/librte_eal/linuxapp/eal/eal_memory.c | 46 ++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-)lib/librte_eal/linuxapp/eal/eal_memory.c +34
-2@@ -25,6 +25,7 @@#include <sys/time.h> #include <signal.h> #include <setjmp.h> +#include <linux/memfd.h> #ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES #include <numa.h> #include <numaif.h> @@ -1345,12 +1346,15 @@ eal_legacy_hugepage_init(void)/* hugetlbfs can be disabled */ if (internal_config.no_hugetlbfs) {struct rte_memseg_list *msl; +int n_segs, cur_seg, fd, memfd, flags;uint64_t page_sz; -int n_segs, cur_seg;/* nohuge mode is legacy mode */ internal_config.legacy_mem =1 ; +/* nohuge mode is single-file segments mode */ + internal_config.single_file_segments =1 ; +/* create a memseg list */ msl = &mcfg->memsegs[0 ];@@ -1363,8 +1367,36 @@ eal_legacy_hugepage_init(void)return -1 ; } +/* set up parameters for anonymous mmap */ + fd =-1 ; + flags =MAP_PRIVATE |MAP_ANONYMOUS ; + +/* create a memfd and store it in the segment fd table */ + memfd =memfd_create ("nohuge" ,0 ); +if (memfd <0 ) { +RTE_LOG (ERR ,EAL ,"Cannot create memfd: %s\n" , +strerror (errno)); +RTE_LOG (ERR ,EAL ,"Falling back to anonymous map\n" ); + }else { +/* we got an fd - now resize it */ +if (ftruncate (memfd, internal_config.memory) <0 ) { +RTE_LOG (ERR ,EAL ,"Cannot resize memfd: %s\n" , +strerror (errno)); +RTE_LOG (ERR ,EAL ,"Falling back to anonymous map\n" ); +close (memfd); + }else { +/* creating memfd-backed file was successful. +* we want changes to memfd to be visible to +* other processes (such as vhost backend), so +* map it as shared memory. +*/ +RTE_LOG (DEBUG ,EAL ,"Using memfd for anonymous memory\n" ); + fd = memfd; + flags =MAP_SHARED ; + } + } addr =mmap (NULL , internal_config.memory,PROT_READ |PROT_WRITE , -MAP_PRIVATE |MAP_ANONYMOUS ,-1 ,0 ); + flags, fd,0 );if (addr ==MAP_FAILED ) {RTE_LOG (ERR ,EAL ,"%s: mmap() failed: %s\n" , __func__,strerror (errno));@@ -1375,6 +1407,16 @@ eal_legacy_hugepage_init(void) msl->socket_id =0 ; msl->len = internal_config.memory;lib/librte_eal/linuxapp/eal/eal_memory.c eal_legacy_hugepage_init(void) · line 1418
Quoted 10 lines
lib/librte_eal/linuxapp/eal/eal_memory.c +9
-0+/* we're in single-file segments mode, so only the segment list +* fd needs to be set up. +*/ +if (fd !=-1 ) { +if (eal_memalloc_set_seg_list_fd (0 , fd) <0 ) { +RTE_LOG (ERR ,EAL ,"Cannot set up segment list fd\n" ); +/* not a serious error, proceed */ + } + }Hi Anatoly,
Quoted 7 lines
Thanks for the work!
It seems the support for getting fd offset is missing in no-huge mode. I got below error in virtio-user while trying this series with --no-huge:
update_memory_region(): Failed to get offset, ms=0x10002e000 rte_errno=19
That's weird, it should have been working. I'll look into it, thanks!
Quoted 10 lines
Thanks
Quoted 6 lines
lib/librte_eal/linuxapp/eal/eal_memory.c +1
-0+/* populate memsegs. each memseg is one page long */ for (cur_seg =0 ; cur_seg < n_segs; cur_seg++) { arr = &msl->memseg_arr;Signature · 1 line
2.17.1
Signature · 2 lines
Thanks, Anatoly
v2 cover Allow using virtio without hugepages
In reply to Anatoly BurakovIt is already possible to use both DPDK in general and virtio specifically, without hugetlbfs mounts, but currently virtio cannot be used without hugepage memory (i.e. with a --no-huge EAL switch) due to the fact that it needs to share memory with the backend.
This patchset uses memfd to create actual files backing anonymous memory. This enabled virtio to work not only without hugetlbfs, but without hugepages altogether, which could be useful in Cloud Native scenarios.
v2:
- Fixed segment fd list not being initialized
- Added some segment fd API fixes
- Added unit test for segment fd API
Anatoly Burakov (5):
mem: fix error code for segment fd API for external segs
memalloc: check for memfd support in segment fd API
memalloc: allow setting up segment list fd's
mem: use memfd for no-huge mode
test: add segment fd API test
doc/guides/rel_notes/release_19_02.rst | 13 +++++ lib/librte_eal/bsdapp/eal/eal_memalloc.c | 6 ++ lib/librte_eal/common/eal_common_memory.c | 12 ++++ lib/librte_eal/common/eal_memalloc.h | 4 ++ lib/librte_eal/linuxapp/eal/eal_memalloc.c | 66 +++++++++++++++++++--- lib/librte_eal/linuxapp/eal/eal_memory.c | 54 +++++++++++++++++- test/test/test_memory.c | 43 ++++++++++++++ 7 files changed, 188 insertions(+), 10 deletions(-)
Signature · 1 line
2.17.1
PATCH v2 1/5 mem: fix error code for segment fd API for external segs
Segment fd API does not support getting segment fd's from externally allocated memory, so return proper error code on any attempts to do so. This changes API behavior, so document the change as well.
---
Notes:
The API is experimental, no deprecation notice needed.
doc/guides/rel_notes/release_19_02.rst | 6 ++++++ lib/librte_eal/common/eal_common_memory.c | 12 ++++++++++++ 2 files changed, 18 insertions(+)
doc/guides/rel_notes/release_19_02.rst +6 -0
@@ -84,6 +84,12 @@ API Changes ========================================================= +* eal: segment fd API on Linux now sets error code to ``ENOTSUP`` in more cases + where segment fd API is not expected to be supported: + + - On attempt to get segment fd for an externally allocated memory segment + + ABI Changes -----------
lib/librte_eal/common/eal_common_memory.c +12 -0
@@ -704,6 +704,12 @@ rte_memseg_get_fd_thread_unsafe(const struct rte_memseg *ms)return -1 ; } +/* segment fd API is not supported for external segments */ +if (msl->external) { + rte_errno =ENOTSUP ; +return -1 ; + } + ret =eal_memalloc_get_seg_fd (msl_idx, seg_idx);if (ret <0 ) { rte_errno = -ret;
@@ -754,6 +760,12 @@ rte_memseg_get_fd_offset_thread_unsafe(const struct rte_memseg *ms,return -1 ; } +/* segment fd API is not supported for external segments */ +if (msl->external) { + rte_errno =ENOTSUP ; +return -1 ; + } + ret =eal_memalloc_get_seg_fd_offset (msl_idx, seg_idx, offset);if (ret <0 ) { rte_errno = -ret;
Signature · 1 line
2.17.1
PATCH v2 2/5 memalloc: check for memfd support in segment fd API
In reply to Anatoly BurakovIf memfd support was not compiled, or hugepage memfd support is not available at runtime, the API will now return proper error code, indicating that this API is unsupported. This changes the API, so document the changes.
---
Notes:
The API is experimental, no deprecation notice needed.
doc/guides/rel_notes/release_19_02.rst | 2 ++ lib/librte_eal/linuxapp/eal/eal_memalloc.c | 40 +++++++++++++++++----- 2 files changed, 34 insertions(+), 8 deletions(-)
doc/guides/rel_notes/release_19_02.rst +2 -0
@@ -88,6 +88,8 @@ API Changes where segment fd API is not expected to be supported: - On attempt to get segment fd for an externally allocated memory segment + - In cases where memfd support would have been required to provide segment + fd's (such as in-memory or no-huge mode) ABI Changes
lib/librte_eal/linuxapp/eal/eal_memalloc.c +32 -8
@@ -23,6 +23,10 @@#include <sys/time.h> #include <signal.h> #include <setjmp.h> +#ifdef F_ADD_SEALS /* if file sealing is supported, so is memfd */ +#include <linux/memfd.h> +#define MEMFD_SUPPORTED +#endif #ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES #include <numa.h> #include <numaif.h>
@@ -53,8 +57,8 @@ const int anonymous_hugepages_supported =#endif /* -* we don't actually care if memfd itself is supported - we only need to check -* if memfd supports hugetlbfs, as that already implies memfd support. +* we've already checked memfd support at compile-time, but we also need to +* check if we can create hugepage files with memfd. * * also, this is not a constant, because while we may be *compiled* with memfd * hugetlbfs support, we might not be *running* on a system that supports memfd
@@ -63,10 +67,11 @@ const int anonymous_hugepages_supported =*/ static int memfd_create_supported =#ifdef MFD_HUGETLB -#define MEMFD_SUPPORTED 1 ; +#define RTE_MFD_HUGETLB MFD_HUGETLB#else 0 ; +#define RTE_MFD_HUGETLB 4U#endif /*
@@ -338,12 +343,12 @@ get_seg_memfd(struct hugepage_info *hi __rte_unused,int fd;char segname[250 ];/* as per manpage, limit is 249 bytes plus null */ +int flags =RTE_MFD_HUGETLB |pagesz_flags (hi->hugepage_sz); +if (internal_config.single_file_segments) { fd = fd_list[list_idx].memseg_list_fd;if (fd <0 ) { -int flags =MFD_HUGETLB |pagesz_flags (hi->hugepage_sz); -snprintf (segname,sizeof (segname),"seg_%i" , list_idx); fd =memfd_create (segname, flags);if (fd <0 ) {
@@ -357,8 +362,6 @@ get_seg_memfd(struct hugepage_info *hi __rte_unused, fd = fd_list[list_idx].fds[seg_idx];if (fd <0 ) { -int flags =MFD_HUGETLB |pagesz_flags (hi->hugepage_sz); -snprintf (segname,sizeof (segname),"seg_%i-%i" , list_idx, seg_idx); fd =memfd_create (segname, flags);
@@ -1542,6 +1545,17 @@ int eal_memalloc_get_seg_fd(int list_idx, int seg_idx) { int fd; + +if (internal_config.in_memory || internal_config.no_hugetlbfs) { +#ifndef MEMFD_SUPPORTED +/* in in-memory or no-huge mode, we rely on memfd support */ +return -ENOTSUP ; +#endif +/* memfd supported, but hugetlbfs memfd may not be */ +if (!internal_config.no_hugetlbfs && !memfd_create_supported) +return -ENOTSUP ; + } +if (internal_config.single_file_segments) { fd = fd_list[list_idx].memseg_list_fd; }else if (fd_list[list_idx].len ==0 ) {
@@ -1565,7 +1579,7 @@ test_memfd_create(void)int pagesz_flag =pagesz_flags (pagesz);int flags; - flags = pagesz_flag |MFD_HUGETLB ; + flags = pagesz_flag |RTE_MFD_HUGETLB ;int fd =memfd_create ("test" , flags);if (fd <0 ) {/* we failed - let memalloc know this isn't working */
@@ -1589,6 +1603,16 @@ eal_memalloc_get_seg_fd_offset(int list_idx, int seg_idx, size_t *offset) {struct rte_mem_config *mcfg =rte_eal_get_configuration ()->mem_config; +if (internal_config.in_memory || internal_config.no_hugetlbfs) { +#ifndef MEMFD_SUPPORTED +/* in in-memory or no-huge mode, we rely on memfd support */ +return -ENOTSUP ; +#endif +/* memfd supported, but hugetlbfs memfd may not be */ +if (!internal_config.no_hugetlbfs && !memfd_create_supported) +return -ENOTSUP ; + } +/* fd_list not initialized? */ if (fd_list[list_idx].len ==0 )return -ENODEV ;
Signature · 1 line
2.17.1
PATCH v2 3/5 memalloc: allow setting up segment list fd's
In reply to Anatoly BurakovCurrently, only segment fd's for multi-file segments are supported, while for memfd-backed no-huge memory we need single-file segments mode. Add support for single-file segments in the internal API.
---
Notes:
v2:
- Add missing fd list allocation on setting segment list fd
lib/librte_eal/bsdapp/eal/eal_memalloc.c | 6 +++++ lib/librte_eal/common/eal_memalloc.h | 4 ++++ lib/librte_eal/linuxapp/eal/eal_memalloc.c | 26 ++++++++++++++++++++++ 3 files changed, 36 insertions(+)
lib/librte_eal/bsdapp/eal/eal_memalloc.c +6 -0
@@ -61,6 +61,12 @@ eal_memalloc_set_seg_fd(int list_idx __rte_unused, int seg_idx __rte_unused,return -ENOTSUP ; } +int +eal_memalloc_set_seg_list_fd(int list_idx __rte_unused, int fd __rte_unused) +{ +return -ENOTSUP ; +} +int eal_memalloc_get_seg_fd_offset(int list_idx __rte_unused, int seg_idx __rte_unused, size_t *offset __rte_unused)
lib/librte_eal/common/eal_memalloc.h +4 -0
@@ -84,6 +84,10 @@ eal_memalloc_get_seg_fd(int list_idx, int seg_idx);int eal_memalloc_set_seg_fd (int list_idx,int seg_idx,int fd); +/* returns 0 or -errno */ +int +eal_memalloc_set_seg_list_fd (int list_idx,int fd); +int eal_memalloc_get_seg_fd_offset (int list_idx,int seg_idx,size_t *offset);
lib/librte_eal/linuxapp/eal/eal_memalloc.c +26 -0
@@ -1529,6 +1529,10 @@ eal_memalloc_set_seg_fd(int list_idx, int seg_idx, int fd) {struct rte_mem_config *mcfg =rte_eal_get_configuration ()->mem_config; +/* single file segments mode doesn't support individual segment fd's */ +if (internal_config.single_file_segments) +return -ENOTSUP ; +/* if list is not allocated, allocate it */ if (fd_list[list_idx].len ==0 ) {int len = mcfg->memsegs[list_idx].memseg_arr.len;
@@ -1541,6 +1545,28 @@ eal_memalloc_set_seg_fd(int list_idx, int seg_idx, int fd)return 0 ; } +int +eal_memalloc_set_seg_list_fd (int list_idx,int fd) +{ +struct rte_mem_config *mcfg =rte_eal_get_configuration ()->mem_config; + +/* non-single file segment mode doesn't support segment list fd's */ +if (!internal_config.single_file_segments) +return -ENOTSUP ; + +/* if list is not allocated, allocate it */ +if (fd_list[list_idx].len ==0 ) { +int len = mcfg->memsegs[list_idx].memseg_arr.len; + +if (alloc_list (list_idx, len) <0 ) +return -ENOMEM ; + } + + fd_list[list_idx].memseg_list_fd = fd; + +return 0 ; +} +int eal_memalloc_get_seg_fd (int list_idx,int seg_idx) {
Signature · 1 line
2.17.1
PATCH v2 4/5 mem: use memfd for no-huge mode
In reply to Anatoly BurakovWhen running in no-huge mode, we anonymously allocate our memory. While this works for regular NICs and vdev's, it's not suitable for memory sharing scenarios such as virtio with vhost_user backend.
To fix this, allocate no-huge memory using memfd, and register it with memalloc just like any other memseg fd. This will enable using rte_memseg_get_fd() API with --no-huge EAL flag.
---
Notes:
v2:
- Detect memfd support at compile time
- Change memfd-related log level to debug
doc/guides/rel_notes/release_19_02.rst | 5 +++ lib/librte_eal/linuxapp/eal/eal_memory.c | 54 +++++++++++++++++++++++- 2 files changed, 57 insertions(+), 2 deletions(-)
doc/guides/rel_notes/release_19_02.rst +5 -0
@@ -23,6 +23,11 @@ DPDK Release 19.02 New Features ------------ +* **Support for using VirtIO without hugepages** + + The --no-huge mode was augmented to use memfd-backed memory (on systems that + support memfd), to allow using VirtIO-based NICs without hugepages. + .. This section should contain new features added in this release. Sample format:
lib/librte_eal/linuxapp/eal/eal_memory.c +52 -2
84 lines not on this page · raw message
Signature · 1 line
2.17.1
Re: [PATCH v2 4/5] mem: use memfd for no-huge mode
Quoted 26 lines · Anatoly Burakov
When running in no-huge mode, we anonymously allocate our memory. While this works for regular NICs and vdev's, it's not suitable for memory sharing scenarios such as virtio with
vhost_userbackend.To fix this, allocate no-huge memory using memfd, and register it with memalloc just like any other memseg fd. This will enable using
rte_memseg_get_fd()API with --no-huge EAL flag.Signed-off-by Anatoly Burakov <[email protected]>---
Notes:
v2:
- Detect memfd support at compile time
- Change memfd-related log level to debugdoc/guides/rel_notes/release_19_02.rst | 5 +++ lib/librte_eal/linuxapp/eal/eal_memory.c | 54 +++++++++++++++++++++++- 2 files changed, 57 insertions(+), 2 deletions(-)doc/guides/rel_notes/release_19_02.rst +0
-0
doc/guides/rel_notes/release_19_02.rst DPDK Release 19.02 · line 29
Quoted 7 lines
doc/guides/rel_notes/release_19_02.rst +4
-0@@ -23,6 +23,11 @@ DPDK Release 19.02 New Features ------------ +* **Support for using VirtIO without hugepages** + + The --no-huge mode was augmented to use memfd-backed memory (on systems that + support memfd), to allow using VirtIO-based NICs without hugepages.
It would be better to say virtio-user here, because virtio NICs e.g. the one emulated by QEMU, could be something quite different.
Quoted 4 lines
doc/guides/rel_notes/release_19_02.rst +1
-0+ .. This section should contain new features added in this release. Sample format:
[...]
Re: [PATCH v2 4/5] mem: use memfd for no-huge mode
Quoted 30 lines · Tiwei Bie
Quoted 29 lines · Anatoly Burakov
When running in no-huge mode, we anonymously allocate our memory. While this works for regular NICs and vdev's, it's not suitable for memory sharing scenarios such as virtio with
vhost_userbackend.To fix this, allocate no-huge memory using memfd, and register it with memalloc just like any other memseg fd. This will enable using
rte_memseg_get_fd()API with --no-huge EAL flag.Signed-off-by Anatoly Burakov <[email protected]>---
Notes:
v2:
- Detect memfd support at compile time
- Change memfd-related log level to debugdoc/guides/rel_notes/release_19_02.rst | 5 +++ lib/librte_eal/linuxapp/eal/eal_memory.c | 54 +++++++++++++++++++++++- 2 files changed, 57 insertions(+), 2 deletions(-)doc/guides/rel_notes/release_19_02.rst +0
-0@@ -23,6 +23,11 @@ DPDK Release 19.02 New Features ------------
Quoted 7 lines
doc/guides/rel_notes/release_19_02.rst DPDK Release 19.02 · line 29
Quoted 4 lines
doc/guides/rel_notes/release_19_02.rst +4
-0+* **Support for using VirtIO without hugepages** + + The --no-huge mode was augmented to use memfd-backed memory (on systems that + support memfd), to allow using VirtIO-based NICs without hugepages.It would be better to say virtio-user here, because virtio NICs e.g. the one emulated by QEMU, could be something quite different.
Thanks, will fix!
Quoted 7 lines
Quoted 5 lines
doc/guides/rel_notes/release_19_02.rst +1
-0+ .. This section should contain new features added in this release. Sample format:[...]
Signature · 2 lines
Thanks, Anatoly
PATCH v2 5/5 test: add segment fd API test
In reply to Anatoly BurakovUse memory autotest to also test segment fd API. This will not do any checks - just see if the relevant API's return success or indicate that the API is not supported.
--- test/test/test_memory.c | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+)
test/test/test_memory.c +43 -0
@@ -37,10 +37,44 @@ check_mem(const struct rte_memseg_list *msl __rte_unused,return 0 ; } +static int +check_seg_fds (const struct rte_memseg_list *msl,const struct rte_memseg *ms, + void *arg __rte_unused) +{ +size_t offset; +int ret; + +/* skip external segments */ +if (msl->external) +return 0 ; + +/* try segment fd first. we're in a callback, so thread-unsafe */ + ret =rte_memseg_get_fd_thread_unsafe (ms); +if (ret <0 ) { +/* ENOTSUP means segment is valid, but there is not support for +* segment fd API (e.g. on FreeBSD). +*/ +if (errno ==ENOTSUP ) +return 1 ; +/* all other errors are treated as failures */ +return -1 ; + } + +/* we're able to get memseg fd - try getting its offset */ + ret =rte_memseg_get_fd_offset_thread_unsafe (ms, &offset); +if (ret <0 ) { +if (errno ==ENOTSUP ) +return 1 ; +return -1 ; + } +return 0 ; +} +static int test_memory (void ) {uint64_t s; +int ret;/* * dump the mapped memory: the python-expect script checks
@@ -59,6 +93,15 @@ test_memory(void)/* try to read memory (should not segfault) */ rte_memseg_walk (check_mem,NULL ); +/* check segment fd support */ + ret =rte_memseg_walk (check_seg_fds,NULL ); +if (ret ==1 ) { +printf ("Segment fd API is unsupported\n" ); + }else if (ret ==-1 ) { +printf ("Error getting segment fd's\n" ); +return -1 ; + } +return 0 ; }
Signature · 1 line
2.17.1
Quoted 10 lines · Anatoly Burakov
It is already possible to use both DPDK in general and virtio specifically, without hugetlbfs mounts, but currently virtio cannot be used without hugepage memory (i.e. with a --no-huge EAL switch) due to the fact that it needs to share memory with the backend.
This patchset uses memfd to create actual files backing anonymous memory. This enabled virtio to work not only without hugetlbfs, but without hugepages altogether, which could be useful in Cloud Native scenarios.
Nice work!
Quoted 24 lines
v2:
- Fixed segment fd list not being initialized
- Added some segment fd API fixes
- Added unit test for segment fd APIAnatoly Burakov (5):
mem: fix error code for segment fd API for external segs
memalloc: check for memfd support in segment fd API
memalloc: allow setting up segment list fd's
mem: use memfd for no-huge mode
test: add segment fd API testdoc/guides/rel_notes/release_19_02.rst | 13 +++++ lib/librte_eal/bsdapp/eal/eal_memalloc.c | 6 ++ lib/librte_eal/common/eal_common_memory.c | 12 ++++ lib/librte_eal/common/eal_memalloc.h | 4 ++ lib/librte_eal/linuxapp/eal/eal_memalloc.c | 66 +++++++++++++++++++--- lib/librte_eal/linuxapp/eal/eal_memory.c | 54 +++++++++++++++++- test/test/test_memory.c | 43 ++++++++++++++ 7 files changed, 188 insertions(+), 10 deletions(-)Signature · 1 line
2.17.1
v3 cover Allow using virtio-user without hugepages
In reply to Anatoly BurakovIt is already possible to use both DPDK in general and virtio-user specifically, without hugetlbfs mounts, but currently virtio-user cannot be used without hugepage memory (i.e. with a --no-huge EAL switch) due to the fact that it needs to share memory with the backend.
This patchset uses memfd to create actual files backing anonymous memory. This enabled virtio-user to work not only without hugetlbfs (which was already possible), but without hugepages altogether, which could be useful in Cloud Native scenarios.
v3:
- Clarify doc changes
v2:
- Fixed segment fd list not being initialized
- Added some segment fd API fixes
- Added unit test for segment fd API
Anatoly Burakov (5):
mem: fix error code for segment fd API for external segs
memalloc: check for memfd support in segment fd API
memalloc: allow setting up segment list fd's
mem: use memfd for no-huge mode
test: add segment fd API test
doc/guides/rel_notes/release_19_02.rst | 13 +++++ lib/librte_eal/bsdapp/eal/eal_memalloc.c | 6 ++ lib/librte_eal/common/eal_common_memory.c | 12 ++++ lib/librte_eal/common/eal_memalloc.h | 4 ++ lib/librte_eal/linuxapp/eal/eal_memalloc.c | 66 +++++++++++++++++++--- lib/librte_eal/linuxapp/eal/eal_memory.c | 54 +++++++++++++++++- test/test/test_memory.c | 43 ++++++++++++++ 7 files changed, 188 insertions(+), 10 deletions(-)
Signature · 1 line
2.17.1
PATCH v3 1/5 mem: fix error code for segment fd API for external segs
Segment fd API does not support getting segment fd's from externally allocated memory, so return proper error code on any attempts to do so. This changes API behavior, so document the change as well.
---
Notes:
The API is experimental, no deprecation notice needed.
doc/guides/rel_notes/release_19_02.rst | 6 ++++++ lib/librte_eal/common/eal_common_memory.c | 12 ++++++++++++ 2 files changed, 18 insertions(+)
doc/guides/rel_notes/release_19_02.rst +6 -0
@@ -84,6 +84,12 @@ API Changes ========================================================= +* eal: segment fd API on Linux now sets error code to ``ENOTSUP`` in more cases + where segment fd API is not expected to be supported: + + - On attempt to get segment fd for an externally allocated memory segment + + ABI Changes -----------
lib/librte_eal/common/eal_common_memory.c +12 -0
@@ -704,6 +704,12 @@ rte_memseg_get_fd_thread_unsafe(const struct rte_memseg *ms)return -1 ; } +/* segment fd API is not supported for external segments */ +if (msl->external) { + rte_errno =ENOTSUP ; +return -1 ; + } + ret =eal_memalloc_get_seg_fd (msl_idx, seg_idx);if (ret <0 ) { rte_errno = -ret;
@@ -754,6 +760,12 @@ rte_memseg_get_fd_offset_thread_unsafe(const struct rte_memseg *ms,return -1 ; } +/* segment fd API is not supported for external segments */ +if (msl->external) { + rte_errno =ENOTSUP ; +return -1 ; + } + ret =eal_memalloc_get_seg_fd_offset (msl_idx, seg_idx, offset);if (ret <0 ) { rte_errno = -ret;
Signature · 1 line
2.17.1
Re: [PATCH v3 1/5] mem: fix error code for segment fd API for external segs
Quoted 10 lines · Anatoly Burakov
Segment fd API does not support getting segment fd's from externally allocated memory, so return proper error code on any attempts to do so. This changes API behavior, so document the change as well.
Fixes 5282bb1c3695 ("mem: allow memseg lists to be marked as external")Signed-off-by Anatoly Burakov <[email protected]>Acked-by Tiwei Bie <[email protected]>
Quoted 9 lines
---
Notes:
The API is experimental, no deprecation notice needed.doc/guides/rel_notes/release_19_02.rst | 6 ++++++ lib/librte_eal/common/eal_common_memory.c | 12 ++++++++++++ 2 files changed, 18 insertions(+)
Thanks,
Maxime
PATCH v3 2/5 memalloc: check for memfd support in segment fd API
In reply to Anatoly BurakovIf memfd support was not compiled, or hugepage memfd support is not available at runtime, the API will now return proper error code, indicating that this API is unsupported. This changes the API, so document the changes.
---
Notes:
The API is experimental, no deprecation notice needed.
doc/guides/rel_notes/release_19_02.rst | 2 ++ lib/librte_eal/linuxapp/eal/eal_memalloc.c | 40 +++++++++++++++++----- 2 files changed, 34 insertions(+), 8 deletions(-)
doc/guides/rel_notes/release_19_02.rst +2 -0
@@ -88,6 +88,8 @@ API Changes where segment fd API is not expected to be supported: - On attempt to get segment fd for an externally allocated memory segment + - In cases where memfd support would have been required to provide segment + fd's (such as in-memory or no-huge mode) ABI Changes
lib/librte_eal/linuxapp/eal/eal_memalloc.c +32 -8
@@ -23,6 +23,10 @@#include <sys/time.h> #include <signal.h> #include <setjmp.h> +#ifdef F_ADD_SEALS /* if file sealing is supported, so is memfd */ +#include <linux/memfd.h> +#define MEMFD_SUPPORTED +#endif #ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES #include <numa.h> #include <numaif.h>
@@ -53,8 +57,8 @@ const int anonymous_hugepages_supported =#endif /* -* we don't actually care if memfd itself is supported - we only need to check -* if memfd supports hugetlbfs, as that already implies memfd support. +* we've already checked memfd support at compile-time, but we also need to +* check if we can create hugepage files with memfd. * * also, this is not a constant, because while we may be *compiled* with memfd * hugetlbfs support, we might not be *running* on a system that supports memfd
@@ -63,10 +67,11 @@ const int anonymous_hugepages_supported =*/ static int memfd_create_supported =#ifdef MFD_HUGETLB -#define MEMFD_SUPPORTED 1 ; +#define RTE_MFD_HUGETLB MFD_HUGETLB#else 0 ; +#define RTE_MFD_HUGETLB 4U#endif /*
@@ -338,12 +343,12 @@ get_seg_memfd(struct hugepage_info *hi __rte_unused,int fd;char segname[250 ];/* as per manpage, limit is 249 bytes plus null */ +int flags =RTE_MFD_HUGETLB |pagesz_flags (hi->hugepage_sz); +if (internal_config.single_file_segments) { fd = fd_list[list_idx].memseg_list_fd;if (fd <0 ) { -int flags =MFD_HUGETLB |pagesz_flags (hi->hugepage_sz); -snprintf (segname,sizeof (segname),"seg_%i" , list_idx); fd =memfd_create (segname, flags);if (fd <0 ) {
@@ -357,8 +362,6 @@ get_seg_memfd(struct hugepage_info *hi __rte_unused, fd = fd_list[list_idx].fds[seg_idx];if (fd <0 ) { -int flags =MFD_HUGETLB |pagesz_flags (hi->hugepage_sz); -snprintf (segname,sizeof (segname),"seg_%i-%i" , list_idx, seg_idx); fd =memfd_create (segname, flags);
@@ -1542,6 +1545,17 @@ int eal_memalloc_get_seg_fd(int list_idx, int seg_idx) { int fd; + +if (internal_config.in_memory || internal_config.no_hugetlbfs) { +#ifndef MEMFD_SUPPORTED +/* in in-memory or no-huge mode, we rely on memfd support */ +return -ENOTSUP ; +#endif +/* memfd supported, but hugetlbfs memfd may not be */ +if (!internal_config.no_hugetlbfs && !memfd_create_supported) +return -ENOTSUP ; + } +if (internal_config.single_file_segments) { fd = fd_list[list_idx].memseg_list_fd; }else if (fd_list[list_idx].len ==0 ) {
@@ -1565,7 +1579,7 @@ test_memfd_create(void)int pagesz_flag =pagesz_flags (pagesz);int flags; - flags = pagesz_flag |MFD_HUGETLB ; + flags = pagesz_flag |RTE_MFD_HUGETLB ;int fd =memfd_create ("test" , flags);if (fd <0 ) {/* we failed - let memalloc know this isn't working */
@@ -1589,6 +1603,16 @@ eal_memalloc_get_seg_fd_offset(int list_idx, int seg_idx, size_t *offset) {struct rte_mem_config *mcfg =rte_eal_get_configuration ()->mem_config; +if (internal_config.in_memory || internal_config.no_hugetlbfs) { +#ifndef MEMFD_SUPPORTED +/* in in-memory or no-huge mode, we rely on memfd support */ +return -ENOTSUP ; +#endif +/* memfd supported, but hugetlbfs memfd may not be */ +if (!internal_config.no_hugetlbfs && !memfd_create_supported) +return -ENOTSUP ; + } +/* fd_list not initialized? */ if (fd_list[list_idx].len ==0 )return -ENODEV ;
Signature · 1 line
2.17.1
Re: [PATCH v3 2/5] memalloc: check for memfd support in segment fd API
Quoted 11 lines · Anatoly Burakov
If memfd support was not compiled, or hugepage memfd support is not available at runtime, the API will now return proper error code, indicating that this API is unsupported. This changes the API, so document the changes.
Fixes 41dbdb68723b ("mem: add external API to retrieve page fd")Fixes 3a44687139eb ("mem: allow querying offset into segment fd")Signed-off-by Anatoly Burakov <[email protected]>Acked-by Tiwei Bie <[email protected]>
Quoted 9 lines
---
Notes:
The API is experimental, no deprecation notice needed.doc/guides/rel_notes/release_19_02.rst | 2 ++ lib/librte_eal/linuxapp/eal/eal_memalloc.c | 40 +++++++++++++++++----- 2 files changed, 34 insertions(+), 8 deletions(-)
Thanks,
Maxime
PATCH v3 3/5 memalloc: allow setting up segment list fd's
In reply to Anatoly BurakovCurrently, only segment fd's for multi-file segments are supported, while for memfd-backed no-huge memory we need single-file segments mode. Add support for single-file segments in the internal API.
---
Notes:
v2:
- Add missing fd list allocation on setting segment list fd
lib/librte_eal/bsdapp/eal/eal_memalloc.c | 6 +++++ lib/librte_eal/common/eal_memalloc.h | 4 ++++ lib/librte_eal/linuxapp/eal/eal_memalloc.c | 26 ++++++++++++++++++++++ 3 files changed, 36 insertions(+)
lib/librte_eal/bsdapp/eal/eal_memalloc.c +6 -0
@@ -61,6 +61,12 @@ eal_memalloc_set_seg_fd(int list_idx __rte_unused, int seg_idx __rte_unused,return -ENOTSUP ; } +int +eal_memalloc_set_seg_list_fd(int list_idx __rte_unused, int fd __rte_unused) +{ +return -ENOTSUP ; +} +int eal_memalloc_get_seg_fd_offset(int list_idx __rte_unused, int seg_idx __rte_unused, size_t *offset __rte_unused)
lib/librte_eal/common/eal_memalloc.h +4 -0
@@ -84,6 +84,10 @@ eal_memalloc_get_seg_fd(int list_idx, int seg_idx);int eal_memalloc_set_seg_fd (int list_idx,int seg_idx,int fd); +/* returns 0 or -errno */ +int +eal_memalloc_set_seg_list_fd (int list_idx,int fd); +int eal_memalloc_get_seg_fd_offset (int list_idx,int seg_idx,size_t *offset);
lib/librte_eal/linuxapp/eal/eal_memalloc.c +26 -0
@@ -1529,6 +1529,10 @@ eal_memalloc_set_seg_fd(int list_idx, int seg_idx, int fd) {struct rte_mem_config *mcfg =rte_eal_get_configuration ()->mem_config; +/* single file segments mode doesn't support individual segment fd's */ +if (internal_config.single_file_segments) +return -ENOTSUP ; +/* if list is not allocated, allocate it */ if (fd_list[list_idx].len ==0 ) {int len = mcfg->memsegs[list_idx].memseg_arr.len;
@@ -1541,6 +1545,28 @@ eal_memalloc_set_seg_fd(int list_idx, int seg_idx, int fd)return 0 ; } +int +eal_memalloc_set_seg_list_fd (int list_idx,int fd) +{ +struct rte_mem_config *mcfg =rte_eal_get_configuration ()->mem_config; + +/* non-single file segment mode doesn't support segment list fd's */ +if (!internal_config.single_file_segments) +return -ENOTSUP ; + +/* if list is not allocated, allocate it */ +if (fd_list[list_idx].len ==0 ) { +int len = mcfg->memsegs[list_idx].memseg_arr.len; + +if (alloc_list (list_idx, len) <0 ) +return -ENOMEM ; + } + + fd_list[list_idx].memseg_list_fd = fd; + +return 0 ; +} +int eal_memalloc_get_seg_fd (int list_idx,int seg_idx) {
Signature · 1 line
2.17.1
Re: [PATCH v3 3/5] memalloc: allow setting up segment list fd's
Quoted 13 lines · Anatoly Burakov
Currently, only segment fd's for multi-file segments are supported, while for memfd-backed no-huge memory we need single-file segments mode. Add support for single-file segments in the internal API.
Signed-off-by Anatoly Burakov <[email protected]>Acked-by Tiwei Bie <[email protected]>---
Notes:
v2:
- Add missing fd list allocation on setting segment list fd
Quoted 5 lines
lib/librte_eal/bsdapp/eal/eal_memalloc.c | 6 +++++ lib/librte_eal/common/eal_memalloc.h | 4 ++++ lib/librte_eal/linuxapp/eal/eal_memalloc.c | 26 ++++++++++++++++++++++ 3 files changed, 36 insertions(+)
Thanks,
Maxime
PATCH v3 4/5 mem: use memfd for no-huge mode
In reply to Anatoly BurakovWhen running in no-huge mode, we anonymously allocate our memory. While this works for regular NICs and vdev's, it's not suitable for memory sharing scenarios such as virtio with vhost_user backend.
To fix this, allocate no-huge memory using memfd, and register it with memalloc just like any other memseg fd. This will enable using rte_memseg_get_fd() API with --no-huge EAL flag.
---
Notes:
v3:
- Clarify release notes to state that the changes apply to virtio-user NICs rather than virtio in general
v2:
- Detect memfd support at compile time
- Change memfd-related log level to debug
doc/guides/rel_notes/release_19_02.rst | 5 +++ lib/librte_eal/linuxapp/eal/eal_memory.c | 54 +++++++++++++++++++++++- 2 files changed, 57 insertions(+), 2 deletions(-)
doc/guides/rel_notes/release_19_02.rst +5 -0
@@ -23,6 +23,11 @@ DPDK Release 19.02 New Features ------------ +* **Support for using VirtIO without hugepages** + + The --no-huge mode was augmented to use memfd-backed memory (on systems that + support memfd), to allow using virtio-user-based NICs without hugepages. + .. This section should contain new features added in this release. Sample format:
lib/librte_eal/linuxapp/eal/eal_memory.c +52 -2
84 lines not on this page · raw message
Signature · 1 line
2.17.1
Re: [PATCH v3 4/5] mem: use memfd for no-huge mode
Quoted 31 lines · Anatoly Burakov
When running in no-huge mode, we anonymously allocate our memory. While this works for regular NICs and vdev's, it's not suitable for memory sharing scenarios such as virtio with
vhost_userbackend.To fix this, allocate no-huge memory using memfd, and register it with memalloc just like any other memseg fd. This will enable using
rte_memseg_get_fd()API with --no-huge EAL flag.Signed-off-by Anatoly Burakov <[email protected]>Acked-by Tiwei Bie <[email protected]>---
Notes:
v3:
- Clarify release notes to state that the changes apply to virtio-user NICs rather than virtio in generalv2:
- Detect memfd support at compile time
- Change memfd-related log level to debugdoc/guides/rel_notes/release_19_02.rst | 5 +++ lib/librte_eal/linuxapp/eal/eal_memory.c | 54 +++++++++++++++++++++++- 2 files changed, 57 insertions(+), 2 deletions(-)doc/guides/rel_notes/release_19_02.rst +0
-0
doc/guides/rel_notes/release_19_02.rst DPDK Release 19.02 · line 26
Quoted 4 lines
doc/guides/rel_notes/release_19_02.rst +1
-0@@ -23,6 +23,11 @@ DPDK Release 19.02 New Features ------------ +* **Support for using VirtIO without hugepages**
^^ oops, forgot to fix the title... Should be virtio-user.
Signature · 2 lines
Thanks, Anatoly
Re: [PATCH v3 4/5] mem: use memfd for no-huge mode
In reply to Anatoly BurakovQuoted 31 lines · Anatoly Burakov
When running in no-huge mode, we anonymously allocate our memory. While this works for regular NICs and vdev's, it's not suitable for memory sharing scenarios such as virtio with
vhost_userbackend.To fix this, allocate no-huge memory using memfd, and register it with memalloc just like any other memseg fd. This will enable using
rte_memseg_get_fd()API with --no-huge EAL flag.Signed-off-by Anatoly Burakov <[email protected]>Acked-by Tiwei Bie <[email protected]>---
Notes:
v3:
- Clarify release notes to state that the changes apply to virtio-user NICs rather than virtio in generalv2:
- Detect memfd support at compile time
- Change memfd-related log level to debugdoc/guides/rel_notes/release_19_02.rst | 5 +++ lib/librte_eal/linuxapp/eal/eal_memory.c | 54 +++++++++++++++++++++++- 2 files changed, 57 insertions(+), 2 deletions(-)doc/guides/rel_notes/release_19_02.rst +0
-0
doc/guides/rel_notes/release_19_02.rst DPDK Release 19.02 · line 27
Quoted 5 lines
doc/guides/rel_notes/release_19_02.rst +2
-0@@ -23,6 +23,11 @@ DPDK Release 19.02 New Features ------------ +* **Support for using VirtIO without hugepages** +
With the title change you suggested:
Thanks,
Maxime
PATCH v3 5/5 test: add segment fd API test
In reply to Anatoly BurakovUse memory autotest to also test segment fd API. This will not do any checks - just see if the relevant API's return success or indicate that the API is not supported.
--- test/test/test_memory.c | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+)
test/test/test_memory.c +43 -0
@@ -37,10 +37,44 @@ check_mem(const struct rte_memseg_list *msl __rte_unused,return 0 ; } +static int +check_seg_fds (const struct rte_memseg_list *msl,const struct rte_memseg *ms, + void *arg __rte_unused) +{ +size_t offset; +int ret; + +/* skip external segments */ +if (msl->external) +return 0 ; + +/* try segment fd first. we're in a callback, so thread-unsafe */ + ret =rte_memseg_get_fd_thread_unsafe (ms); +if (ret <0 ) { +/* ENOTSUP means segment is valid, but there is not support for +* segment fd API (e.g. on FreeBSD). +*/ +if (errno ==ENOTSUP ) +return 1 ; +/* all other errors are treated as failures */ +return -1 ; + } + +/* we're able to get memseg fd - try getting its offset */ + ret =rte_memseg_get_fd_offset_thread_unsafe (ms, &offset); +if (ret <0 ) { +if (errno ==ENOTSUP ) +return 1 ; +return -1 ; + } +return 0 ; +} +static int test_memory (void ) {uint64_t s; +int ret;/* * dump the mapped memory: the python-expect script checks
@@ -59,6 +93,15 @@ test_memory(void)/* try to read memory (should not segfault) */ rte_memseg_walk (check_mem,NULL ); +/* check segment fd support */ + ret =rte_memseg_walk (check_seg_fds,NULL ); +if (ret ==1 ) { +printf ("Segment fd API is unsupported\n" ); + }else if (ret ==-1 ) { +printf ("Error getting segment fd's\n" ); +return -1 ; + } +return 0 ; }
Signature · 1 line
2.17.1
Re: [PATCH v3 5/5] test: add segment fd API test
Quoted 10 lines · Anatoly Burakov
Use memory autotest to also test segment fd API. This will not do any checks - just see if the relevant API's return success or indicate that the API is not supported.
Signed-off-by Anatoly Burakov <[email protected]>Acked-by Tiwei Bie <[email protected]>--- test/test/test_memory.c | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+)
Thanks,
Maxime
Thomas Monjalon
AppliedRe: [PATCH v3 0/5] Allow using virtio-user without hugepages
In reply to Anatoly BurakovQuoted 6 lines
Anatoly Burakov (5):
mem: fix error code for segment fd API for external segs
memalloc: check for memfd support in segment fd API
memalloc: allow setting up segment list fd's
mem: use memfd for no-huge mode
test: add segment fd API test
Applied, thanks