Re: [PATCH v4 1/1] eal/linux: reject mountpt not parent of --huge-dir

2023-01-11 Thread John Levon
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

2021-06-25 Thread John Levon
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

2021-07-07 Thread John Levon
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

2021-10-12 Thread John Levon
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

2021-10-12 Thread John Levon
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

2021-09-14 Thread John Levon
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

2021-09-16 Thread John Levon
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

2021-09-22 Thread John Levon
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

2021-07-08 Thread John Levon
v2: fix to prefer closest match



[dpdk-dev] [PATCH] eal: allow hugetlbfs sub-directories

2021-07-08 Thread John Levon
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

2021-07-08 Thread John Levon
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

2021-07-22 Thread John Levon
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

2021-07-26 Thread John Levon
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

2021-07-26 Thread John Levon
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

2021-07-26 Thread John Levon
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

2021-08-01 Thread John Levon
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

2021-08-09 Thread John Levon
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

2021-10-08 Thread John Levon
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

2021-08-17 Thread John Levon
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

2023-01-04 Thread John Levon
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

2021-06-10 Thread John Levon
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