All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] eal/linux: cleanup hugepage code
@ 2015-07-07  9:00 David Marchand
  2015-07-07  9:00 ` [PATCH 1/6] eal/linux: remove useless check on process type David Marchand
                   ` (7 more replies)
  0 siblings, 8 replies; 17+ messages in thread
From: David Marchand @ 2015-07-07  9:00 UTC (permalink / raw)
  To: dev

Here is a little patchset cleaning eal_hugepage_info.c file and fixing a bug
when having more than two hugepage sizes.
No functional change to be expected.

-- 
David Marchand

David Marchand (6):
  eal/linux: remove useless check on process type
  eal/linux: remove useless casts
  eal/linux: cosmetic change
  eal/linux: rework while loop
  eal/linux: indent file
  eal/linux: avoid out of bound access

 lib/librte_eal/linuxapp/eal/eal_hugepage_info.c |  156 ++++++++++++-----------
 1 file changed, 80 insertions(+), 76 deletions(-)

-- 
1.7.10.4

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 1/6] eal/linux: remove useless check on process type
  2015-07-07  9:00 [PATCH 0/6] eal/linux: cleanup hugepage code David Marchand
@ 2015-07-07  9:00 ` David Marchand
  2015-07-07  9:00 ` [PATCH 2/6] eal/linux: remove useless casts David Marchand
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 17+ messages in thread
From: David Marchand @ 2015-07-07  9:00 UTC (permalink / raw)
  To: dev

The code in eal_hugepage_info.c is not reachable by secondary processes.

Signed-off-by: David Marchand <david.marchand@6wind.com>
---
 lib/librte_eal/linuxapp/eal/eal_hugepage_info.c |   17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
index 028e309..6dd8a0b 100644
--- a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
+++ b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
@@ -61,31 +61,24 @@
 
 static const char sys_dir_path[] = "/sys/kernel/mm/hugepages";
 
+/* this function is only called from eal_hugepage_info_init which itself
+ * is only called from a primary process */
 static int32_t
 get_num_hugepages(const char *subdir)
 {
 	char path[PATH_MAX];
 	long unsigned resv_pages, num_pages = 0;
-	const char *nr_hp_file;
+	const char *nr_hp_file = "free_hugepages";
 	const char *nr_rsvd_file = "resv_hugepages";
 
 	/* first, check how many reserved pages kernel reports */
 	snprintf(path, sizeof(path), "%s/%s/%s",
 			sys_dir_path, subdir, nr_rsvd_file);
-
 	if (eal_parse_sysfs_value(path, &resv_pages) < 0)
 		return 0;
 
-	/* if secondary process, just look at the number of hugepages,
-	 * otherwise look at number of free hugepages */
-	if (internal_config.process_type == RTE_PROC_SECONDARY)
-		nr_hp_file = "nr_hugepages";
-	else
-		nr_hp_file = "free_hugepages";
-
 	snprintf(path, sizeof(path), "%s/%s/%s",
 			sys_dir_path, subdir, nr_hp_file);
-
 	if (eal_parse_sysfs_value(path, &num_pages) < 0)
 		return 0;
 
@@ -93,8 +86,8 @@ get_num_hugepages(const char *subdir)
 		RTE_LOG(WARNING, EAL, "No free hugepages reported in %s\n",
 				subdir);
 
-	/* adjust num_pages in case of primary process */
-	if (num_pages > 0 && internal_config.process_type == RTE_PROC_PRIMARY)
+	/* adjust num_pages */
+	if (num_pages > 0)
 		num_pages -= resv_pages;
 
 	return (int32_t)num_pages;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 2/6] eal/linux: remove useless casts
  2015-07-07  9:00 [PATCH 0/6] eal/linux: cleanup hugepage code David Marchand
  2015-07-07  9:00 ` [PATCH 1/6] eal/linux: remove useless check on process type David Marchand
@ 2015-07-07  9:00 ` David Marchand
  2015-07-09  2:04   ` Thomas Monjalon
  2015-07-07  9:00 ` [PATCH 3/6] eal/linux: cosmetic change David Marchand
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 17+ messages in thread
From: David Marchand @ 2015-07-07  9:00 UTC (permalink / raw)
  To: dev

Rather than cast the huge pages number returned by get_num_hugepages, rework
this function so that it returns 0 when something goes wrong.
And no need for casts in log.

Signed-off-by: David Marchand <david.marchand@6wind.com>
---
 lib/librte_eal/linuxapp/eal/eal_hugepage_info.c |   21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
index 6dd8a0b..0b6ece7 100644
--- a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
+++ b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
@@ -63,7 +63,7 @@ static const char sys_dir_path[] = "/sys/kernel/mm/hugepages";
 
 /* this function is only called from eal_hugepage_info_init which itself
  * is only called from a primary process */
-static int32_t
+static unsigned long
 get_num_hugepages(const char *subdir)
 {
 	char path[PATH_MAX];
@@ -87,10 +87,12 @@ get_num_hugepages(const char *subdir)
 				subdir);
 
 	/* adjust num_pages */
-	if (num_pages > 0)
+	if (num_pages >= resv_pages)
 		num_pages -= resv_pages;
+	else if (resv_pages)
+		num_pages = 0;
 
-	return (int32_t)num_pages;
+	return num_pages;
 }
 
 static uint64_t
@@ -288,12 +290,13 @@ eal_hugepage_info_init(void)
 
 			/* first, check if we have a mountpoint */
 			if (hpi->hugedir == NULL){
-				int32_t num_pages;
-				if ((num_pages = get_num_hugepages(dirent->d_name)) > 0)
-					RTE_LOG(INFO, EAL, "%u hugepages of size %llu reserved, "\
-							"but no mounted hugetlbfs found for that size\n",
-							(unsigned)num_pages,
-							(unsigned long long)hpi->hugepage_sz);
+				unsigned long num_pages;
+
+				num_pages = get_num_hugepages(dirent->d_name);
+				if (num_pages > 0)
+					RTE_LOG(INFO, EAL, "%lu hugepages of size %lu reserved, "
+						"but no mounted hugetlbfs found for that size\n",
+						num_pages, hpi->hugepage_sz);
 			} else {
 				/* try to obtain a writelock */
 				hpi->lock_descriptor = open(hpi->hugedir, O_RDONLY);
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 3/6] eal/linux: cosmetic change
  2015-07-07  9:00 [PATCH 0/6] eal/linux: cleanup hugepage code David Marchand
  2015-07-07  9:00 ` [PATCH 1/6] eal/linux: remove useless check on process type David Marchand
  2015-07-07  9:00 ` [PATCH 2/6] eal/linux: remove useless casts David Marchand
@ 2015-07-07  9:00 ` David Marchand
  2015-07-07  9:00 ` [PATCH 4/6] eal/linux: rework while loop David Marchand
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 17+ messages in thread
From: David Marchand @ 2015-07-07  9:00 UTC (permalink / raw)
  To: dev

Prepare for checkpatch compliance.

Signed-off-by: David Marchand <david.marchand@6wind.com>
---
 lib/librte_eal/linuxapp/eal/eal_hugepage_info.c |   28 +++++++++++++----------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
index 0b6ece7..b474159 100644
--- a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
+++ b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
@@ -274,22 +274,26 @@ eal_hugepage_info_init(void)
 	const char dirent_start_text[] = "hugepages-";
 	const size_t dirent_start_len = sizeof(dirent_start_text) - 1;
 	unsigned i, num_sizes = 0;
+	DIR *dir;
+	struct dirent *dirent;
 
-	DIR *dir = opendir(sys_dir_path);
+	dir = opendir(sys_dir_path);
 	if (dir == NULL)
-		rte_panic("Cannot open directory %s to read system hugepage info\n",
-				sys_dir_path);
+		rte_panic("Cannot open directory %s to read system hugepage "
+			  "info\n", sys_dir_path);
 
-	struct dirent *dirent = readdir(dir);
-	while(dirent != NULL){
-		if (strncmp(dirent->d_name, dirent_start_text, dirent_start_len) == 0){
-			struct hugepage_info *hpi = \
-					&internal_config.hugepage_info[num_sizes];
+	dirent = readdir(dir);
+	while (dirent != NULL) {
+		struct hugepage_info *hpi;
+
+		if (strncmp(dirent->d_name, dirent_start_text,
+			    dirent_start_len) == 0) {
+			hpi = &internal_config.hugepage_info[num_sizes];
 			hpi->hugepage_sz = rte_str_to_size(&dirent->d_name[dirent_start_len]);
 			hpi->hugedir = get_hugepage_dir(hpi->hugepage_sz);
 
 			/* first, check if we have a mountpoint */
-			if (hpi->hugedir == NULL){
+			if (hpi->hugedir == NULL) {
 				unsigned long num_pages;
 
 				num_pages = get_num_hugepages(dirent->d_name);
@@ -332,10 +336,10 @@ eal_hugepage_info_init(void)
 	internal_config.num_hugepage_sizes = num_sizes;
 
 	/* sort the page directory entries by size, largest to smallest */
-	for (i = 0; i < num_sizes; i++){
+	for (i = 0; i < num_sizes; i++) {
 		unsigned j;
 		for (j = i+1; j < num_sizes; j++)
-			if (internal_config.hugepage_info[j-1].hugepage_sz < \
+			if (internal_config.hugepage_info[j-1].hugepage_sz <
 					internal_config.hugepage_info[j].hugepage_sz)
 				swap_hpi(&internal_config.hugepage_info[j-1],
 						&internal_config.hugepage_info[j]);
@@ -344,7 +348,7 @@ eal_hugepage_info_init(void)
 	/* now we have all info, check we have at least one valid size */
 	for (i = 0; i < num_sizes; i++)
 		if (internal_config.hugepage_info[i].hugedir != NULL &&
-				internal_config.hugepage_info[i].num_pages[0] > 0)
+		    internal_config.hugepage_info[i].num_pages[0] > 0)
 			return 0;
 
 	/* no valid hugepage mounts available, return error */
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 4/6] eal/linux: rework while loop
  2015-07-07  9:00 [PATCH 0/6] eal/linux: cleanup hugepage code David Marchand
                   ` (2 preceding siblings ...)
  2015-07-07  9:00 ` [PATCH 3/6] eal/linux: cosmetic change David Marchand
@ 2015-07-07  9:00 ` David Marchand
  2015-07-07  9:00 ` [PATCH 5/6] eal/linux: indent file David Marchand
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 17+ messages in thread
From: David Marchand @ 2015-07-07  9:00 UTC (permalink / raw)
  To: dev

Replace this while loop with a for loop and simplify error handling.
Indent is broken on purpose, fixed in next commit.

Signed-off-by: David Marchand <david.marchand@6wind.com>
---
 lib/librte_eal/linuxapp/eal/eal_hugepage_info.c |   28 ++++++++++++-----------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
index b474159..de3f48d 100644
--- a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
+++ b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
@@ -282,12 +282,13 @@ eal_hugepage_info_init(void)
 		rte_panic("Cannot open directory %s to read system hugepage "
 			  "info\n", sys_dir_path);
 
-	dirent = readdir(dir);
-	while (dirent != NULL) {
+	for (dirent = readdir(dir); dirent != NULL; dirent = readdir(dir)) {
 		struct hugepage_info *hpi;
 
 		if (strncmp(dirent->d_name, dirent_start_text,
-			    dirent_start_len) == 0) {
+			    dirent_start_len) != 0)
+			continue;
+
 			hpi = &internal_config.hugepage_info[num_sizes];
 			hpi->hugepage_sz = rte_str_to_size(&dirent->d_name[dirent_start_len]);
 			hpi->hugedir = get_hugepage_dir(hpi->hugepage_sz);
@@ -301,21 +302,20 @@ eal_hugepage_info_init(void)
 					RTE_LOG(INFO, EAL, "%lu hugepages of size %lu reserved, "
 						"but no mounted hugetlbfs found for that size\n",
 						num_pages, hpi->hugepage_sz);
-			} else {
+				continue;
+			}
+
 				/* try to obtain a writelock */
 				hpi->lock_descriptor = open(hpi->hugedir, O_RDONLY);
 
 				/* if blocking lock failed */
 				if (flock(hpi->lock_descriptor, LOCK_EX) == -1) {
 					RTE_LOG(CRIT, EAL, "Failed to lock hugepage directory!\n");
-					closedir(dir);
-					return -1;
+					break;
 				}
 				/* clear out the hugepages dir from unused pages */
-				if (clear_hugedir(hpi->hugedir) == -1) {
-					closedir(dir);
-					return -1;
-				}
+				if (clear_hugedir(hpi->hugedir) == -1)
+					break;
 
 				/* for now, put all pages into socket 0,
 				 * later they will be sorted */
@@ -328,11 +328,13 @@ eal_hugepage_info_init(void)
 #endif
 
 				num_sizes++;
-			}
-		}
-		dirent = readdir(dir);
 	}
 	closedir(dir);
+
+	/* something went wrong, and we broke from the for loop above */
+	if (dirent != NULL)
+		return -1;
+
 	internal_config.num_hugepage_sizes = num_sizes;
 
 	/* sort the page directory entries by size, largest to smallest */
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 5/6] eal/linux: indent file
  2015-07-07  9:00 [PATCH 0/6] eal/linux: cleanup hugepage code David Marchand
                   ` (3 preceding siblings ...)
  2015-07-07  9:00 ` [PATCH 4/6] eal/linux: rework while loop David Marchand
@ 2015-07-07  9:00 ` David Marchand
  2015-07-07  9:00 ` [PATCH 6/6] eal/linux: avoid out of bound access David Marchand
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 17+ messages in thread
From: David Marchand @ 2015-07-07  9:00 UTC (permalink / raw)
  To: dev

With this, we should be checkpatch compliant.

Signed-off-by: David Marchand <david.marchand@6wind.com>
---
 lib/librte_eal/linuxapp/eal/eal_hugepage_info.c |   73 ++++++++++++-----------
 1 file changed, 39 insertions(+), 34 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
index de3f48d..df60f6e 100644
--- a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
+++ b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
@@ -289,45 +289,50 @@ eal_hugepage_info_init(void)
 			    dirent_start_len) != 0)
 			continue;
 
-			hpi = &internal_config.hugepage_info[num_sizes];
-			hpi->hugepage_sz = rte_str_to_size(&dirent->d_name[dirent_start_len]);
-			hpi->hugedir = get_hugepage_dir(hpi->hugepage_sz);
-
-			/* first, check if we have a mountpoint */
-			if (hpi->hugedir == NULL) {
-				unsigned long num_pages;
-
-				num_pages = get_num_hugepages(dirent->d_name);
-				if (num_pages > 0)
-					RTE_LOG(INFO, EAL, "%lu hugepages of size %lu reserved, "
-						"but no mounted hugetlbfs found for that size\n",
-						num_pages, hpi->hugepage_sz);
-				continue;
-			}
+		hpi = &internal_config.hugepage_info[num_sizes];
+		hpi->hugepage_sz =
+			rte_str_to_size(&dirent->d_name[dirent_start_len]);
+		hpi->hugedir = get_hugepage_dir(hpi->hugepage_sz);
+
+		/* first, check if we have a mountpoint */
+		if (hpi->hugedir == NULL) {
+			unsigned long num_pages;
+
+			num_pages = get_num_hugepages(dirent->d_name);
+			if (num_pages > 0)
+				RTE_LOG(INFO, EAL,
+					"%lu hugepages of size %lu reserved, "
+					"but no mounted hugetlbfs found for "
+					"that size\n",
+					num_pages, hpi->hugepage_sz);
+			continue;
+		}
 
-				/* try to obtain a writelock */
-				hpi->lock_descriptor = open(hpi->hugedir, O_RDONLY);
+		/* try to obtain a writelock */
+		hpi->lock_descriptor = open(hpi->hugedir, O_RDONLY);
 
-				/* if blocking lock failed */
-				if (flock(hpi->lock_descriptor, LOCK_EX) == -1) {
-					RTE_LOG(CRIT, EAL, "Failed to lock hugepage directory!\n");
-					break;
-				}
-				/* clear out the hugepages dir from unused pages */
-				if (clear_hugedir(hpi->hugedir) == -1)
-					break;
+		/* if blocking lock failed */
+		if (flock(hpi->lock_descriptor, LOCK_EX) == -1) {
+			RTE_LOG(CRIT, EAL,
+				"Failed to lock hugepage directory!\n");
+			break;
+		}
+		/* clear out the hugepages dir from unused pages */
+		if (clear_hugedir(hpi->hugedir) == -1)
+			break;
 
-				/* for now, put all pages into socket 0,
-				 * later they will be sorted */
-				hpi->num_pages[0] = get_num_hugepages(dirent->d_name);
+		/* for now, put all pages into socket 0,
+		 * later they will be sorted */
+		hpi->num_pages[0] = get_num_hugepages(dirent->d_name);
 
 #ifndef RTE_ARCH_64
-				/* for 32-bit systems, limit number of hugepages to 1GB per page size */
-				hpi->num_pages[0] = RTE_MIN(hpi->num_pages[0],
-						RTE_PGSIZE_1G / hpi->hugepage_sz);
+		/* for 32-bit systems, limit number of hugepages to
+		 * 1GB per page size */
+		hpi->num_pages[0] = RTE_MIN(hpi->num_pages[0],
+					    RTE_PGSIZE_1G / hpi->hugepage_sz);
 #endif
 
-				num_sizes++;
+		num_sizes++;
 	}
 	closedir(dir);
 
@@ -342,9 +347,9 @@ eal_hugepage_info_init(void)
 		unsigned j;
 		for (j = i+1; j < num_sizes; j++)
 			if (internal_config.hugepage_info[j-1].hugepage_sz <
-					internal_config.hugepage_info[j].hugepage_sz)
+			     internal_config.hugepage_info[j].hugepage_sz)
 				swap_hpi(&internal_config.hugepage_info[j-1],
-						&internal_config.hugepage_info[j]);
+					 &internal_config.hugepage_info[j]);
 	}
 
 	/* now we have all info, check we have at least one valid size */
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 6/6] eal/linux: avoid out of bound access
  2015-07-07  9:00 [PATCH 0/6] eal/linux: cleanup hugepage code David Marchand
                   ` (4 preceding siblings ...)
  2015-07-07  9:00 ` [PATCH 5/6] eal/linux: indent file David Marchand
@ 2015-07-07  9:00 ` David Marchand
  2015-07-08 11:03 ` [PATCH 0/6] eal/linux: cleanup hugepage code Gonzalez Monroy, Sergio
  2015-07-09  9:19 ` [PATCH v2 " David Marchand
  7 siblings, 0 replies; 17+ messages in thread
From: David Marchand @ 2015-07-07  9:00 UTC (permalink / raw)
  To: dev

Using IBM advance toolchain on Ubuntu 14.04 (package 8.0-3), gcc is complaining
about out of bound accesses.

  CC eal_hugepage_info.o
lib/librte_eal/linuxapp/eal/eal_hugepage_info.c:
In function ‘eal_hugepage_info_init’:
lib/librte_eal/linuxapp/eal/eal_hugepage_info.c:350:35:
error: array subscript is above array bounds [-Werror=array-bounds]
      internal_config.hugepage_info[j].hugepage_sz)
                                   ^
lib/librte_eal/linuxapp/eal/eal_hugepage_info.c:350:35:
error: array subscript is above array bounds [-Werror=array-bounds]
lib/librte_eal/linuxapp/eal/eal_hugepage_info.c:349:37:
error: array subscript is above array bounds [-Werror=array-bounds]
    if (internal_config.hugepage_info[j-1].hugepage_sz <
                                     ^
lib/librte_eal/linuxapp/eal/eal_hugepage_info.c:350:35:
error: array subscript is above array bounds [-Werror=array-bounds]
      internal_config.hugepage_info[j].hugepage_sz)

Looking at the code, these warnings are invalid from my pov and they disappeared
when upgrading the toolchain to new version (8.0-4).

However, the code was buggy (sorting code is wrong), so fix this by using qsort and adding a
check on num_sizes to avoid potential out of bound accesses.

Signed-off-by: David Marchand <david.marchand@6wind.com>
---
 lib/librte_eal/linuxapp/eal/eal_hugepage_info.c |   31 ++++++++++-------------
 1 file changed, 14 insertions(+), 17 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
index df60f6e..2f96164 100644
--- a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
+++ b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
@@ -184,15 +184,6 @@ get_hugepage_dir(uint64_t hugepage_sz)
 	return retval;
 }
 
-static inline void
-swap_hpi(struct hugepage_info *a, struct hugepage_info *b)
-{
-	char buf[sizeof(*a)];
-	memcpy(buf, a, sizeof(buf));
-	memcpy(a, b, sizeof(buf));
-	memcpy(b, buf, sizeof(buf));
-}
-
 /*
  * Clear the hugepage directory of whatever hugepage files
  * there are. Checks if the file is locked (i.e.
@@ -263,6 +254,15 @@ error:
 	return -1;
 }
 
+static int
+compare_hpi(const void *a, const void *b)
+{
+	const struct hugepage_info *hpi_a = a;
+	const struct hugepage_info *hpi_b = b;
+
+	return hpi_b->hugepage_sz - hpi_a->hugepage_sz;
+}
+
 /*
  * when we initialize the hugepage info, everything goes
  * to socket 0 by default. it will later get sorted by memory
@@ -289,6 +289,9 @@ eal_hugepage_info_init(void)
 			    dirent_start_len) != 0)
 			continue;
 
+		if (num_sizes >= MAX_HUGEPAGE_SIZES)
+			break;
+
 		hpi = &internal_config.hugepage_info[num_sizes];
 		hpi->hugepage_sz =
 			rte_str_to_size(&dirent->d_name[dirent_start_len]);
@@ -343,14 +346,8 @@ eal_hugepage_info_init(void)
 	internal_config.num_hugepage_sizes = num_sizes;
 
 	/* sort the page directory entries by size, largest to smallest */
-	for (i = 0; i < num_sizes; i++) {
-		unsigned j;
-		for (j = i+1; j < num_sizes; j++)
-			if (internal_config.hugepage_info[j-1].hugepage_sz <
-			     internal_config.hugepage_info[j].hugepage_sz)
-				swap_hpi(&internal_config.hugepage_info[j-1],
-					 &internal_config.hugepage_info[j]);
-	}
+	qsort(&internal_config.hugepage_info[0], num_sizes,
+	      sizeof(internal_config.hugepage_info[0]), compare_hpi);
 
 	/* now we have all info, check we have at least one valid size */
 	for (i = 0; i < num_sizes; i++)
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH 0/6] eal/linux: cleanup hugepage code
  2015-07-07  9:00 [PATCH 0/6] eal/linux: cleanup hugepage code David Marchand
                   ` (5 preceding siblings ...)
  2015-07-07  9:00 ` [PATCH 6/6] eal/linux: avoid out of bound access David Marchand
@ 2015-07-08 11:03 ` Gonzalez Monroy, Sergio
  2015-07-09  9:19 ` [PATCH v2 " David Marchand
  7 siblings, 0 replies; 17+ messages in thread
From: Gonzalez Monroy, Sergio @ 2015-07-08 11:03 UTC (permalink / raw)
  To: David Marchand, dev

On 07/07/2015 10:00, David Marchand wrote:
> Here is a little patchset cleaning eal_hugepage_info.c file and fixing a bug
> when having more than two hugepage sizes.
> No functional change to be expected.
>
Acked-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 2/6] eal/linux: remove useless casts
  2015-07-07  9:00 ` [PATCH 2/6] eal/linux: remove useless casts David Marchand
@ 2015-07-09  2:04   ` Thomas Monjalon
  0 siblings, 0 replies; 17+ messages in thread
From: Thomas Monjalon @ 2015-07-09  2:04 UTC (permalink / raw)
  To: David Marchand; +Cc: dev

David, there is a 32-bit failure. See below

2015-07-07 11:00, David Marchand:
> Rather than cast the huge pages number returned by get_num_hugepages, rework
> this function so that it returns 0 when something goes wrong.
> And no need for casts in log.

> --- a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
> +++ b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
> +					RTE_LOG(INFO, EAL, "%lu hugepages of size %lu reserved, "
> +						"but no mounted hugetlbfs found for that size\n",
> +						num_pages, hpi->hugepage_sz);

error: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 5 has type ‘uint64_t {aka long long unsigned int}’

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 0/6] eal/linux: cleanup hugepage code
  2015-07-07  9:00 [PATCH 0/6] eal/linux: cleanup hugepage code David Marchand
                   ` (6 preceding siblings ...)
  2015-07-08 11:03 ` [PATCH 0/6] eal/linux: cleanup hugepage code Gonzalez Monroy, Sergio
@ 2015-07-09  9:19 ` David Marchand
  2015-07-09  9:19   ` [PATCH v2 1/6] eal/linux: remove useless check on process type David Marchand
                     ` (6 more replies)
  7 siblings, 7 replies; 17+ messages in thread
From: David Marchand @ 2015-07-09  9:19 UTC (permalink / raw)
  To: dev

Here is a little patchset cleaning eal_hugepage_info.c file and fixing a bug
when having more than two hugepage sizes.
No functional change to be expected.

Changes since v1
- fix build on 32 bits system

-- 
David Marchand

David Marchand (6):
  eal/linux: remove useless check on process type
  eal/linux: remove useless casts
  eal/linux: cosmetic change
  eal/linux: rework while loop
  eal/linux: indent file
  eal/linux: avoid out of bound access

 lib/librte_eal/linuxapp/eal/eal_hugepage_info.c |  161 ++++++++++++-----------
 1 file changed, 85 insertions(+), 76 deletions(-)

-- 
1.7.10.4

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 1/6] eal/linux: remove useless check on process type
  2015-07-09  9:19 ` [PATCH v2 " David Marchand
@ 2015-07-09  9:19   ` David Marchand
  2015-07-09  9:19   ` [PATCH v2 2/6] eal/linux: remove useless casts David Marchand
                     ` (5 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: David Marchand @ 2015-07-09  9:19 UTC (permalink / raw)
  To: dev

The code in eal_hugepage_info.c is not reachable by secondary processes.

Signed-off-by: David Marchand <david.marchand@6wind.com>
Acked-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
---
 lib/librte_eal/linuxapp/eal/eal_hugepage_info.c |   17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
index 028e309..6dd8a0b 100644
--- a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
+++ b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
@@ -61,31 +61,24 @@
 
 static const char sys_dir_path[] = "/sys/kernel/mm/hugepages";
 
+/* this function is only called from eal_hugepage_info_init which itself
+ * is only called from a primary process */
 static int32_t
 get_num_hugepages(const char *subdir)
 {
 	char path[PATH_MAX];
 	long unsigned resv_pages, num_pages = 0;
-	const char *nr_hp_file;
+	const char *nr_hp_file = "free_hugepages";
 	const char *nr_rsvd_file = "resv_hugepages";
 
 	/* first, check how many reserved pages kernel reports */
 	snprintf(path, sizeof(path), "%s/%s/%s",
 			sys_dir_path, subdir, nr_rsvd_file);
-
 	if (eal_parse_sysfs_value(path, &resv_pages) < 0)
 		return 0;
 
-	/* if secondary process, just look at the number of hugepages,
-	 * otherwise look at number of free hugepages */
-	if (internal_config.process_type == RTE_PROC_SECONDARY)
-		nr_hp_file = "nr_hugepages";
-	else
-		nr_hp_file = "free_hugepages";
-
 	snprintf(path, sizeof(path), "%s/%s/%s",
 			sys_dir_path, subdir, nr_hp_file);
-
 	if (eal_parse_sysfs_value(path, &num_pages) < 0)
 		return 0;
 
@@ -93,8 +86,8 @@ get_num_hugepages(const char *subdir)
 		RTE_LOG(WARNING, EAL, "No free hugepages reported in %s\n",
 				subdir);
 
-	/* adjust num_pages in case of primary process */
-	if (num_pages > 0 && internal_config.process_type == RTE_PROC_PRIMARY)
+	/* adjust num_pages */
+	if (num_pages > 0)
 		num_pages -= resv_pages;
 
 	return (int32_t)num_pages;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 2/6] eal/linux: remove useless casts
  2015-07-09  9:19 ` [PATCH v2 " David Marchand
  2015-07-09  9:19   ` [PATCH v2 1/6] eal/linux: remove useless check on process type David Marchand
@ 2015-07-09  9:19   ` David Marchand
  2015-07-09  9:19   ` [PATCH v2 3/6] eal/linux: cosmetic change David Marchand
                     ` (4 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: David Marchand @ 2015-07-09  9:19 UTC (permalink / raw)
  To: dev

Rather than cast the huge pages number returned by get_num_hugepages, rework
this function so that it returns 0 when something goes wrong.
And no need for casts in log.

Signed-off-by: David Marchand <david.marchand@6wind.com>
Acked-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
---
 lib/librte_eal/linuxapp/eal/eal_hugepage_info.c |   26 +++++++++++++++--------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
index 6dd8a0b..91e288c 100644
--- a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
+++ b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
@@ -63,7 +63,7 @@ static const char sys_dir_path[] = "/sys/kernel/mm/hugepages";
 
 /* this function is only called from eal_hugepage_info_init which itself
  * is only called from a primary process */
-static int32_t
+static uint32_t
 get_num_hugepages(const char *subdir)
 {
 	char path[PATH_MAX];
@@ -87,10 +87,17 @@ get_num_hugepages(const char *subdir)
 				subdir);
 
 	/* adjust num_pages */
-	if (num_pages > 0)
+	if (num_pages >= resv_pages)
 		num_pages -= resv_pages;
+	else if (resv_pages)
+		num_pages = 0;
 
-	return (int32_t)num_pages;
+	/* we want to return a uint32_t and more than this looks suspicious
+	 * anyway ... */
+	if (num_pages > UINT32_MAX)
+		num_pages = UINT32_MAX;
+
+	return num_pages;
 }
 
 static uint64_t
@@ -288,12 +295,13 @@ eal_hugepage_info_init(void)
 
 			/* first, check if we have a mountpoint */
 			if (hpi->hugedir == NULL){
-				int32_t num_pages;
-				if ((num_pages = get_num_hugepages(dirent->d_name)) > 0)
-					RTE_LOG(INFO, EAL, "%u hugepages of size %llu reserved, "\
-							"but no mounted hugetlbfs found for that size\n",
-							(unsigned)num_pages,
-							(unsigned long long)hpi->hugepage_sz);
+				uint32_t num_pages;
+
+				num_pages = get_num_hugepages(dirent->d_name);
+				if (num_pages > 0)
+					RTE_LOG(INFO, EAL, "%" PRIu32 " hugepages of size %" PRIu64 " reserved, "
+						"but no mounted hugetlbfs found for that size\n",
+						num_pages, hpi->hugepage_sz);
 			} else {
 				/* try to obtain a writelock */
 				hpi->lock_descriptor = open(hpi->hugedir, O_RDONLY);
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 3/6] eal/linux: cosmetic change
  2015-07-09  9:19 ` [PATCH v2 " David Marchand
  2015-07-09  9:19   ` [PATCH v2 1/6] eal/linux: remove useless check on process type David Marchand
  2015-07-09  9:19   ` [PATCH v2 2/6] eal/linux: remove useless casts David Marchand
@ 2015-07-09  9:19   ` David Marchand
  2015-07-09  9:19   ` [PATCH v2 4/6] eal/linux: rework while loop David Marchand
                     ` (3 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: David Marchand @ 2015-07-09  9:19 UTC (permalink / raw)
  To: dev

Prepare for checkpatch compliance.

Signed-off-by: David Marchand <david.marchand@6wind.com>
Acked-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
---
 lib/librte_eal/linuxapp/eal/eal_hugepage_info.c |   28 +++++++++++++----------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
index 91e288c..e676a31 100644
--- a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
+++ b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
@@ -279,22 +279,26 @@ eal_hugepage_info_init(void)
 	const char dirent_start_text[] = "hugepages-";
 	const size_t dirent_start_len = sizeof(dirent_start_text) - 1;
 	unsigned i, num_sizes = 0;
+	DIR *dir;
+	struct dirent *dirent;
 
-	DIR *dir = opendir(sys_dir_path);
+	dir = opendir(sys_dir_path);
 	if (dir == NULL)
-		rte_panic("Cannot open directory %s to read system hugepage info\n",
-				sys_dir_path);
+		rte_panic("Cannot open directory %s to read system hugepage "
+			  "info\n", sys_dir_path);
 
-	struct dirent *dirent = readdir(dir);
-	while(dirent != NULL){
-		if (strncmp(dirent->d_name, dirent_start_text, dirent_start_len) == 0){
-			struct hugepage_info *hpi = \
-					&internal_config.hugepage_info[num_sizes];
+	dirent = readdir(dir);
+	while (dirent != NULL) {
+		struct hugepage_info *hpi;
+
+		if (strncmp(dirent->d_name, dirent_start_text,
+			    dirent_start_len) == 0) {
+			hpi = &internal_config.hugepage_info[num_sizes];
 			hpi->hugepage_sz = rte_str_to_size(&dirent->d_name[dirent_start_len]);
 			hpi->hugedir = get_hugepage_dir(hpi->hugepage_sz);
 
 			/* first, check if we have a mountpoint */
-			if (hpi->hugedir == NULL){
+			if (hpi->hugedir == NULL) {
 				uint32_t num_pages;
 
 				num_pages = get_num_hugepages(dirent->d_name);
@@ -337,10 +341,10 @@ eal_hugepage_info_init(void)
 	internal_config.num_hugepage_sizes = num_sizes;
 
 	/* sort the page directory entries by size, largest to smallest */
-	for (i = 0; i < num_sizes; i++){
+	for (i = 0; i < num_sizes; i++) {
 		unsigned j;
 		for (j = i+1; j < num_sizes; j++)
-			if (internal_config.hugepage_info[j-1].hugepage_sz < \
+			if (internal_config.hugepage_info[j-1].hugepage_sz <
 					internal_config.hugepage_info[j].hugepage_sz)
 				swap_hpi(&internal_config.hugepage_info[j-1],
 						&internal_config.hugepage_info[j]);
@@ -349,7 +353,7 @@ eal_hugepage_info_init(void)
 	/* now we have all info, check we have at least one valid size */
 	for (i = 0; i < num_sizes; i++)
 		if (internal_config.hugepage_info[i].hugedir != NULL &&
-				internal_config.hugepage_info[i].num_pages[0] > 0)
+		    internal_config.hugepage_info[i].num_pages[0] > 0)
 			return 0;
 
 	/* no valid hugepage mounts available, return error */
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 4/6] eal/linux: rework while loop
  2015-07-09  9:19 ` [PATCH v2 " David Marchand
                     ` (2 preceding siblings ...)
  2015-07-09  9:19   ` [PATCH v2 3/6] eal/linux: cosmetic change David Marchand
@ 2015-07-09  9:19   ` David Marchand
  2015-07-09  9:19   ` [PATCH v2 5/6] eal/linux: indent file David Marchand
                     ` (2 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: David Marchand @ 2015-07-09  9:19 UTC (permalink / raw)
  To: dev

Replace this while loop with a for loop and simplify error handling.
Indent is broken on purpose, fixed in next commit.

Signed-off-by: David Marchand <david.marchand@6wind.com>
Acked-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
---
 lib/librte_eal/linuxapp/eal/eal_hugepage_info.c |   28 ++++++++++++-----------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
index e676a31..d602350 100644
--- a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
+++ b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
@@ -287,12 +287,13 @@ eal_hugepage_info_init(void)
 		rte_panic("Cannot open directory %s to read system hugepage "
 			  "info\n", sys_dir_path);
 
-	dirent = readdir(dir);
-	while (dirent != NULL) {
+	for (dirent = readdir(dir); dirent != NULL; dirent = readdir(dir)) {
 		struct hugepage_info *hpi;
 
 		if (strncmp(dirent->d_name, dirent_start_text,
-			    dirent_start_len) == 0) {
+			    dirent_start_len) != 0)
+			continue;
+
 			hpi = &internal_config.hugepage_info[num_sizes];
 			hpi->hugepage_sz = rte_str_to_size(&dirent->d_name[dirent_start_len]);
 			hpi->hugedir = get_hugepage_dir(hpi->hugepage_sz);
@@ -306,21 +307,20 @@ eal_hugepage_info_init(void)
 					RTE_LOG(INFO, EAL, "%" PRIu32 " hugepages of size %" PRIu64 " reserved, "
 						"but no mounted hugetlbfs found for that size\n",
 						num_pages, hpi->hugepage_sz);
-			} else {
+				continue;
+			}
+
 				/* try to obtain a writelock */
 				hpi->lock_descriptor = open(hpi->hugedir, O_RDONLY);
 
 				/* if blocking lock failed */
 				if (flock(hpi->lock_descriptor, LOCK_EX) == -1) {
 					RTE_LOG(CRIT, EAL, "Failed to lock hugepage directory!\n");
-					closedir(dir);
-					return -1;
+					break;
 				}
 				/* clear out the hugepages dir from unused pages */
-				if (clear_hugedir(hpi->hugedir) == -1) {
-					closedir(dir);
-					return -1;
-				}
+				if (clear_hugedir(hpi->hugedir) == -1)
+					break;
 
 				/* for now, put all pages into socket 0,
 				 * later they will be sorted */
@@ -333,11 +333,13 @@ eal_hugepage_info_init(void)
 #endif
 
 				num_sizes++;
-			}
-		}
-		dirent = readdir(dir);
 	}
 	closedir(dir);
+
+	/* something went wrong, and we broke from the for loop above */
+	if (dirent != NULL)
+		return -1;
+
 	internal_config.num_hugepage_sizes = num_sizes;
 
 	/* sort the page directory entries by size, largest to smallest */
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 5/6] eal/linux: indent file
  2015-07-09  9:19 ` [PATCH v2 " David Marchand
                     ` (3 preceding siblings ...)
  2015-07-09  9:19   ` [PATCH v2 4/6] eal/linux: rework while loop David Marchand
@ 2015-07-09  9:19   ` David Marchand
  2015-07-09  9:19   ` [PATCH v2 6/6] eal/linux: avoid out of bound access David Marchand
  2015-07-09 12:21   ` [PATCH v2 0/6] eal/linux: cleanup hugepage code Thomas Monjalon
  6 siblings, 0 replies; 17+ messages in thread
From: David Marchand @ 2015-07-09  9:19 UTC (permalink / raw)
  To: dev

With this, we should be checkpatch compliant.

Signed-off-by: David Marchand <david.marchand@6wind.com>
Acked-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
---
 lib/librte_eal/linuxapp/eal/eal_hugepage_info.c |   73 ++++++++++++-----------
 1 file changed, 39 insertions(+), 34 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
index d602350..f097e71 100644
--- a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
+++ b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
@@ -294,45 +294,50 @@ eal_hugepage_info_init(void)
 			    dirent_start_len) != 0)
 			continue;
 
-			hpi = &internal_config.hugepage_info[num_sizes];
-			hpi->hugepage_sz = rte_str_to_size(&dirent->d_name[dirent_start_len]);
-			hpi->hugedir = get_hugepage_dir(hpi->hugepage_sz);
-
-			/* first, check if we have a mountpoint */
-			if (hpi->hugedir == NULL) {
-				uint32_t num_pages;
-
-				num_pages = get_num_hugepages(dirent->d_name);
-				if (num_pages > 0)
-					RTE_LOG(INFO, EAL, "%" PRIu32 " hugepages of size %" PRIu64 " reserved, "
-						"but no mounted hugetlbfs found for that size\n",
-						num_pages, hpi->hugepage_sz);
-				continue;
-			}
+		hpi = &internal_config.hugepage_info[num_sizes];
+		hpi->hugepage_sz =
+			rte_str_to_size(&dirent->d_name[dirent_start_len]);
+		hpi->hugedir = get_hugepage_dir(hpi->hugepage_sz);
+
+		/* first, check if we have a mountpoint */
+		if (hpi->hugedir == NULL) {
+			uint32_t num_pages;
+
+			num_pages = get_num_hugepages(dirent->d_name);
+			if (num_pages > 0)
+				RTE_LOG(INFO, EAL,
+					"%" PRIu32 " hugepages of size "
+					"%" PRIu64 " reserved, but no mounted "
+					"hugetlbfs found for that size\n",
+					num_pages, hpi->hugepage_sz);
+			continue;
+		}
 
-				/* try to obtain a writelock */
-				hpi->lock_descriptor = open(hpi->hugedir, O_RDONLY);
+		/* try to obtain a writelock */
+		hpi->lock_descriptor = open(hpi->hugedir, O_RDONLY);
 
-				/* if blocking lock failed */
-				if (flock(hpi->lock_descriptor, LOCK_EX) == -1) {
-					RTE_LOG(CRIT, EAL, "Failed to lock hugepage directory!\n");
-					break;
-				}
-				/* clear out the hugepages dir from unused pages */
-				if (clear_hugedir(hpi->hugedir) == -1)
-					break;
+		/* if blocking lock failed */
+		if (flock(hpi->lock_descriptor, LOCK_EX) == -1) {
+			RTE_LOG(CRIT, EAL,
+				"Failed to lock hugepage directory!\n");
+			break;
+		}
+		/* clear out the hugepages dir from unused pages */
+		if (clear_hugedir(hpi->hugedir) == -1)
+			break;
 
-				/* for now, put all pages into socket 0,
-				 * later they will be sorted */
-				hpi->num_pages[0] = get_num_hugepages(dirent->d_name);
+		/* for now, put all pages into socket 0,
+		 * later they will be sorted */
+		hpi->num_pages[0] = get_num_hugepages(dirent->d_name);
 
 #ifndef RTE_ARCH_64
-				/* for 32-bit systems, limit number of hugepages to 1GB per page size */
-				hpi->num_pages[0] = RTE_MIN(hpi->num_pages[0],
-						RTE_PGSIZE_1G / hpi->hugepage_sz);
+		/* for 32-bit systems, limit number of hugepages to
+		 * 1GB per page size */
+		hpi->num_pages[0] = RTE_MIN(hpi->num_pages[0],
+					    RTE_PGSIZE_1G / hpi->hugepage_sz);
 #endif
 
-				num_sizes++;
+		num_sizes++;
 	}
 	closedir(dir);
 
@@ -347,9 +352,9 @@ eal_hugepage_info_init(void)
 		unsigned j;
 		for (j = i+1; j < num_sizes; j++)
 			if (internal_config.hugepage_info[j-1].hugepage_sz <
-					internal_config.hugepage_info[j].hugepage_sz)
+			     internal_config.hugepage_info[j].hugepage_sz)
 				swap_hpi(&internal_config.hugepage_info[j-1],
-						&internal_config.hugepage_info[j]);
+					 &internal_config.hugepage_info[j]);
 	}
 
 	/* now we have all info, check we have at least one valid size */
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 6/6] eal/linux: avoid out of bound access
  2015-07-09  9:19 ` [PATCH v2 " David Marchand
                     ` (4 preceding siblings ...)
  2015-07-09  9:19   ` [PATCH v2 5/6] eal/linux: indent file David Marchand
@ 2015-07-09  9:19   ` David Marchand
  2015-07-09 12:21   ` [PATCH v2 0/6] eal/linux: cleanup hugepage code Thomas Monjalon
  6 siblings, 0 replies; 17+ messages in thread
From: David Marchand @ 2015-07-09  9:19 UTC (permalink / raw)
  To: dev

Using IBM advance toolchain on Ubuntu 14.04 (package 8.0-3), gcc is complaining
about out of bound accesses.

  CC eal_hugepage_info.o
lib/librte_eal/linuxapp/eal/eal_hugepage_info.c:
In function ‘eal_hugepage_info_init’:
lib/librte_eal/linuxapp/eal/eal_hugepage_info.c:350:35:
error: array subscript is above array bounds [-Werror=array-bounds]
      internal_config.hugepage_info[j].hugepage_sz)
                                   ^
lib/librte_eal/linuxapp/eal/eal_hugepage_info.c:350:35:
error: array subscript is above array bounds [-Werror=array-bounds]
lib/librte_eal/linuxapp/eal/eal_hugepage_info.c:349:37:
error: array subscript is above array bounds [-Werror=array-bounds]
    if (internal_config.hugepage_info[j-1].hugepage_sz <
                                     ^
lib/librte_eal/linuxapp/eal/eal_hugepage_info.c:350:35:
error: array subscript is above array bounds [-Werror=array-bounds]
      internal_config.hugepage_info[j].hugepage_sz)

Looking at the code, these warnings are invalid from my pov and they disappeared
when upgrading the toolchain to new version (8.0-4).

However, the code was buggy (sorting code is wrong), so fix this by using qsort
and adding a check on num_sizes to avoid potential out of bound accesses.

Signed-off-by: David Marchand <david.marchand@6wind.com>
Acked-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
---
 lib/librte_eal/linuxapp/eal/eal_hugepage_info.c |   31 ++++++++++-------------
 1 file changed, 14 insertions(+), 17 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
index f097e71..cdaa47b 100644
--- a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
+++ b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
@@ -189,15 +189,6 @@ get_hugepage_dir(uint64_t hugepage_sz)
 	return retval;
 }
 
-static inline void
-swap_hpi(struct hugepage_info *a, struct hugepage_info *b)
-{
-	char buf[sizeof(*a)];
-	memcpy(buf, a, sizeof(buf));
-	memcpy(a, b, sizeof(buf));
-	memcpy(b, buf, sizeof(buf));
-}
-
 /*
  * Clear the hugepage directory of whatever hugepage files
  * there are. Checks if the file is locked (i.e.
@@ -268,6 +259,15 @@ error:
 	return -1;
 }
 
+static int
+compare_hpi(const void *a, const void *b)
+{
+	const struct hugepage_info *hpi_a = a;
+	const struct hugepage_info *hpi_b = b;
+
+	return hpi_b->hugepage_sz - hpi_a->hugepage_sz;
+}
+
 /*
  * when we initialize the hugepage info, everything goes
  * to socket 0 by default. it will later get sorted by memory
@@ -294,6 +294,9 @@ eal_hugepage_info_init(void)
 			    dirent_start_len) != 0)
 			continue;
 
+		if (num_sizes >= MAX_HUGEPAGE_SIZES)
+			break;
+
 		hpi = &internal_config.hugepage_info[num_sizes];
 		hpi->hugepage_sz =
 			rte_str_to_size(&dirent->d_name[dirent_start_len]);
@@ -348,14 +351,8 @@ eal_hugepage_info_init(void)
 	internal_config.num_hugepage_sizes = num_sizes;
 
 	/* sort the page directory entries by size, largest to smallest */
-	for (i = 0; i < num_sizes; i++) {
-		unsigned j;
-		for (j = i+1; j < num_sizes; j++)
-			if (internal_config.hugepage_info[j-1].hugepage_sz <
-			     internal_config.hugepage_info[j].hugepage_sz)
-				swap_hpi(&internal_config.hugepage_info[j-1],
-					 &internal_config.hugepage_info[j]);
-	}
+	qsort(&internal_config.hugepage_info[0], num_sizes,
+	      sizeof(internal_config.hugepage_info[0]), compare_hpi);
 
 	/* now we have all info, check we have at least one valid size */
 	for (i = 0; i < num_sizes; i++)
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 0/6] eal/linux: cleanup hugepage code
  2015-07-09  9:19 ` [PATCH v2 " David Marchand
                     ` (5 preceding siblings ...)
  2015-07-09  9:19   ` [PATCH v2 6/6] eal/linux: avoid out of bound access David Marchand
@ 2015-07-09 12:21   ` Thomas Monjalon
  6 siblings, 0 replies; 17+ messages in thread
From: Thomas Monjalon @ 2015-07-09 12:21 UTC (permalink / raw)
  To: David Marchand; +Cc: dev

2015-07-09 11:19, David Marchand:
> Here is a little patchset cleaning eal_hugepage_info.c file and fixing a bug
> when having more than two hugepage sizes.
> No functional change to be expected.
> 
> Changes since v1
> - fix build on 32 bits system

Applied, thanks

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2015-07-09 12:22 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-07  9:00 [PATCH 0/6] eal/linux: cleanup hugepage code David Marchand
2015-07-07  9:00 ` [PATCH 1/6] eal/linux: remove useless check on process type David Marchand
2015-07-07  9:00 ` [PATCH 2/6] eal/linux: remove useless casts David Marchand
2015-07-09  2:04   ` Thomas Monjalon
2015-07-07  9:00 ` [PATCH 3/6] eal/linux: cosmetic change David Marchand
2015-07-07  9:00 ` [PATCH 4/6] eal/linux: rework while loop David Marchand
2015-07-07  9:00 ` [PATCH 5/6] eal/linux: indent file David Marchand
2015-07-07  9:00 ` [PATCH 6/6] eal/linux: avoid out of bound access David Marchand
2015-07-08 11:03 ` [PATCH 0/6] eal/linux: cleanup hugepage code Gonzalez Monroy, Sergio
2015-07-09  9:19 ` [PATCH v2 " David Marchand
2015-07-09  9:19   ` [PATCH v2 1/6] eal/linux: remove useless check on process type David Marchand
2015-07-09  9:19   ` [PATCH v2 2/6] eal/linux: remove useless casts David Marchand
2015-07-09  9:19   ` [PATCH v2 3/6] eal/linux: cosmetic change David Marchand
2015-07-09  9:19   ` [PATCH v2 4/6] eal/linux: rework while loop David Marchand
2015-07-09  9:19   ` [PATCH v2 5/6] eal/linux: indent file David Marchand
2015-07-09  9:19   ` [PATCH v2 6/6] eal/linux: avoid out of bound access David Marchand
2015-07-09 12:21   ` [PATCH v2 0/6] eal/linux: cleanup hugepage code Thomas Monjalon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.