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