xref: /dpdk/lib/eal/windows/eal_hugepages.c (revision ae67895b507bb6af22263c79ba0d5c374b396485)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2020 Dmitry Kozlyuk
3  */
4 
5 #include <rte_errno.h>
6 #include <rte_log.h>
7 #include <rte_memory.h>
8 #include <rte_memzone.h>
9 
10 #include "eal_private.h"
11 #include "eal_filesystem.h"
12 #include "eal_hugepages.h"
13 #include "eal_internal_cfg.h"
14 #include "eal_windows.h"
15 
16 static int
hugepage_claim_privilege(void)17 hugepage_claim_privilege(void)
18 {
19 	static const wchar_t privilege[] = L"SeLockMemoryPrivilege";
20 
21 	HANDLE token;
22 	LUID luid;
23 	TOKEN_PRIVILEGES tp;
24 	int ret = -1;
25 
26 	if (!OpenProcessToken(GetCurrentProcess(),
27 			TOKEN_ADJUST_PRIVILEGES, &token)) {
28 		RTE_LOG_WIN32_ERR("OpenProcessToken()");
29 		return -1;
30 	}
31 
32 	if (!LookupPrivilegeValueW(NULL, privilege, &luid)) {
33 		RTE_LOG_WIN32_ERR("LookupPrivilegeValue(\"%S\")", privilege);
34 		goto exit;
35 	}
36 
37 	tp.PrivilegeCount = 1;
38 	tp.Privileges[0].Luid = luid;
39 	tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
40 
41 	if (!AdjustTokenPrivileges(
42 			token, FALSE, &tp, sizeof(tp), NULL, NULL)) {
43 		RTE_LOG_WIN32_ERR("AdjustTokenPrivileges()");
44 		goto exit;
45 	}
46 
47 	/* AdjustTokenPrivileges() may succeed with ERROR_NOT_ALL_ASSIGNED. */
48 	if (GetLastError() != ERROR_SUCCESS)
49 		goto exit;
50 
51 	ret = 0;
52 
53 exit:
54 	CloseHandle(token);
55 
56 	return ret;
57 }
58 
59 static int
hugepage_info_init(void)60 hugepage_info_init(void)
61 {
62 	struct hugepage_info *hpi;
63 	unsigned int socket_id;
64 	int ret = 0;
65 	struct internal_config *internal_conf =
66 		eal_get_internal_configuration();
67 
68 	/* Only one hugepage size available on Windows. */
69 	internal_conf->num_hugepage_sizes = 1;
70 	hpi = &internal_conf->hugepage_info[0];
71 
72 	hpi->hugepage_sz = GetLargePageMinimum();
73 	if (hpi->hugepage_sz == 0)
74 		return -ENOTSUP;
75 
76 	/* Assume all memory on each NUMA node available for hugepages,
77 	 * because Windows neither advertises additional limits,
78 	 * nor provides an API to query them.
79 	 */
80 	for (socket_id = 0; socket_id < rte_socket_count(); socket_id++) {
81 		ULONGLONG bytes;
82 		unsigned int numa_node;
83 
84 		numa_node = eal_socket_numa_node(socket_id);
85 		if (!GetNumaAvailableMemoryNodeEx(numa_node, &bytes)) {
86 			RTE_LOG_WIN32_ERR("GetNumaAvailableMemoryNodeEx(%u)",
87 				numa_node);
88 			continue;
89 		}
90 
91 		hpi->num_pages[socket_id] = bytes / hpi->hugepage_sz;
92 		EAL_LOG(DEBUG,
93 			"Found %u hugepages of %zu bytes on socket %u",
94 			hpi->num_pages[socket_id], hpi->hugepage_sz, socket_id);
95 	}
96 
97 	/* No hugepage filesystem on Windows. */
98 	hpi->lock_descriptor = -1;
99 	memset(hpi->hugedir, 0, sizeof(hpi->hugedir));
100 
101 	return ret;
102 }
103 
104 int
eal_hugepage_info_init(void)105 eal_hugepage_info_init(void)
106 {
107 	if (hugepage_claim_privilege() < 0) {
108 		EAL_LOG(ERR,
109 			"Cannot claim hugepage privilege, check large-page support privilege");
110 		return -1;
111 	}
112 
113 	if (hugepage_info_init() < 0) {
114 		EAL_LOG(ERR, "Cannot discover available hugepages");
115 		return -1;
116 	}
117 
118 	return 0;
119 }
120