Re: [PATCH v4 1/1] eal/linux: reject mountpt not parent of --huge-dir
On Sun, Jan 08, 2023 at 06:52:39PM -0700, Ashish Sadanandan wrote: > The code added for allowing --huge-dir to specify hugetlbfs > sub-directories has a bug where it incorrectly matches mounts that > contain a prefix of the specified --huge-dir. > > Consider --huge-dir=/dev/hugepages1G is passed to rte_eal_init. Given > the following hugetlbfs mounts > > $ mount | grep hugetlbfs > hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime,pagesize=2M) > hugetlbfs on /dev/hugepages1G type hugetlbfs (rw,relatime,pagesize=1024M) > hugetlbfs on /mnt/huge type hugetlbfs (rw,relatime,pagesize=2M) > > get_hugepage_dir is first called with hugepage_sz=2097152. While > iterating over all mount points, /dev/hugepages is incorrectly > determined to be a match because it's a prefix of --huge-dir. The caller > then obtains an exclusive lock on --huge-dir. > > In the next call to get_hugepage_dir, hugepage_sz=1073741824. This call > correctly determines /dev/hugepages1G is a match. The caller again > attempts to obtain an exclusive lock on --huge-dir and deadlocks because > it's already holding a lock. > > This has been corrected by ensuring any matched mount point is either an > exact match or a parent path of --huge-dir. > > Fixes: 24d5a1ce6b85 ("eal/linux: allow hugetlbfs sub-directories") > Cc: john.le...@nutanix.com > Cc: sta...@dpdk.org > Signed-off-by: Ashish Sadanandan Reviewed-by: John Levon thanks john
[dpdk-dev] [PATCH RESEND] eal: allow hugetlbfs sub-directories
get_hugepage_dir() was implemented in such a way that a --huge-dir option had to exactly match the mountpoint, but there's no reason for this restriction. Fix the implementation to allow a sub-directory within a suitable hugetlbfs mountpoint to be specified. Signed-off-by: John Levon --- lib/eal/linux/eal_hugepage_info.c | 25 +++-- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/eal/linux/eal_hugepage_info.c b/lib/eal/linux/eal_hugepage_info.c index d97792cad..d7e9918f8 100644 --- a/lib/eal/linux/eal_hugepage_info.c +++ b/lib/eal/linux/eal_hugepage_info.c @@ -226,16 +226,29 @@ get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len) default_size = get_default_hp_size(); while (fgets(buf, sizeof(buf), fd)){ + const char *dir; + if (rte_strsplit(buf, sizeof(buf), splitstr, _FIELDNAME_MAX, split_tok) != _FIELDNAME_MAX) { RTE_LOG(ERR, EAL, "Error parsing %s\n", proc_mounts); break; /* return NULL */ } - /* we have a specified --huge-dir option, only examine that dir */ - if (internal_conf->hugepage_dir != NULL && - strcmp(splitstr[MOUNTPT], internal_conf->hugepage_dir) != 0) - continue; + dir = splitstr[MOUNTPT]; + + /* +* If a --huge-dir option has been specified, only examine +* mounts that contain that directory, and make sure to return +* the directory, not the mount. +*/ + if (internal_conf->hugepage_dir != NULL) { + if (strncmp(internal_conf->hugepage_dir, + splitstr[MOUNTPT], + strlen(splitstr[MOUNTPT])) != 0) + continue; + + dir = internal_conf->hugepage_dir; + } if (strncmp(splitstr[FSTYPE], hugetlbfs_str, htlbfs_str_len) == 0){ const char *pagesz_str = strstr(splitstr[OPTIONS], pagesize_opt); @@ -243,7 +256,7 @@ get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len) /* if no explicit page size, the default page size is compared */ if (pagesz_str == NULL){ if (hugepage_sz == default_size){ - strlcpy(hugedir, splitstr[MOUNTPT], len); + strlcpy(hugedir, dir, len); retval = 0; break; } @@ -252,7 +265,7 @@ get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len) else { uint64_t pagesz = rte_str_to_size(&pagesz_str[pagesize_opt_len]); if (pagesz == hugepage_sz) { - strlcpy(hugedir, splitstr[MOUNTPT], len); + strlcpy(hugedir, dir, len); retval = 0; break; } -- 2.25.1
Re: [dpdk-dev] [PATCH RESEND] eal: allow hugetlbfs sub-directories
On Wed, Jul 07, 2021 at 11:06:05PM +0300, Dmitry Kozlyuk wrote: > > get_hugepage_dir() was implemented in such a way that a --huge-dir option > > had to exactly match the mountpoint, but there's no reason for this > > restriction. Fix the implementation to allow a sub-directory within a > > suitable hugetlbfs mountpoint to be specified. > > > > Signed-off-by: John Levon > > --- > > lib/eal/linux/eal_hugepage_info.c | 25 +++-- > > 1 file changed, 19 insertions(+), 6 deletions(-) > > > > diff --git a/lib/eal/linux/eal_hugepage_info.c > > b/lib/eal/linux/eal_hugepage_info.c > > index d97792cad..d7e9918f8 100644 > > --- a/lib/eal/linux/eal_hugepage_info.c > > +++ b/lib/eal/linux/eal_hugepage_info.c > > @@ -226,16 +226,29 @@ get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, > > int len) > > default_size = get_default_hp_size(); > > > > while (fgets(buf, sizeof(buf), fd)){ > > + const char *dir; > > + > > if (rte_strsplit(buf, sizeof(buf), splitstr, _FIELDNAME_MAX, > > split_tok) != _FIELDNAME_MAX) { > > RTE_LOG(ERR, EAL, "Error parsing %s\n", proc_mounts); > > break; /* return NULL */ > > } > > > > - /* we have a specified --huge-dir option, only examine that dir > > */ > > - if (internal_conf->hugepage_dir != NULL && > > - strcmp(splitstr[MOUNTPT], > > internal_conf->hugepage_dir) != 0) > > - continue; > > + dir = splitstr[MOUNTPT]; > > + > > + /* > > +* If a --huge-dir option has been specified, only examine > > +* mounts that contain that directory, and make sure to return > > +* the directory, not the mount. > > +*/ > > + if (internal_conf->hugepage_dir != NULL) { > > + if (strncmp(internal_conf->hugepage_dir, > > + splitstr[MOUNTPT], > > + strlen(splitstr[MOUNTPT])) != 0) > > + continue; > > + > > + dir = internal_conf->hugepage_dir; > > + } > > Suppose there are /mnt/huge and /mnt/huge-2M mounted with -o pagesize=2M. > If --huge-dir=/mnt/huge-2M is specified, this code will select /mnt/huge. Yeah, good spot. I'll change it to prefer closer matches or something. > The code would be shorter with `splitstr[MOUNTPT]` -> `dir`. Sure. regards john
[dpdk-dev] [PATCH] eal/linux: allow hugetlbfs sub-directories
get_hugepage_dir() was implemented in such a way that a --huge-dir option had to exactly match the mountpoint, but there's no reason for this restriction: DPDK might not be the only user of hugepages, and shouldn't assume it owns an entire mountpoint. For example, if I have /dev/hugepages/myapp, and /dev/hugepages/dpdk, I should be able to specify: --huge-dir=/dev/hugepages/dpdk/ and have DPDK only use that sub-directory. Fix the implementation to allow a sub-directory within a suitable hugetlbfs mountpoint to be specified, preferring the closest match. Signed-off-by: John Levon Acked-by: Dmitry Kozlyuk --- v2: prefer closer matches v3: checkpatch fixes v4: fix docs, added tests v5: added release note app/test/test_eal_flags.c | 116 -- doc/guides/linux_gsg/linux_eal_parameters.rst | 3 +- doc/guides/rel_notes/release_21_11.rst| 6 +- lib/eal/linux/eal_hugepage_info.c | 83 + 4 files changed, 143 insertions(+), 65 deletions(-) diff --git a/app/test/test_eal_flags.c b/app/test/test_eal_flags.c index b4880ee802..1d18a0ba8f 100644 --- a/app/test/test_eal_flags.c +++ b/app/test/test_eal_flags.c @@ -14,8 +14,9 @@ #include #include #include -#include #include +#include +#include #include #include @@ -800,6 +801,9 @@ static int test_misc_flags(void) { char hugepath[PATH_MAX] = {0}; + char hugepath_dir[PATH_MAX] = {0}; + char hugepath_dir2[PATH_MAX] = {0}; + char hugepath_dir3[PATH_MAX] = {0}; #ifdef RTE_EXEC_ENV_FREEBSD /* BSD target doesn't support prefixes at this point */ const char * prefix = ""; @@ -810,6 +814,7 @@ test_misc_flags(void) FILE * hugedir_handle = NULL; char line[PATH_MAX] = {0}; unsigned i, isempty = 1; + if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { printf("Error - unable to get current prefix!\n"); return -1; @@ -849,6 +854,20 @@ test_misc_flags(void) } #endif + snprintf(hugepath_dir, sizeof(hugepath_dir), "%s/dpdk.missing", hugepath); + snprintf(hugepath_dir2, sizeof(hugepath_dir2), "%s/dpdk.dir", hugepath); + + if (mkdir(hugepath_dir2, 0700) != 0 && errno != EEXIST) { + printf("Error - failed to mkdir(%s)\n", hugepath_dir2); + return -1; + } + + snprintf(hugepath_dir3, sizeof(hugepath_dir3), "%s/dpdk.dir/sub", hugepath); + + if (mkdir(hugepath_dir3, 0700) != 0 && errno != EEXIST) { + printf("Error - failed to mkdir(%s)\n", hugepath_dir3); + goto fail; + } /* check that some general flags don't prevent things from working. * All cases, apart from the first, app should run. @@ -881,60 +900,66 @@ test_misc_flags(void) /* With invalid --huge-dir */ const char *argv9[] = {prgname, "-m", DEFAULT_MEM_SIZE, "--file-prefix=hugedir", "--huge-dir", "invalid"}; + /* With invalid --huge-dir sub-directory */ + const char *argv10[] = {prgname, "-m", DEFAULT_MEM_SIZE, + "--file-prefix=hugedir", "--huge-dir", hugepath_dir}; + /* With valid --huge-dir sub-directory */ + const char *argv11[] = {prgname, "-m", DEFAULT_MEM_SIZE, + "--file-prefix=hugedir", "--huge-dir", hugepath_dir2}; /* Secondary process with invalid --huge-dir (should run as flag has no * effect on secondary processes) */ - const char *argv10[] = {prgname, prefix, mp_flag, + const char *argv12[] = {prgname, prefix, mp_flag, "--huge-dir", "invalid"}; /* try running with base-virtaddr param */ - const char *argv11[] = {prgname, "--file-prefix=virtaddr", + const char *argv13[] = {prgname, "--file-prefix=virtaddr", "--base-virtaddr=0x12345678"}; /* try running with --vfio-intr INTx flag */ - const char *argv12[] = {prgname, "--file-prefix=intr", + const char *argv14[] = {prgname, "--file-prefix=intr", "--vfio-intr=legacy"}; /* try running with --vfio-intr MSI flag */ - const char *argv13[] = {prgname, "--file-prefix=intr", + const char *argv15[] = {prgname, "--file-prefix=intr", "--vfio-intr=msi"}; /* try running with --vfio-intr MSI-X flag */ - const char *argv14[] = {prgname, "--file-prefix=intr", + const char *argv16[] = {prgname, "--file-prefix=intr", "--vfio-intr=msix"}; /* try running with --vfio-intr invalid f
Re: [dpdk-dev] [PATCH] eal/linux: allow hugetlbfs sub-directories
On Tue, Oct 12, 2021 at 09:03:09PM +0200, David Marchand wrote: > > diff --git a/doc/guides/rel_notes/release_21_11.rst > > b/doc/guides/rel_notes/release_21_11.rst > > index 54718ff367..9fe689356b 100644 > > --- a/doc/guides/rel_notes/release_21_11.rst > > +++ b/doc/guides/rel_notes/release_21_11.rst > > @@ -154,7 +159,6 @@ New Features > >* Added tests to verify tunnel header verification in IPsec inbound. > >* Added tests to verify inner checksum. > > > > - > > Restored this empty line: sections in doc are separated with two empty lines. Apologies, and thanks for fixing. regards john
Re: [dpdk-dev] [PATCH v3 1/3] eal/linux: make hugetlbfs analysis reusable
On Tue, Sep 14, 2021 at 01:34:54PM +0300, Dmitry Kozlyuk wrote: > get_hugepage_dir() searched for a hugetlbfs mount with a given page size > using handcraft parsing of /proc/mounts and mixing traversal logic with > selecting the needed entry. Separate code to enumerate hugetlbfs mounts > to eal_hugepage_mount_walk() taking a callback that can inspect already > parsed entries. Use mntent(3) API for parsing. This allows to reuse > enumeration logic in subsequent patches. Hi, are you planning to implement my pending change on top of this? thanks john
Re: [dpdk-dev] [PATCH v3 1/3] eal/linux: make hugetlbfs analysis reusable
On Tue, Sep 14, 2021 at 01:34:54PM +0300, Dmitry Kozlyuk wrote: > + do { > + m = getmntent(f); Should you be using getmntent_r() etc? Nice cleanup! regards john
Re: [dpdk-dev] [PATCH v5 1/3] eal/linux: make hugetlbfs analysis reusable
On Tue, Sep 21, 2021 at 11:16:30AM +0300, dkozl...@nvidia.com wrote: > From: Dmitry Kozlyuk > > get_hugepage_dir() searched for a hugetlbfs mount with a given page size > using handcraft parsing of /proc/mounts and mixing traversal logic with > selecting the needed entry. Separate code to enumerate hugetlbfs mounts > to eal_hugepage_mount_walk() taking a callback that can inspect already > parsed entries. Use mntent(3) API for parsing. This allows to reuse > enumeration logic in subsequent patches. > > Signed-off-by: Dmitry Kozlyuk > Reviewed-by: Viacheslav Ovsiienko Reviewed-by: John Levon regards john
[dpdk-dev] [PATCH] eal: allow hugetlbfs sub-directories
v2: fix to prefer closest match
[dpdk-dev] [PATCH] eal: allow hugetlbfs sub-directories
get_hugepage_dir() was implemented in such a way that a --huge-dir option had to exactly match the mountpoint, but there's no reason for this restriction. Fix the implementation to allow a sub-directory within a suitable hugetlbfs mountpoint to be specified, preferring the closest match. Signed-off-by: John Levon --- lib/eal/linux/eal_hugepage_info.c | 74 +-- 1 file changed, 51 insertions(+), 23 deletions(-) diff --git a/lib/eal/linux/eal_hugepage_info.c b/lib/eal/linux/eal_hugepage_info.c index d97792cad..b5f08e94d 100644 --- a/lib/eal/linux/eal_hugepage_info.c +++ b/lib/eal/linux/eal_hugepage_info.c @@ -213,8 +213,8 @@ get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len) const size_t pagesize_opt_len = sizeof(pagesize_opt) - 1; const char split_tok = ' '; char *splitstr[_FIELDNAME_MAX]; + char found[PATH_MAX] = ""; char buf[BUFSIZ]; - int retval = -1; const struct internal_config *internal_conf = eal_get_internal_configuration(); @@ -226,42 +226,70 @@ get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len) default_size = get_default_hp_size(); while (fgets(buf, sizeof(buf), fd)){ + const char *pagesz_str; + if (rte_strsplit(buf, sizeof(buf), splitstr, _FIELDNAME_MAX, split_tok) != _FIELDNAME_MAX) { RTE_LOG(ERR, EAL, "Error parsing %s\n", proc_mounts); break; /* return NULL */ } - /* we have a specified --huge-dir option, only examine that dir */ - if (internal_conf->hugepage_dir != NULL && - strcmp(splitstr[MOUNTPT], internal_conf->hugepage_dir) != 0) + if (strncmp(splitstr[FSTYPE], hugetlbfs_str, htlbfs_str_len) != 0) { continue; + } - if (strncmp(splitstr[FSTYPE], hugetlbfs_str, htlbfs_str_len) == 0){ - const char *pagesz_str = strstr(splitstr[OPTIONS], pagesize_opt); + pagesz_str = strstr(splitstr[OPTIONS], pagesize_opt); - /* if no explicit page size, the default page size is compared */ - if (pagesz_str == NULL){ - if (hugepage_sz == default_size){ - strlcpy(hugedir, splitstr[MOUNTPT], len); - retval = 0; - break; - } + /* if no explicit page size, the default page size is compared */ + if (pagesz_str == NULL) { + if (hugepage_sz != default_size) { + continue; } - /* there is an explicit page size, so check it */ - else { - uint64_t pagesz = rte_str_to_size(&pagesz_str[pagesize_opt_len]); - if (pagesz == hugepage_sz) { - strlcpy(hugedir, splitstr[MOUNTPT], len); - retval = 0; - break; - } + } + /* there is an explicit page size, so check it */ + else { + uint64_t pagesz = rte_str_to_size(&pagesz_str[pagesize_opt_len]); + if (pagesz != hugepage_sz) { + continue; } - } /* end if strncmp hugetlbfs */ + } + + /* +* If no --huge-dir option has been given, we're done. +*/ + if (internal_conf->hugepage_dir == NULL) { + strlcpy(found, splitstr[MOUNTPT], len); + break; + } + + /* +* Ignore any mount that doesn't contain the --huge-dir +* directory. +*/ + if (strncmp(internal_conf->hugepage_dir, splitstr[MOUNTPT], + strlen(splitstr[MOUNTPT])) != 0) { + continue; + } + + /* +* We found a match, but only prefer it if it's a longer match +* (so /mnt/1 is preferred over /mnt for matching /mnt/1/2)). +*/ + if (strlen(splitstr[MOUNTPT]) > strlen(found)) { + strlcpy(found, splitstr[MOUNTPT], len); + } } /* end while fgets */ fclose(fd); - return retval; + + if (found[0] != '\0') { + /* If needed, return the requested dir, n
[dpdk-dev] [PATCH v3] eal: allow hugetlbfs sub-directories
get_hugepage_dir() was implemented in such a way that a --huge-dir option had to exactly match the mountpoint, but there's no reason for this restriction. Fix the implementation to allow a sub-directory within a suitable hugetlbfs mountpoint to be specified, preferring the closest match. Signed-off-by: John Levon --- v2: prefer closer matches v3: checkpatch fixes lib/eal/linux/eal_hugepage_info.c | 74 --- 1 file changed, 49 insertions(+), 25 deletions(-) diff --git a/lib/eal/linux/eal_hugepage_info.c b/lib/eal/linux/eal_hugepage_info.c index d97792cad..f78347617 100644 --- a/lib/eal/linux/eal_hugepage_info.c +++ b/lib/eal/linux/eal_hugepage_info.c @@ -213,8 +213,8 @@ get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len) const size_t pagesize_opt_len = sizeof(pagesize_opt) - 1; const char split_tok = ' '; char *splitstr[_FIELDNAME_MAX]; + char found[PATH_MAX] = ""; char buf[BUFSIZ]; - int retval = -1; const struct internal_config *internal_conf = eal_get_internal_configuration(); @@ -226,42 +226,66 @@ get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len) default_size = get_default_hp_size(); while (fgets(buf, sizeof(buf), fd)){ + const char *pagesz_str; + if (rte_strsplit(buf, sizeof(buf), splitstr, _FIELDNAME_MAX, split_tok) != _FIELDNAME_MAX) { RTE_LOG(ERR, EAL, "Error parsing %s\n", proc_mounts); break; /* return NULL */ } - /* we have a specified --huge-dir option, only examine that dir */ - if (internal_conf->hugepage_dir != NULL && - strcmp(splitstr[MOUNTPT], internal_conf->hugepage_dir) != 0) + if (strncmp(splitstr[FSTYPE], hugetlbfs_str, htlbfs_str_len) != 0) continue; - if (strncmp(splitstr[FSTYPE], hugetlbfs_str, htlbfs_str_len) == 0){ - const char *pagesz_str = strstr(splitstr[OPTIONS], pagesize_opt); + pagesz_str = strstr(splitstr[OPTIONS], pagesize_opt); - /* if no explicit page size, the default page size is compared */ - if (pagesz_str == NULL){ - if (hugepage_sz == default_size){ - strlcpy(hugedir, splitstr[MOUNTPT], len); - retval = 0; - break; - } - } - /* there is an explicit page size, so check it */ - else { - uint64_t pagesz = rte_str_to_size(&pagesz_str[pagesize_opt_len]); - if (pagesz == hugepage_sz) { - strlcpy(hugedir, splitstr[MOUNTPT], len); - retval = 0; - break; - } - } - } /* end if strncmp hugetlbfs */ + /* if no explicit page size, the default page size is compared */ + if (pagesz_str == NULL) { + if (hugepage_sz != default_size) + continue; + } + /* there is an explicit page size, so check it */ + else { + uint64_t pagesz = rte_str_to_size(&pagesz_str[pagesize_opt_len]); + if (pagesz != hugepage_sz) + continue; + } + + /* +* If no --huge-dir option has been given, we're done. +*/ + if (internal_conf->hugepage_dir == NULL) { + strlcpy(found, splitstr[MOUNTPT], len); + break; + } + + /* +* Ignore any mount that doesn't contain the --huge-dir +* directory. +*/ + if (strncmp(internal_conf->hugepage_dir, splitstr[MOUNTPT], + strlen(splitstr[MOUNTPT])) != 0) { + continue; + } + + /* +* We found a match, but only prefer it if it's a longer match +* (so /mnt/1 is preferred over /mnt for matching /mnt/1/2)). +*/ + if (strlen(splitstr[MOUNTPT]) > strlen(found)) + strlcpy(found, splitstr[MOUNTPT], len); } /* end while fgets */ fclose(fd); - return retval; + + if (found[0] != '\0') { + /* If needed, return the requested dir, n
Re: [dpdk-dev] [PATCH v3] eal: allow hugetlbfs sub-directories
On Thu, Jul 22, 2021 at 10:29:45PM +0200, David Marchand wrote: > On Thu, Jul 8, 2021 at 1:00 PM John Levon wrote: > > > > get_hugepage_dir() was implemented in such a way that a --huge-dir > > option had to exactly match the mountpoint, but there's no reason for > > this restriction. Fix the implementation to allow a sub-directory within > > a suitable hugetlbfs mountpoint to be specified, preferring the closest > > match. > > > > Signed-off-by: John Levon > > This change in EAL hugetlbfs discovery is too dangerous to be taken after > -rc1. Sure. > Could you give some usecases/examples on why this change is needed? Would you like me to expand the commit message? I had hoped it was clear enough, but I suppose not. Simply put, DPDK above is assuming its the only user of hugepages on the system - including clear_hugedir(). That is certainly not the case for our use cases. > Updating the documentation https://doc.dpdk.org/guides/linux_gsg/linux_eal_parameters.html """ --huge-dir Use specified hugetlbfs directory instead of autodetected ones. """ That is, it already says "directory", not "mount". You'd like something additional saying it can be below a mount point? > and the unit test also seem necessary. You're talking about app/test/test_eal_flags.c or something else? thanks, john
[dpdk-dev] [PATCH] app/test: flush stdout after forking
meson test was not capturing the intended output from the child process; force a flush to ensure it reaches the test log. Signed-off-by: John Levon --- app/test/process.h | 1 + 1 file changed, 1 insertion(+) diff --git a/app/test/process.h b/app/test/process.h index a09a088477..0ed91a939e 100644 --- a/app/test/process.h +++ b/app/test/process.h @@ -110,6 +110,7 @@ process_dup(const char *const argv[], int numargs, const char *env_value) for (i = 0; i < num; i++) printf("'%s' ", argv_cpy[i]); printf("\n"); + fflush(stdout); /* set the environment variable */ if (setenv(RECURSIVE_ENV_VAR, env_value, 1) != 0) -- 2.25.1
[dpdk-dev] [PATCH] app/test: quieten noise while forking
When closing file descriptors post-fork, ignore "." and ".." directory entries. Signed-off-by: John Levon --- app/test/process.h | 5 + 1 file changed, 5 insertions(+) diff --git a/app/test/process.h b/app/test/process.h index 0ed91a939e..5b10cf64df 100644 --- a/app/test/process.h +++ b/app/test/process.h @@ -90,6 +90,11 @@ process_dup(const char *const argv[], int numargs, const char *env_value) } while ((dirent = readdir(dir)) != NULL) { + + if (strcmp(dirent->d_name, ".") == 0 || + strcmp(dirent->d_name, "..") == 0) + continue; + errno = 0; fd = strtol(dirent->d_name, &endptr, 10); if (errno != 0 || endptr[0] != '\0') { -- 2.25.1
Re: [dpdk-dev] [PATCH] app/test: flush stdout after forking
On Mon, Jul 26, 2021 at 01:27:48PM +0100, Bruce Richardson wrote: > On Mon, Jul 26, 2021 at 01:16:27PM +0100, John Levon wrote: > > meson test was not capturing the intended output from the child > > process; force a flush to ensure it reaches the test log. > > > > Signed-off-by: John Levon > > --- > > app/test/process.h | 1 + > > 1 file changed, 1 insertion(+) > > > > diff --git a/app/test/process.h b/app/test/process.h > > index a09a088477..0ed91a939e 100644 > > --- a/app/test/process.h > > +++ b/app/test/process.h > > @@ -110,6 +110,7 @@ process_dup(const char *const argv[], int numargs, > > const char *env_value) > > for (i = 0; i < num; i++) > > printf("'%s' ", argv_cpy[i]); > > printf("\n"); > > + fflush(stdout); > > > I thought that "\n" normally flushes in most cases, but if explicit flush > is necessary for some cases, let's add it. stdout is only line-buffered if it's to a tty, but regardless, meson test appears to wrap all output into tmp files. I didn't dig into exactly what's going on with meson (or why the fork() matters), but certainly you don't get this output *at all* under meson test (even with -v), but you do running dpdk_test directly. Furthermore, looks like others have found the same thing as there are several other direct fflush()es. regards john
[dpdk-dev] [PATCH] app/test: quieten noise while forking
When closing file descriptors post-fork, ignore "." and ".." directory entries, so the test log doesn't have distracting errors like: Error converting name fd 0 .: Error converting name fd 0 ..: Signed-off-by: John Levon --- app/test/process.h | 5 + 1 file changed, 5 insertions(+) diff --git a/app/test/process.h b/app/test/process.h index 0ed91a939e..5b10cf64df 100644 --- a/app/test/process.h +++ b/app/test/process.h @@ -90,6 +90,11 @@ process_dup(const char *const argv[], int numargs, const char *env_value) } while ((dirent = readdir(dir)) != NULL) { + + if (strcmp(dirent->d_name, ".") == 0 || + strcmp(dirent->d_name, "..") == 0) + continue; + errno = 0; fd = strtol(dirent->d_name, &endptr, 10); if (errno != 0 || endptr[0] != '\0') { -- 2.25.1
[dpdk-dev] [PATCH] eal: allow hugetlbfs sub-directories
get_hugepage_dir() was implemented in such a way that a --huge-dir option had to exactly match the mountpoint, but there's no reason for this restriction: DPDK might not be the only user of hugepages, and shouldn't assume it owns an entire mountpoint. For example, if I have /dev/hugepages/myapp, and /dev/hugepages/dpdk, I should be able to specify: --huge-dir=/dev/hugepages/dpdk/ and have DPDK only use that sub-directory. Fix the implementation to allow a sub-directory within a suitable hugetlbfs mountpoint to be specified, preferring the closest match. Signed-off-by: John Levon --- v2: prefer closer matches v3: checkpatch fixes v4: fix docs, added tests app/test/test_eal_flags.c | 116 -- doc/guides/linux_gsg/linux_eal_parameters.rst | 3 +- lib/eal/linux/eal_hugepage_info.c | 83 + 3 files changed, 138 insertions(+), 64 deletions(-) diff --git a/app/test/test_eal_flags.c b/app/test/test_eal_flags.c index b4880ee802..1d18a0ba8f 100644 --- a/app/test/test_eal_flags.c +++ b/app/test/test_eal_flags.c @@ -14,8 +14,9 @@ #include #include #include -#include #include +#include +#include #include #include @@ -800,6 +801,9 @@ static int test_misc_flags(void) { char hugepath[PATH_MAX] = {0}; + char hugepath_dir[PATH_MAX] = {0}; + char hugepath_dir2[PATH_MAX] = {0}; + char hugepath_dir3[PATH_MAX] = {0}; #ifdef RTE_EXEC_ENV_FREEBSD /* BSD target doesn't support prefixes at this point */ const char * prefix = ""; @@ -810,6 +814,7 @@ test_misc_flags(void) FILE * hugedir_handle = NULL; char line[PATH_MAX] = {0}; unsigned i, isempty = 1; + if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { printf("Error - unable to get current prefix!\n"); return -1; @@ -849,6 +854,20 @@ test_misc_flags(void) } #endif + snprintf(hugepath_dir, sizeof(hugepath_dir), "%s/dpdk.missing", hugepath); + snprintf(hugepath_dir2, sizeof(hugepath_dir2), "%s/dpdk.dir", hugepath); + + if (mkdir(hugepath_dir2, 0700) != 0 && errno != EEXIST) { + printf("Error - failed to mkdir(%s)\n", hugepath_dir2); + return -1; + } + + snprintf(hugepath_dir3, sizeof(hugepath_dir3), "%s/dpdk.dir/sub", hugepath); + + if (mkdir(hugepath_dir3, 0700) != 0 && errno != EEXIST) { + printf("Error - failed to mkdir(%s)\n", hugepath_dir3); + goto fail; + } /* check that some general flags don't prevent things from working. * All cases, apart from the first, app should run. @@ -881,60 +900,66 @@ test_misc_flags(void) /* With invalid --huge-dir */ const char *argv9[] = {prgname, "-m", DEFAULT_MEM_SIZE, "--file-prefix=hugedir", "--huge-dir", "invalid"}; + /* With invalid --huge-dir sub-directory */ + const char *argv10[] = {prgname, "-m", DEFAULT_MEM_SIZE, + "--file-prefix=hugedir", "--huge-dir", hugepath_dir}; + /* With valid --huge-dir sub-directory */ + const char *argv11[] = {prgname, "-m", DEFAULT_MEM_SIZE, + "--file-prefix=hugedir", "--huge-dir", hugepath_dir2}; /* Secondary process with invalid --huge-dir (should run as flag has no * effect on secondary processes) */ - const char *argv10[] = {prgname, prefix, mp_flag, + const char *argv12[] = {prgname, prefix, mp_flag, "--huge-dir", "invalid"}; /* try running with base-virtaddr param */ - const char *argv11[] = {prgname, "--file-prefix=virtaddr", + const char *argv13[] = {prgname, "--file-prefix=virtaddr", "--base-virtaddr=0x12345678"}; /* try running with --vfio-intr INTx flag */ - const char *argv12[] = {prgname, "--file-prefix=intr", + const char *argv14[] = {prgname, "--file-prefix=intr", "--vfio-intr=legacy"}; /* try running with --vfio-intr MSI flag */ - const char *argv13[] = {prgname, "--file-prefix=intr", + const char *argv15[] = {prgname, "--file-prefix=intr", "--vfio-intr=msi"}; /* try running with --vfio-intr MSI-X flag */ - const char *argv14[] = {prgname, "--file-prefix=intr", + const char *argv16[] = {prgname, "--file-prefix=intr", "--vfio-intr=msix"}; /* try running with --vfio-intr invalid flag */ - const char *argv15[] = {prgname, "--file-prefix=intr", + const char *argv17[
Re: [dpdk-dev] [PATCH v5 1/3] eal/linux: make hugetlbfs analysis reusable
On Tue, Oct 05, 2021 at 07:36:21PM +0200, Thomas Monjalon wrote: > 21/09/2021 10:16, dkozl...@oss.nvidia.com: > > From: Dmitry Kozlyuk > > > > get_hugepage_dir() searched for a hugetlbfs mount with a given page size > > using handcraft parsing of /proc/mounts and mixing traversal logic with > > selecting the needed entry. Separate code to enumerate hugetlbfs mounts > > to eal_hugepage_mount_walk() taking a callback that can inspect already > > parsed entries. Use mntent(3) API for parsing. This allows to reuse > > enumeration logic in subsequent patches. > > > > Signed-off-by: Dmitry Kozlyuk > > Reviewed-by: Viacheslav Ovsiienko > > First version was sent in July. > Anatoly, please are you available to review? Any progress on these? Since now my original patch ("eal: allow hugetlbfs sub-directories") is going to have to wait behind this series, since nobody responded to review of the last version. Is it usual in DPDK to have to wait months? thanks john
Re: [dpdk-dev] [PATCH] eal: allow hugetlbfs sub-directories
On Mon, Aug 09, 2021 at 12:24:34PM +0100, John Levon wrote: > get_hugepage_dir() was implemented in such a way that a --huge-dir > option had to exactly match the mountpoint, but there's no reason for > this restriction: DPDK might not be the only user of hugepages, and > shouldn't assume it owns an entire mountpoint. For example, if I have > /dev/hugepages/myapp, and /dev/hugepages/dpdk, I should be able to > specify: > > --huge-dir=/dev/hugepages/dpdk/ > > and have DPDK only use that sub-directory. > > Fix the implementation to allow a sub-directory within a suitable > hugetlbfs mountpoint to be specified, preferring the closest match. > > Signed-off-by: John Levon > --- > v2: prefer closer matches > v3: checkpatch fixes > v4: fix docs, added tests Anyone like to (re) review? thanks john > > app/test/test_eal_flags.c | 116 -- > doc/guides/linux_gsg/linux_eal_parameters.rst | 3 +- > lib/eal/linux/eal_hugepage_info.c | 83 + > 3 files changed, 138 insertions(+), 64 deletions(-) > > diff --git a/app/test/test_eal_flags.c b/app/test/test_eal_flags.c > index b4880ee802..1d18a0ba8f 100644 > --- a/app/test/test_eal_flags.c > +++ b/app/test/test_eal_flags.c > @@ -14,8 +14,9 @@ > #include > #include > #include > -#include > #include > +#include > +#include > #include > #include > > @@ -800,6 +801,9 @@ static int > test_misc_flags(void) > { > char hugepath[PATH_MAX] = {0}; > + char hugepath_dir[PATH_MAX] = {0}; > + char hugepath_dir2[PATH_MAX] = {0}; > + char hugepath_dir3[PATH_MAX] = {0}; > #ifdef RTE_EXEC_ENV_FREEBSD > /* BSD target doesn't support prefixes at this point */ > const char * prefix = ""; > @@ -810,6 +814,7 @@ test_misc_flags(void) > FILE * hugedir_handle = NULL; > char line[PATH_MAX] = {0}; > unsigned i, isempty = 1; > + > if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { > printf("Error - unable to get current prefix!\n"); > return -1; > @@ -849,6 +854,20 @@ test_misc_flags(void) > } > #endif > > + snprintf(hugepath_dir, sizeof(hugepath_dir), "%s/dpdk.missing", > hugepath); > + snprintf(hugepath_dir2, sizeof(hugepath_dir2), "%s/dpdk.dir", hugepath); > + > + if (mkdir(hugepath_dir2, 0700) != 0 && errno != EEXIST) { > + printf("Error - failed to mkdir(%s)\n", hugepath_dir2); > + return -1; > + } > + > + snprintf(hugepath_dir3, sizeof(hugepath_dir3), "%s/dpdk.dir/sub", > hugepath); > + > + if (mkdir(hugepath_dir3, 0700) != 0 && errno != EEXIST) { > + printf("Error - failed to mkdir(%s)\n", hugepath_dir3); > + goto fail; > + } > > /* check that some general flags don't prevent things from working. >* All cases, apart from the first, app should run. > @@ -881,60 +900,66 @@ test_misc_flags(void) > /* With invalid --huge-dir */ > const char *argv9[] = {prgname, "-m", DEFAULT_MEM_SIZE, > "--file-prefix=hugedir", "--huge-dir", "invalid"}; > + /* With invalid --huge-dir sub-directory */ > + const char *argv10[] = {prgname, "-m", DEFAULT_MEM_SIZE, > + "--file-prefix=hugedir", "--huge-dir", hugepath_dir}; > + /* With valid --huge-dir sub-directory */ > + const char *argv11[] = {prgname, "-m", DEFAULT_MEM_SIZE, > + "--file-prefix=hugedir", "--huge-dir", hugepath_dir2}; > /* Secondary process with invalid --huge-dir (should run as flag has no >* effect on secondary processes) */ > - const char *argv10[] = {prgname, prefix, mp_flag, > + const char *argv12[] = {prgname, prefix, mp_flag, > "--huge-dir", "invalid"}; > > /* try running with base-virtaddr param */ > - const char *argv11[] = {prgname, "--file-prefix=virtaddr", > + const char *argv13[] = {prgname, "--file-prefix=virtaddr", > "--base-virtaddr=0x12345678"}; > > /* try running with --vfio-intr INTx flag */ > - const char *argv12[] = {prgname, "--file-prefix=intr", > + const char *argv14[] = {prgname, "--file-prefix=intr", > "--vfio-intr=legacy"}; > > /* try running with --vfio-intr MSI flag */ > - const char *argv13[] = {prgname, "--file-prefix=intr&q
Re: [PATCH v2 1/1] eal/linux: reject --huge-dir not parent of mountpt
On Tue, Jan 03, 2023 at 05:00:30PM -0700, Ashish Sadanandan wrote: > The code added for allowing --huge-dir to specify hugetlbfs > sub-directories has a bug where it incorrectly matches mounts that > contain a prefix of the specified --huge-dir. Sorry for the trouble & thanks for the fix. > + /* > + * Ignore any mount where hugepage_dir is not a parent path of > + * the mount > + */ > + else if(hugepage_dir_len > mountpt_len && > + internal_conf->hugepage_dir[mountpt_len] != '/') { > continue; > } Shouldn't this comment say "Ignore any mount that is not a parent path of hugepage_dir" ? regards john
[dpdk-dev] [PATCH] eal: allow hugetlbfs sub-directories
get_hugepage_dir() was implemented in such a way that a --huge-dir option had to exactly match the mountpoint, but there's no reason for this restriction. Fix the implementation to allow a sub-directory within a suitable hugetlbfs mountpoint to be specified. Signed-off-by: John Levon --- lib/eal/linux/eal_hugepage_info.c | 25 +++-- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/lib/eal/linux/eal_hugepage_info.c b/lib/eal/linux/eal_hugepage_info.c index d97792cad..d7e9918f8 100644 --- a/lib/eal/linux/eal_hugepage_info.c +++ b/lib/eal/linux/eal_hugepage_info.c @@ -226,16 +226,29 @@ get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len) default_size = get_default_hp_size(); while (fgets(buf, sizeof(buf), fd)){ + const char *dir; + if (rte_strsplit(buf, sizeof(buf), splitstr, _FIELDNAME_MAX, split_tok) != _FIELDNAME_MAX) { RTE_LOG(ERR, EAL, "Error parsing %s\n", proc_mounts); break; /* return NULL */ } - /* we have a specified --huge-dir option, only examine that dir */ - if (internal_conf->hugepage_dir != NULL && - strcmp(splitstr[MOUNTPT], internal_conf->hugepage_dir) != 0) - continue; + dir = splitstr[MOUNTPT]; + + /* +* If a --huge-dir option has been specified, only examine +* mounts that contain that directory, and make sure to return +* the directory, not the mount. +*/ + if (internal_conf->hugepage_dir != NULL) { + if (strncmp(internal_conf->hugepage_dir, + splitstr[MOUNTPT], + strlen(splitstr[MOUNTPT])) != 0) + continue; + + dir = internal_conf->hugepage_dir; + } if (strncmp(splitstr[FSTYPE], hugetlbfs_str, htlbfs_str_len) == 0){ const char *pagesz_str = strstr(splitstr[OPTIONS], pagesize_opt); @@ -243,7 +256,7 @@ get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len) /* if no explicit page size, the default page size is compared */ if (pagesz_str == NULL){ if (hugepage_sz == default_size){ - strlcpy(hugedir, splitstr[MOUNTPT], len); + strlcpy(hugedir, dir, len); retval = 0; break; } @@ -252,7 +265,7 @@ get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len) else { uint64_t pagesz = rte_str_to_size(&pagesz_str[pagesize_opt_len]); if (pagesz == hugepage_sz) { - strlcpy(hugedir, splitstr[MOUNTPT], len); + strlcpy(hugedir, dir, len); retval = 0; break; } -- 2.25.1