[RESEND] eal: allow hugetlbfs sub-directories

Message ID 20210625104449.2096166-1-john.levon@nutanix.com (mailing list archive)
State Superseded, archived
Delegated to: David Marchand
Headers
Series [RESEND] eal: allow hugetlbfs sub-directories |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-abi-testing success Testing PASS
ci/github-robot success github build: passed
ci/iol-testing success Testing PASS
ci/Intel-compilation success Compilation OK
ci/intel-Testing success Testing PASS

Commit Message

John Levon June 25, 2021, 10:44 a.m. UTC
  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 <john.levon@nutanix.com>
---
 lib/eal/linux/eal_hugepage_info.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)
  

Comments

David Marchand July 6, 2021, 9:43 a.m. UTC | #1
Hello Anatoly,

On Fri, Jun 25, 2021 at 12:46 PM John Levon <john.levon@nutanix.com> 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.

Review please.


>
> Signed-off-by: John Levon <john.levon@nutanix.com>
  
Dmitry Kozlyuk July 7, 2021, 8:06 p.m. UTC | #2
2021-06-25 11:44 (UTC+0100), 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 <john.levon@nutanix.com>
> ---
>  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.
The code would be shorter with `splitstr[MOUNTPT]` -> `dir`.
  
John Levon July 7, 2021, 9:58 p.m. UTC | #3
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 <john.levon@nutanix.com>
> > ---
> >  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
  
John Levon July 8, 2021, 9:36 a.m. UTC | #4
v2: fix to prefer closest match
  

Patch

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;
 				}