DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/6] eal/linux: cleanup hugepage code
@ 2015-07-07  9:00 David Marchand
  2015-07-07  9:00 ` [dpdk-dev] [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

* [dpdk-dev] [PATCH 1/6] eal/linux: remove useless check on process type
  2015-07-07  9:00 [dpdk-dev] [PATCH 0/6] eal/linux: cleanup hugepage code David Marchand
@ 2015-07-07  9:00 ` David Marchand
  2015-07-07  9:00 ` [dpdk-dev] [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	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH 2/6] eal/linux: remove useless casts
  2015-07-07  9:00 [dpdk-dev] [PATCH 0/6] eal/linux: cleanup hugepage code David Marchand
  2015-07-07  9:00 ` [dpdk-dev] [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 ` [dpdk-dev] [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	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH 3/6] eal/linux: cosmetic change
  2015-07-07  9:00 [dpdk-dev] [PATCH 0/6] eal/linux: cleanup hugepage code David Marchand
  2015-07-07  9:00 ` [dpdk-dev] [PATCH 1/6] eal/linux: remove useless check on process type David Marchand
  2015-07-07  9:00 ` [dpdk-dev] [PATCH 2/6] eal/linux: remove useless casts David Marchand
@ 2015-07-07  9:00 ` David Marchand
  2015-07-07  9:00 ` [dpdk-dev] [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	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH 4/6] eal/linux: rework while loop
  2015-07-07  9:00 [dpdk-dev] [PATCH 0/6] eal/linux: cleanup hugepage code David Marchand
                   ` (2 preceding siblings ...)
  2015-07-07  9:00 ` [dpdk-dev] [PATCH 3/6] eal/linux: cosmetic change David Marchand
@ 2015-07-07  9:00 ` David Marchand
  2015-07-07  9:00 ` [dpdk-dev] [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	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH 5/6] eal/linux: indent file
  2015-07-07  9:00 [dpdk-dev] [PATCH 0/6] eal/linux: cleanup hugepage code David Marchand
                   ` (3 preceding siblings ...)
  2015-07-07  9:00 ` [dpdk-dev] [PATCH 4/6] eal/linux: rework while loop David Marchand
@ 2015-07-07  9:00 ` David Marchand
  2015-07-07  9:00 ` [dpdk-dev] [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	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH 6/6] eal/linux: avoid out of bound access
  2015-07-07  9:00 [dpdk-dev] [PATCH 0/6] eal/linux: cleanup hugepage code David Marchand
                   ` (4 preceding siblings ...)
  2015-07-07  9:00 ` [dpdk-dev] [PATCH 5/6] eal/linux: indent file David Marchand
@ 2015-07-07  9:00 ` David Marchand
  2015-07-08 11:03 ` [dpdk-dev] [PATCH 0/6] eal/linux: cleanup hugepage code Gonzalez Monroy, Sergio
  2015-07-09  9:19 ` [dpdk-dev] [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	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH 0/6] eal/linux: cleanup hugepage code
  2015-07-07  9:00 [dpdk-dev] [PATCH 0/6] eal/linux: cleanup hugepage code David Marchand
                   ` (5 preceding siblings ...)
  2015-07-07  9:00 ` [dpdk-dev] [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 ` [dpdk-dev] [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: [dpdk-dev] [PATCH 2/6] eal/linux: remove useless casts
  2015-07-07  9:00 ` [dpdk-dev] [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

* [dpdk-dev] [PATCH v2 0/6] eal/linux: cleanup hugepage code
  2015-07-07  9:00 [dpdk-dev] [PATCH 0/6] eal/linux: cleanup hugepage code David Marchand
                   ` (6 preceding siblings ...)
  2015-07-08 11:03 ` [dpdk-dev] [PATCH 0/6] eal/linux: cleanup hugepage code Gonzalez Monroy, Sergio
@ 2015-07-09  9:19 ` David Marchand
  2015-07-09  9:19   ` [dpdk-dev] [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

* [dpdk-dev] [PATCH v2 1/6] eal/linux: remove useless check on process type
  2015-07-09  9:19 ` [dpdk-dev] [PATCH v2 " David Marchand
@ 2015-07-09  9:19   ` David Marchand
  2015-07-09  9:19   ` [dpdk-dev] [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	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v2 2/6] eal/linux: remove useless casts
  2015-07-09  9:19 ` [dpdk-dev] [PATCH v2 " David Marchand
  2015-07-09  9:19   ` [dpdk-dev] [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   ` [dpdk-dev] [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	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v2 3/6] eal/linux: cosmetic change
  2015-07-09  9:19 ` [dpdk-dev] [PATCH v2 " David Marchand
  2015-07-09  9:19   ` [dpdk-dev] [PATCH v2 1/6] eal/linux: remove useless check on process type David Marchand
  2015-07-09  9:19   ` [dpdk-dev] [PATCH v2 2/6] eal/linux: remove useless casts David Marchand
@ 2015-07-09  9:19   ` David Marchand
  2015-07-09  9:19   ` [dpdk-dev] [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	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v2 4/6] eal/linux: rework while loop
  2015-07-09  9:19 ` [dpdk-dev] [PATCH v2 " David Marchand
                     ` (2 preceding siblings ...)
  2015-07-09  9:19   ` [dpdk-dev] [PATCH v2 3/6] eal/linux: cosmetic change David Marchand
@ 2015-07-09  9:19   ` David Marchand
  2015-07-09  9:19   ` [dpdk-dev] [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	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v2 5/6] eal/linux: indent file
  2015-07-09  9:19 ` [dpdk-dev] [PATCH v2 " David Marchand
                     ` (3 preceding siblings ...)
  2015-07-09  9:19   ` [dpdk-dev] [PATCH v2 4/6] eal/linux: rework while loop David Marchand
@ 2015-07-09  9:19   ` David Marchand
  2015-07-09  9:19   ` [dpdk-dev] [PATCH v2 6/6] eal/linux: avoid out of bound access David Marchand
  2015-07-09 12:21   ` [dpdk-dev] [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	[flat|nested] 17+ messages in thread

* [dpdk-dev] [PATCH v2 6/6] eal/linux: avoid out of bound access
  2015-07-09  9:19 ` [dpdk-dev] [PATCH v2 " David Marchand
                     ` (4 preceding siblings ...)
  2015-07-09  9:19   ` [dpdk-dev] [PATCH v2 5/6] eal/linux: indent file David Marchand
@ 2015-07-09  9:19   ` David Marchand
  2015-07-09 12:21   ` [dpdk-dev] [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	[flat|nested] 17+ messages in thread

* Re: [dpdk-dev] [PATCH v2 0/6] eal/linux: cleanup hugepage code
  2015-07-09  9:19 ` [dpdk-dev] [PATCH v2 " David Marchand
                     ` (5 preceding siblings ...)
  2015-07-09  9:19   ` [dpdk-dev] [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 [dpdk-dev] [PATCH 0/6] eal/linux: cleanup hugepage code David Marchand
2015-07-07  9:00 ` [dpdk-dev] [PATCH 1/6] eal/linux: remove useless check on process type David Marchand
2015-07-07  9:00 ` [dpdk-dev] [PATCH 2/6] eal/linux: remove useless casts David Marchand
2015-07-09  2:04   ` Thomas Monjalon
2015-07-07  9:00 ` [dpdk-dev] [PATCH 3/6] eal/linux: cosmetic change David Marchand
2015-07-07  9:00 ` [dpdk-dev] [PATCH 4/6] eal/linux: rework while loop David Marchand
2015-07-07  9:00 ` [dpdk-dev] [PATCH 5/6] eal/linux: indent file David Marchand
2015-07-07  9:00 ` [dpdk-dev] [PATCH 6/6] eal/linux: avoid out of bound access David Marchand
2015-07-08 11:03 ` [dpdk-dev] [PATCH 0/6] eal/linux: cleanup hugepage code Gonzalez Monroy, Sergio
2015-07-09  9:19 ` [dpdk-dev] [PATCH v2 " David Marchand
2015-07-09  9:19   ` [dpdk-dev] [PATCH v2 1/6] eal/linux: remove useless check on process type David Marchand
2015-07-09  9:19   ` [dpdk-dev] [PATCH v2 2/6] eal/linux: remove useless casts David Marchand
2015-07-09  9:19   ` [dpdk-dev] [PATCH v2 3/6] eal/linux: cosmetic change David Marchand
2015-07-09  9:19   ` [dpdk-dev] [PATCH v2 4/6] eal/linux: rework while loop David Marchand
2015-07-09  9:19   ` [dpdk-dev] [PATCH v2 5/6] eal/linux: indent file David Marchand
2015-07-09  9:19   ` [dpdk-dev] [PATCH v2 6/6] eal/linux: avoid out of bound access David Marchand
2015-07-09 12:21   ` [dpdk-dev] [PATCH v2 0/6] eal/linux: cleanup hugepage code Thomas Monjalon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).