All of lore.kernel.org
 help / color / mirror / Atom feed
From: <dkozlyuk@oss.nvidia.com>
To: <dev@dpdk.org>
Cc: Anatoly Burakov <anatoly.burakov@intel.com>,
	Dmitry Kozlyuk <dkozlyuk@oss.nvidia.com>,
	John Levon <john.levon@nutanix.com>,
	"Viacheslav Ovsiienko" <viacheslavo@oss.nvidia.com>
Subject: [dpdk-dev] [PATCH v5 1/3] eal/linux: make hugetlbfs analysis reusable
Date: Tue, 21 Sep 2021 11:16:30 +0300	[thread overview]
Message-ID: <20210921081632.858873-2-dkozlyuk@nvidia.com> (raw)
In-Reply-To: <20210921081632.858873-1-dkozlyuk@nvidia.com>

From: Dmitry Kozlyuk <dkozlyuk@nvidia.com>

get_hugepage_dir() searched for a hugetlbfs mount with a given page size
using handcraft parsing of /proc/mounts and mixing traversal logic with
selecting the needed entry. Separate code to enumerate hugetlbfs mounts
to eal_hugepage_mount_walk() taking a callback that can inspect already
parsed entries. Use mntent(3) API for parsing. This allows to reuse
enumeration logic in subsequent patches.

Signed-off-by: Dmitry Kozlyuk <dkozlyuk@nvidia.com>
Reviewed-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
 lib/eal/linux/eal_hugepage_info.c | 153 +++++++++++++++++++-----------
 lib/eal/linux/eal_hugepage_info.h |  39 ++++++++
 2 files changed, 135 insertions(+), 57 deletions(-)
 create mode 100644 lib/eal/linux/eal_hugepage_info.h

diff --git a/lib/eal/linux/eal_hugepage_info.c b/lib/eal/linux/eal_hugepage_info.c
index d97792cade..193282e779 100644
--- a/lib/eal/linux/eal_hugepage_info.c
+++ b/lib/eal/linux/eal_hugepage_info.c
@@ -12,6 +12,7 @@
 #include <stdio.h>
 #include <fnmatch.h>
 #include <inttypes.h>
+#include <mntent.h>
 #include <stdarg.h>
 #include <unistd.h>
 #include <errno.h>
@@ -34,6 +35,7 @@
 #include "eal_private.h"
 #include "eal_internal_cfg.h"
 #include "eal_hugepages.h"
+#include "eal_hugepage_info.h"
 #include "eal_filesystem.h"
 
 static const char sys_dir_path[] = "/sys/kernel/mm/hugepages";
@@ -195,73 +197,110 @@ get_default_hp_size(void)
 	return size;
 }
 
-static int
-get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len)
+int
+eal_hugepage_mount_walk(eal_hugepage_mount_walk_cb *cb, void *cb_arg)
 {
-	enum proc_mount_fieldnames {
-		DEVICE = 0,
-		MOUNTPT,
-		FSTYPE,
-		OPTIONS,
-		_FIELDNAME_MAX
-	};
-	static uint64_t default_size = 0;
-	const char proc_mounts[] = "/proc/mounts";
-	const char hugetlbfs_str[] = "hugetlbfs";
-	const size_t htlbfs_str_len = sizeof(hugetlbfs_str) - 1;
-	const char pagesize_opt[] = "pagesize=";
-	const size_t pagesize_opt_len = sizeof(pagesize_opt) - 1;
-	const char split_tok = ' ';
-	char *splitstr[_FIELDNAME_MAX];
-	char buf[BUFSIZ];
-	int retval = -1;
-	const struct internal_config *internal_conf =
-		eal_get_internal_configuration();
-
-	FILE *fd = fopen(proc_mounts, "r");
-	if (fd == NULL)
-		rte_panic("Cannot open %s\n", proc_mounts);
+	static const char PATH[] = "/proc/mounts";
+	static const char OPTION[] = "pagesize";
+
+	static uint64_t default_size;
+
+	FILE *f = NULL;
+	struct mntent mntent;
+	char strings[PATH_MAX];
+	char *hugepage_sz_str;
+	uint64_t hugepage_sz;
+	bool stopped = false;
+	int ret = -1;
+
+	f = setmntent(PATH, "r");
+	if (f == NULL) {
+		RTE_LOG(ERR, EAL, "%s(): setmntent(%s): %s\n",
+				__func__, PATH, strerror(errno));
+		goto exit;
+	}
 
 	if (default_size == 0)
 		default_size = get_default_hp_size();
 
-	while (fgets(buf, sizeof(buf), fd)){
-		if (rte_strsplit(buf, sizeof(buf), splitstr, _FIELDNAME_MAX,
-				split_tok) != _FIELDNAME_MAX) {
-			RTE_LOG(ERR, EAL, "Error parsing %s\n", proc_mounts);
-			break; /* return NULL */
+	ret = 0;
+	while (getmntent_r(f, &mntent, strings, sizeof(strings)) != NULL) {
+		if (strcmp(mntent.mnt_type, "hugetlbfs") != 0)
+			continue;
+
+		hugepage_sz_str = hasmntopt(&mntent, OPTION);
+		if (hugepage_sz_str != NULL) {
+			hugepage_sz_str += strlen(OPTION) + 1; /* +1 for '=' */
+			hugepage_sz = rte_str_to_size(hugepage_sz_str);
+			if (hugepage_sz == 0) {
+				RTE_LOG(DEBUG, EAL, "Cannot parse hugepage size from '%s' for %s\n",
+						mntent.mnt_opts, mntent.mnt_dir);
+				continue;
+			}
+		} else {
+			RTE_LOG(DEBUG, EAL, "Hugepage filesystem at %s without %s option\n",
+					mntent.mnt_dir, OPTION);
+			hugepage_sz = default_size;
 		}
 
-		/* we have a specified --huge-dir option, only examine that dir */
-		if (internal_conf->hugepage_dir != NULL &&
-				strcmp(splitstr[MOUNTPT], internal_conf->hugepage_dir) != 0)
-			continue;
+		if (cb(mntent.mnt_dir, hugepage_sz, cb_arg) != 0) {
+			stopped = true;
+			break;
+		}
+	}
 
-		if (strncmp(splitstr[FSTYPE], hugetlbfs_str, htlbfs_str_len) == 0){
-			const char *pagesz_str = strstr(splitstr[OPTIONS], pagesize_opt);
+	if (ferror(f) || (!stopped && !feof(f))) {
+		RTE_LOG(ERR, EAL, "%s(): getmntent_r(): %s\n",
+				__func__, strerror(errno));
+		ret = -1;
+		goto exit;
+	}
 
-			/* if no explicit page size, the default page size is compared */
-			if (pagesz_str == NULL){
-				if (hugepage_sz == default_size){
-					strlcpy(hugedir, splitstr[MOUNTPT], len);
-					retval = 0;
-					break;
-				}
-			}
-			/* there is an explicit page size, so check it */
-			else {
-				uint64_t pagesz = rte_str_to_size(&pagesz_str[pagesize_opt_len]);
-				if (pagesz == hugepage_sz) {
-					strlcpy(hugedir, splitstr[MOUNTPT], len);
-					retval = 0;
-					break;
-				}
-			}
-		} /* end if strncmp hugetlbfs */
-	} /* end while fgets */
+exit:
+	if (f != NULL)
+		endmntent(f);
+	return ret;
+}
 
-	fclose(fd);
-	return retval;
+struct match_hugepage_mount_arg {
+	uint64_t hugepage_sz;
+	char *hugedir;
+	int hugedir_len;
+	bool done;
+};
+
+static int
+match_hugepage_mount(const char *path, uint64_t hugepage_sz, void *cb_arg)
+{
+	const struct internal_config *internal_conf =
+		eal_get_internal_configuration();
+	struct match_hugepage_mount_arg *arg = cb_arg;
+
+	/* we have a specified --huge-dir option, only examine that dir */
+	if (internal_conf->hugepage_dir != NULL &&
+			strcmp(path, internal_conf->hugepage_dir) != 0)
+		return 0;
+
+	if (hugepage_sz == arg->hugepage_sz) {
+		strlcpy(arg->hugedir, path, arg->hugedir_len);
+		arg->done = true;
+		return 1;
+	}
+
+	return 0;
+}
+
+static int
+get_hugepage_dir(uint64_t hugepage_sz, char *hugedir, int len)
+{
+	struct match_hugepage_mount_arg arg = {
+		.hugepage_sz = hugepage_sz,
+		.hugedir = hugedir,
+		.hugedir_len = len,
+		.done = false,
+	};
+	int ret = eal_hugepage_mount_walk(match_hugepage_mount, &arg);
+	return ret == 0 && arg.done ? 0 : -1;
 }
 
 /*
diff --git a/lib/eal/linux/eal_hugepage_info.h b/lib/eal/linux/eal_hugepage_info.h
new file mode 100644
index 0000000000..c7efa37c66
--- /dev/null
+++ b/lib/eal/linux/eal_hugepage_info.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2021 NVIDIA CORPORATION & AFFILIATES.
+ */
+
+#ifndef _EAL_HUGEPAGE_INFO_
+#define _EAL_HUGEPAGE_INFO_
+
+#include <stdint.h>
+
+/**
+ * Function called for each hugetlbfs mount point.
+ *
+ * @param path
+ *  Mount point directory.
+ * @param hugepage_sz
+ *  Hugepage size for the mount or default system hugepage size.
+ * @param arg
+ *  User data.
+ *
+ * @return
+ *  0 to continue walking, 1 to stop.
+ */
+typedef int (eal_hugepage_mount_walk_cb)(const char *path, uint64_t hugepage_sz,
+					 void *arg);
+
+/**
+ * Enumerate hugetlbfs mount points.
+ *
+ * @param cb
+ *  Function called for each mount point.
+ * @param cb_arg
+ *  User data passed to the callback.
+ *
+ * @return
+ *  0 on success, negative on failure.
+ */
+int eal_hugepage_mount_walk(eal_hugepage_mount_walk_cb *cb, void *cb_arg);
+
+#endif /* _EAL_HUGEPAGE_INFO_ */
-- 
2.25.1


  reply	other threads:[~2021-09-21  8:17 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-05 12:49 [dpdk-dev] [PATCH 21.11 0/3] eal: add memory pre-allocation from existing files Dmitry Kozlyuk
2021-07-05 12:49 ` [dpdk-dev] [PATCH 21.11 1/3] eal/linux: make hugetlbfs analysis reusable Dmitry Kozlyuk
2021-07-05 12:49 ` [dpdk-dev] [PATCH 21.11 2/3] eal: add memory pre-allocation from existing files Dmitry Kozlyuk
2021-07-05 12:49 ` [dpdk-dev] [PATCH 21.11 3/3] app/test: add allocator performance autotest Dmitry Kozlyuk
2021-07-16 11:08 ` [dpdk-dev] [PATCH 21.11 v2 0/3] eal: add memory pre-allocation from existing files Dmitry Kozlyuk
2021-07-16 11:08   ` [dpdk-dev] [PATCH 21.11 v2 1/3] eal/linux: make hugetlbfs analysis reusable Dmitry Kozlyuk
2021-07-16 11:08   ` [dpdk-dev] [PATCH 21.11 v2 2/3] eal: add memory pre-allocation from existing files Dmitry Kozlyuk
2021-07-16 11:08   ` [dpdk-dev] [PATCH 21.11 v2 3/3] app/test: add allocator performance autotest Dmitry Kozlyuk
2021-08-09  9:45   ` [dpdk-dev] [PATCH 21.11 v2 0/3] eal: add memory pre-allocation from existing files Dmitry Kozlyuk
2021-08-30  8:21     ` Dmitry Kozlyuk
2021-09-14 10:34   ` [dpdk-dev] [PATCH v3 " Dmitry Kozlyuk
2021-09-14 10:34     ` [dpdk-dev] [PATCH v3 1/3] eal/linux: make hugetlbfs analysis reusable Dmitry Kozlyuk
2021-09-14 12:48       ` John Levon
2021-09-14 12:57         ` Dmitry Kozlyuk
2021-09-16 12:08       ` John Levon
2021-09-14 10:34     ` [dpdk-dev] [PATCH v3 2/3] eal: add memory pre-allocation from existing files Dmitry Kozlyuk
2021-09-14 10:34     ` [dpdk-dev] [PATCH v3 3/3] app/test: add allocator performance autotest Dmitry Kozlyuk
2021-09-20 12:52     ` [dpdk-dev] [PATCH v4 0/3] eal: add memory pre-allocation from existing files dkozlyuk
2021-09-20 12:53       ` [dpdk-dev] [PATCH v4 1/3] eal/linux: make hugetlbfs analysis reusable dkozlyuk
2021-09-20 12:53       ` [dpdk-dev] [PATCH v4 2/3] eal: add memory pre-allocation from existing files dkozlyuk
2021-09-20 12:53       ` [dpdk-dev] [PATCH v4 3/3] app/test: add allocator performance autotest dkozlyuk
2021-09-21  8:16       ` [dpdk-dev] [PATCH v5 0/3] eal: add memory pre-allocation from existing files dkozlyuk
2021-09-21  8:16         ` dkozlyuk [this message]
2021-09-22 13:52           ` [dpdk-dev] [PATCH v5 1/3] eal/linux: make hugetlbfs analysis reusable John Levon
2021-10-05 17:36           ` Thomas Monjalon
2021-10-08 15:33             ` John Levon
2021-10-08 15:50               ` Dmitry Kozlyuk
2021-09-21  8:16         ` [dpdk-dev] [PATCH v5 2/3] eal: add memory pre-allocation from existing files dkozlyuk
2021-09-21  8:16         ` [dpdk-dev] [PATCH v5 3/3] app/test: add allocator performance autotest dkozlyuk
2021-10-11  8:56         ` [dpdk-dev] [PATCH v6 0/3] eal: add memory pre-allocation from existing files Dmitry Kozlyuk
2021-10-11  8:56           ` [dpdk-dev] [PATCH v6 1/3] eal/linux: make hugetlbfs analysis reusable Dmitry Kozlyuk
2021-10-13  8:16             ` David Marchand
2021-10-13  9:21               ` Dmitry Kozlyuk
2021-10-11  8:56           ` [dpdk-dev] [PATCH v6 2/3] eal: add memory pre-allocation from existing files Dmitry Kozlyuk
2021-10-12 15:37             ` David Marchand
2021-10-12 15:55               ` Dmitry Kozlyuk
2021-10-12 17:32                 ` David Marchand
2021-10-12 21:09                   ` Dmitry Kozlyuk
2021-10-13 10:18                     ` David Marchand
2021-11-08 14:27                       ` Dmitry Kozlyuk
2021-11-08 17:45                         ` David Marchand
2021-10-11  8:56           ` [dpdk-dev] [PATCH v6 3/3] app/test: add allocator performance autotest Dmitry Kozlyuk
2021-10-12 13:53             ` Aaron Conole
2021-10-12 14:48               ` Dmitry Kozlyuk
2021-10-15 13:47                 ` Aaron Conole
2021-10-11 18:52           ` [dpdk-dev] [PATCH v6 0/3] eal: add memory pre-allocation from existing files Thomas Monjalon
2021-10-11 21:12             ` [dpdk-dev] [dpdk-ci] " Lincoln Lavoie
2021-10-12  6:54               ` Thomas Monjalon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210921081632.858873-2-dkozlyuk@nvidia.com \
    --to=dkozlyuk@oss.nvidia.com \
    --cc=anatoly.burakov@intel.com \
    --cc=dev@dpdk.org \
    --cc=john.levon@nutanix.com \
    --cc=viacheslavo@oss.nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.