From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124])
	by inbox.dpdk.org (Postfix) with ESMTP id B6E51A0C4C;
	Fri, 16 Jul 2021 13:08:32 +0200 (CEST)
Received: from [217.70.189.124] (localhost [127.0.0.1])
	by mails.dpdk.org (Postfix) with ESMTP id C055641357;
	Fri, 16 Jul 2021 13:08:31 +0200 (CEST)
Received: from NAM02-BN1-obe.outbound.protection.outlook.com
 (mail-bn1nam07on2077.outbound.protection.outlook.com [40.107.212.77])
 by mails.dpdk.org (Postfix) with ESMTP id CEE804134E
 for <dev@dpdk.org>; Fri, 16 Jul 2021 13:08:29 +0200 (CEST)
ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;
 b=VKG0fqmWK6et7110khkjrz4Ra1gc49CZBTkqTplIpdGK3YYEJOFsHVITpdw7kTzqbeXYGAgNMKC6h7HNQ/MqyIjSVW1Rvi6kOdD/pIV9F6arf2yi2aF1yesy144BQcpSnyLB1ywcw9+kwtbW5saIMK9QbijHFXgUlHfcYqojPI9Rrvoeib5SM0ryN12xs6I3x4u49JfFm1+3yqZNeGFh20383Bu4mz4obNHQIyhpEojknaJRpU4Si0bMzxGpjBjc7sHwYBE3BkKPGb0n/Nfjt+3MRfJ69JJPeHMXPz+AaB7ROndtfYv6FQif+7R8WAT5z6XdKRu51+62SYj8CoBxng==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; 
 s=arcselector9901;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=EzAhVRISwFsdw0J26/1ykpw8XFGEUa4Wvu8iDiW4fws=;
 b=m4irIJSGmOni48wNmdfpmSpjG05Ml1L3i42RlRVzfmeOgMR7RzVd+N44yXHJ0xoP+KwfHwyDx+fN0LyvIjLwwP7IDyk5xVbH1qis2Ma655w6Z/23l45w3/z+TR3UsSSU/NQpPoECVriVDvWa+RPMEb2vlsnq8cr15q4h46U8hqhd9qr18sFi1TcpRCRalbXDZbdxs04YyCmySn8QgyMjb8RPYT5vQYEOLG1xdinnTBJs2rPseSGCrCL/pulreeZ2oSxIQrwTo8IvNOI0r7tGQReHWcRmwFyhSyp8MrAoEzCZ0diq31HGB3bVRABFwJU697e7TqJ2jA3cxCBoNjlTMw==
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is
 216.228.112.34) smtp.rcpttodomain=intel.com smtp.mailfrom=nvidia.com;
 dmarc=pass (p=quarantine sp=none pct=100) action=none header.from=nvidia.com; 
 dkim=none (message not signed); arc=none
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com;
 s=selector2;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=EzAhVRISwFsdw0J26/1ykpw8XFGEUa4Wvu8iDiW4fws=;
 b=qzNmMe3RclX8kCyGBE5iTJxUOlbN97n5+zqzivZEx/6eJXZGy1JaNStpSREuY9DqskrI9cXNc5bYDsn1HRpyMmlcDPVZVo3MrIg5v0K7MHb7uhSvwTfQIYVUZozamiBD0gWewTtCa7eSYwO47pEkZnkwPZ3WMmeJ9lOo9wF3qKo3x6BpZ/WTWrgbazkjwLW5RlXufHabas0DC4auHAQB6VJO47z02lL8WwMCxyyUQzHD+DX5aRDi4QWzkxyMyHz6MwEja6OsWBrX9APEoH+61bWHd+A0PQOLMbdOLOIYn1JbV38atqAm/HXISdBG2XRu/+Xl7Ea3U/BzkrOSlZPM7Q==
Received: from DM3PR12CA0082.namprd12.prod.outlook.com (2603:10b6:0:57::26) by
 BYAPR12MB2694.namprd12.prod.outlook.com (2603:10b6:a03:69::31) with
 Microsoft
 SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id
 15.20.4308.23; Fri, 16 Jul 2021 11:08:26 +0000
Received: from DM6NAM11FT027.eop-nam11.prod.protection.outlook.com
 (2603:10b6:0:57:cafe::fe) by DM3PR12CA0082.outlook.office365.com
 (2603:10b6:0:57::26) with Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4331.21 via Frontend
 Transport; Fri, 16 Jul 2021 11:08:26 +0000
X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.112.34)
 smtp.mailfrom=nvidia.com; intel.com; dkim=none (message not signed)
 header.d=none;intel.com; dmarc=pass action=none header.from=nvidia.com;
Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates
 216.228.112.34 as permitted sender) receiver=protection.outlook.com;
 client-ip=216.228.112.34; helo=mail.nvidia.com;
Received: from mail.nvidia.com (216.228.112.34) by
 DM6NAM11FT027.mail.protection.outlook.com (10.13.172.205) with Microsoft SMTP
 Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id
 15.20.4331.21 via Frontend Transport; Fri, 16 Jul 2021 11:08:25 +0000
Received: from nvidia.com (172.20.187.5) by HQMAIL107.nvidia.com
 (172.20.187.13) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 16 Jul
 2021 11:08:24 +0000
From: Dmitry Kozlyuk <dkozlyuk@nvidia.com>
To: <dev@dpdk.org>
CC: Anatoly Burakov <anatoly.burakov@intel.com>, Viacheslav Ovsiienko
 <viacheslavo@nvidia.com>
Date: Fri, 16 Jul 2021 14:08:04 +0300
Message-ID: <20210716110806.2566788-2-dkozlyuk@nvidia.com>
X-Mailer: git-send-email 2.25.1
In-Reply-To: <20210716110806.2566788-1-dkozlyuk@nvidia.com>
References: <20210705124950.902701-1-dkozlyuk@nvidia.com>
 <20210716110806.2566788-1-dkozlyuk@nvidia.com>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Content-Type: text/plain
X-Originating-IP: [172.20.187.5]
X-ClientProxiedBy: HQMAIL111.nvidia.com (172.20.187.18) To
 HQMAIL107.nvidia.com (172.20.187.13)
X-EOPAttributedMessage: 0
X-MS-PublicTrafficType: Email
X-MS-Office365-Filtering-Correlation-Id: 9a76be90-57ed-464a-2740-08d9484a08a9
X-MS-TrafficTypeDiagnostic: BYAPR12MB2694:
X-Microsoft-Antispam-PRVS: <BYAPR12MB2694C2225AFF20F9FBFE7080B9119@BYAPR12MB2694.namprd12.prod.outlook.com>
X-MS-Oob-TLC-OOBClassifiers: OLM:5236;
X-MS-Exchange-SenderADCheck: 1
X-MS-Exchange-AntiSpam-Relay: 0
X-Microsoft-Antispam: BCL:0;
X-Microsoft-Antispam-Message-Info: dd8GbvQsx2ttqhFzpcCobHeXQhskkuSAGjrs5VUhDv08oavs7jagDCndM3TxXmeteMZ7JoKbyKWljZg8YLALkx/ASo8fFaBtshWOtqHBfHQiEtONfpBvA8ZhpJdkzkMRPatKJwE3BBK1Hds+jTwaMfk/m865IOQoqWczaWyWZWzWhtDDe6A7U3L6J/BIBwS0bUO24sp/jXHDvLEeBw6Rq+Xfs84qyRLrWI350uawlzk6j/zVEM3MLtatT2POEDJqMAti7hQZtKjc4D5Pob4vFEA3XOliSEHaSMhGC+SpnwrbfcZbPA5RwxYQyn6nv1R63+mo+sycOz1/7IuUzKbNE3qQk/ef94K0YJKX1jcG1jmcYgbcVE4nNrTaWPQvbj1VsxYN7Jbz2FZJ8J5OKWKhJXJ8yZURlXQqWIkrv9Aaa58fOf31XxVtnG8Qt6yRebojrAD83olgeJmdXNkfEFdRs0fJtINfXuX0ryDti6lC9Cx2Kl5NmQrbFQALsde5M/fSA7UryBiFpFywKr/vAGDy2e5uylZEiIWemVmV+cF+X4Mj78kdv8VStHZh46TxjSlSZ8w5BBNVWqxDu03+uQcro1NMF0MhcCgmHWM8HkvcpNEL0jSK+I6Z/f2/lHZbAblOMzGkpEt5BJNKdNJ5Fsm9bh6lg8aZWfTvaSMP3v5BCTlBE04uJr5qaq6uwz0HR3bf1pbRX4jbFcbJZaeg27V3zKNOBNdJTb/sTLTrukhhddU=
X-Forefront-Antispam-Report: CIP:216.228.112.34; CTRY:US; LANG:en; SCL:1; SRV:;
 IPV:NLI; SFV:NSPM; H:mail.nvidia.com; PTR:schybrid03.nvidia.com; CAT:NONE;
 SFS:(4636009)(39860400002)(396003)(346002)(136003)(376002)(36840700001)(46966006)(34020700004)(6286002)(82310400003)(2906002)(1076003)(6916009)(70206006)(70586007)(478600001)(107886003)(6666004)(336012)(54906003)(2616005)(7696005)(83380400001)(36906005)(36756003)(356005)(426003)(4326008)(55016002)(5660300002)(82740400003)(316002)(86362001)(47076005)(186003)(26005)(8676002)(16526019)(36860700001)(8936002)(7636003);
 DIR:OUT; SFP:1101; 
X-OriginatorOrg: Nvidia.com
X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Jul 2021 11:08:25.8309 (UTC)
X-MS-Exchange-CrossTenant-Network-Message-Id: 9a76be90-57ed-464a-2740-08d9484a08a9
X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a
X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a; Ip=[216.228.112.34];
 Helo=[mail.nvidia.com]
X-MS-Exchange-CrossTenant-AuthSource: DM6NAM11FT027.eop-nam11.prod.protection.outlook.com
X-MS-Exchange-CrossTenant-AuthAs: Anonymous
X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem
X-MS-Exchange-Transport-CrossTenantHeadersStamped: BYAPR12MB2694
Subject: [dpdk-dev] [PATCH 21.11 v2 1/3] eal/linux: make hugetlbfs analysis
 reusable
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org
Sender: "dev" <dev-bounces@dpdk.org>

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..a090c0a5b5 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 *m;
+	char *hugepage_sz_str;
+	uint64_t hugepage_sz;
+	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;
+	do {
+		m = getmntent(f);
+		if (m == NULL)
+			break;
 
-		/* 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)
+		if (strcmp(m->mnt_fsname, "hugetlbfs") != 0)
 			continue;
 
-		if (strncmp(splitstr[FSTYPE], hugetlbfs_str, htlbfs_str_len) == 0){
-			const char *pagesz_str = strstr(splitstr[OPTIONS], pagesize_opt);
-
-			/* 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;
-				}
+		hugepage_sz_str = hasmntopt(m, 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",
+						m->mnt_opts, m->mnt_dir);
+				continue;
 			}
-		} /* end if strncmp hugetlbfs */
-	} /* end while fgets */
+		} else {
+			RTE_LOG(DEBUG, EAL, "Hugepage filesystem at %s without %s option\n",
+					m->mnt_dir, OPTION);
+			hugepage_sz = default_size;
+		}
 
-	fclose(fd);
-	return retval;
+		if (cb(m->mnt_dir, hugepage_sz, cb_arg) != 0)
+			break;
+	} while (m != NULL);
+
+	if (ferror(f) && !feof(f)) {
+		RTE_LOG(DEBUG, EAL, "%s(): getmntent(): %s\n",
+				__func__, strerror(errno));
+		ret = -1;
+		goto exit;
+	}
+
+exit:
+	if (f != NULL)
+		endmntent(f);
+	return ret;
+}
+
+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