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