EAL: count nr_overcommit_hugepages as available

Message ID 447Z3z1XpYz9d@rere.qmqm.pl (mailing list archive)
State Accepted, archived
Delegated to: Thomas Monjalon
Headers
Series EAL: count nr_overcommit_hugepages as available |

Checks

Context Check Description
ci/Intel-compilation success Compilation OK

Commit Message

Michał Mirosław Feb. 25, 2019, 8:57 p.m. UTC
  From: Michał Mirosław <michal.miroslaw@atendesoftware.pl>

With nr_overcommit_hugepages > 0 application may be able to allocate
hugepages even when free_hugepages == 0. Take this into account when
counting available hugepages.

Signed-off-by: Michał Mirosław <michal.miroslaw@atendesoftware.pl>
---
 .../linuxapp/eal/eal_hugepage_info.c          | 43 ++++++++++++++-----
 1 file changed, 32 insertions(+), 11 deletions(-)
  

Comments

Burakov, Anatoly March 19, 2019, 1:52 p.m. UTC | #1
On 25-Feb-19 8:57 PM, Michał Mirosław wrote:
> From: Michał Mirosław <michal.miroslaw@atendesoftware.pl>
> 
> With nr_overcommit_hugepages > 0 application may be able to allocate
> hugepages even when free_hugepages == 0. Take this into account when
> counting available hugepages.
> 
> Signed-off-by: Michał Mirosław <michal.miroslaw@atendesoftware.pl>
> ---

Surplus pages go back at least as far as 2009, and as far as i can tell, 
the patch works under any conditions i thought to throw at it, and 
doesn't break anything else. So...

Reviewed-by: Anatoly Burakov <anatoly.burakov@intel.com>
  
Thomas Monjalon March 28, 2019, 10:43 p.m. UTC | #2
19/03/2019 14:52, Burakov, Anatoly:
> On 25-Feb-19 8:57 PM, Michał Mirosław wrote:
> > From: Michał Mirosław <michal.miroslaw@atendesoftware.pl>
> > 
> > With nr_overcommit_hugepages > 0 application may be able to allocate
> > hugepages even when free_hugepages == 0. Take this into account when
> > counting available hugepages.
> > 
> > Signed-off-by: Michał Mirosław <michal.miroslaw@atendesoftware.pl>
> > ---
> 
> Surplus pages go back at least as far as 2009, and as far as i can tell, 
> the patch works under any conditions i thought to throw at it, and 
> doesn't break anything else. So...
> 
> Reviewed-by: Anatoly Burakov <anatoly.burakov@intel.com>

Applied, thanks

And thanks Ferruh for reminding to update this very old patch.
  

Patch

diff --git a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
index 0eab1cf71..ce3e99256 100644
--- a/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
+++ b/lib/librte_eal/linuxapp/eal/eal_hugepage_info.c
@@ -70,30 +70,38 @@  create_shared_memory(const char *filename, const size_t mem_size)
 	return map_shared_memory(filename, mem_size, O_RDWR | O_CREAT);
 }
 
+static int get_hp_sysfs_value(const char *subdir, const char *file, unsigned long *val)
+{
+	char path[PATH_MAX];
+
+	snprintf(path, sizeof(path), "%s/%s/%s",
+			sys_dir_path, subdir, file);
+	return eal_parse_sysfs_value(path, val);
+}
+
 /* this function is only called from eal_hugepage_info_init which itself
  * is only called from a primary process */
 static uint32_t
 get_num_hugepages(const char *subdir)
 {
-	char path[PATH_MAX];
-	long unsigned resv_pages, num_pages = 0;
+	unsigned long resv_pages, num_pages, over_pages, surplus_pages;
 	const char *nr_hp_file = "free_hugepages";
 	const char *nr_rsvd_file = "resv_hugepages";
+	const char *nr_over_file = "nr_overcommit_hugepages";
+	const char *nr_splus_file = "surplus_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)
+	if (get_hp_sysfs_value(subdir, nr_rsvd_file, &resv_pages) < 0)
 		return 0;
 
-	snprintf(path, sizeof(path), "%s/%s/%s",
-			sys_dir_path, subdir, nr_hp_file);
-	if (eal_parse_sysfs_value(path, &num_pages) < 0)
+	if (get_hp_sysfs_value(subdir, nr_hp_file, &num_pages) < 0)
 		return 0;
 
-	if (num_pages == 0)
-		RTE_LOG(WARNING, EAL, "No free hugepages reported in %s\n",
-				subdir);
+	if (get_hp_sysfs_value(subdir, nr_over_file, &over_pages) < 0)
+		over_pages = 0;
+
+	if (get_hp_sysfs_value(subdir, nr_splus_file, &surplus_pages) < 0)
+		surplus_pages = 0;
 
 	/* adjust num_pages */
 	if (num_pages >= resv_pages)
@@ -101,6 +109,19 @@  get_num_hugepages(const char *subdir)
 	else if (resv_pages)
 		num_pages = 0;
 
+	if (over_pages >= surplus_pages)
+		over_pages -= surplus_pages;
+	else
+		over_pages = 0;
+
+	if (num_pages == 0 && over_pages == 0)
+		RTE_LOG(WARNING, EAL, "No available hugepages reported in %s\n",
+				subdir);
+
+	num_pages += over_pages;
+	if (num_pages < over_pages) /* overflow */
+		num_pages = UINT32_MAX;
+
 	/* we want to return a uint32_t and more than this looks suspicious
 	 * anyway ... */
 	if (num_pages > UINT32_MAX)