From: Dmitry Kozlyuk Date: Mon, 15 Jun 2020 00:43:53 +0000 (+0300) Subject: eal/windows: initialize hugepage info X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=c08bd191b13d;p=dpdk.git eal/windows: initialize hugepage info Add hugepages discovery ("large pages" in Windows terminology) and update documentation for required privilege setup. Only 2MB hugepages are supported and their number is estimated roughly due to the lack or unstable status of suitable OS APIs. Assign myself as maintainer for the implementation file. Signed-off-by: Dmitry Kozlyuk --- diff --git a/MAINTAINERS b/MAINTAINERS index 687d5cd12b..e8ece02405 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -334,6 +334,10 @@ F: lib/librte_eal/windows/ F: lib/librte_eal/rte_eal_exports.def F: doc/guides/windows_gsg/ +Windows memory allocation +M: Dmitry Kozlyuk +F: lib/librte_eal/windows/eal_hugepages.c + Core Libraries -------------- diff --git a/config/meson.build b/config/meson.build index 43ab113106..c1e80de4b7 100644 --- a/config/meson.build +++ b/config/meson.build @@ -268,6 +268,8 @@ if is_windows if cc.get_id() == 'gcc' add_project_arguments('-D__USE_MINGW_ANSI_STDIO', language: 'c') endif + + add_project_link_arguments('-ladvapi32', language: 'c') endif if get_option('b_lto') diff --git a/doc/guides/windows_gsg/run_apps.rst b/doc/guides/windows_gsg/run_apps.rst index ff4c4654fe..9c9f42e4b1 100644 --- a/doc/guides/windows_gsg/run_apps.rst +++ b/doc/guides/windows_gsg/run_apps.rst @@ -4,6 +4,29 @@ Running DPDK Applications ========================= +Grant *Lock pages in memory* Privilege +-------------------------------------- + +Use of hugepages ("large pages" in Windows terminology) requires +``SeLockMemoryPrivilege`` for the user running an application. + +1. Open *Local Security Policy* snap-in, either: + + * Control Panel / Computer Management / Local Security Policy; + * or Win+R, type ``secpol``, press Enter. + +2. Open *Local Policies / User Rights Assignment / Lock pages in memory.* + +3. Add desired users or groups to the list of grantees. + +4. Privilege is applied upon next logon. In particular, if privilege has been + granted to current user, a logoff is required before it is available. + +See `Large-Page Support`_ in MSDN for details. + +.. _Large-Page Support: https://docs.microsoft.com/en-us/windows/win32/memory/large-page-support + + Run the ``helloworld`` Example ------------------------------ diff --git a/lib/librte_eal/windows/eal.c b/lib/librte_eal/windows/eal.c index a81b963664..c371c36fc0 100644 --- a/lib/librte_eal/windows/eal.c +++ b/lib/librte_eal/windows/eal.c @@ -19,8 +19,11 @@ #include #include +#include "eal_hugepages.h" #include "eal_windows.h" +#define MEMSIZE_IF_NO_HUGE_PAGE (64ULL * 1024ULL * 1024ULL) + /* Allow the application to print its usage message too if set */ static rte_usage_hook_t rte_application_usage_hook; @@ -279,6 +282,17 @@ rte_eal_init(int argc, char **argv) if (fctret < 0) exit(1); + if (!internal_config.no_hugetlbfs && (eal_hugepage_info_init() < 0)) { + rte_eal_init_alert("Cannot get hugepage information"); + rte_errno = EACCES; + return -1; + } + + if (internal_config.memory == 0 && !internal_config.force_sockets) { + if (internal_config.no_hugetlbfs) + internal_config.memory = MEMSIZE_IF_NO_HUGE_PAGE; + } + eal_thread_init_master(rte_config.master_lcore); RTE_LCORE_FOREACH_SLAVE(i) { diff --git a/lib/librte_eal/windows/eal_hugepages.c b/lib/librte_eal/windows/eal_hugepages.c new file mode 100644 index 0000000000..61d0dcd3c5 --- /dev/null +++ b/lib/librte_eal/windows/eal_hugepages.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include +#include + +#include "eal_filesystem.h" +#include "eal_hugepages.h" +#include "eal_internal_cfg.h" +#include "eal_windows.h" + +static int +hugepage_claim_privilege(void) +{ + static const wchar_t privilege[] = L"SeLockMemoryPrivilege"; + + HANDLE token; + LUID luid; + TOKEN_PRIVILEGES tp; + int ret = -1; + + if (!OpenProcessToken(GetCurrentProcess(), + TOKEN_ADJUST_PRIVILEGES, &token)) { + RTE_LOG_WIN32_ERR("OpenProcessToken()"); + return -1; + } + + if (!LookupPrivilegeValueW(NULL, privilege, &luid)) { + RTE_LOG_WIN32_ERR("LookupPrivilegeValue(\"%S\")", privilege); + goto exit; + } + + tp.PrivilegeCount = 1; + tp.Privileges[0].Luid = luid; + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + if (!AdjustTokenPrivileges( + token, FALSE, &tp, sizeof(tp), NULL, NULL)) { + RTE_LOG_WIN32_ERR("AdjustTokenPrivileges()"); + goto exit; + } + + ret = 0; + +exit: + CloseHandle(token); + + return ret; +} + +static int +hugepage_info_init(void) +{ + struct hugepage_info *hpi; + unsigned int socket_id; + int ret = 0; + + /* Only one hugepage size available on Windows. */ + internal_config.num_hugepage_sizes = 1; + hpi = &internal_config.hugepage_info[0]; + + hpi->hugepage_sz = GetLargePageMinimum(); + if (hpi->hugepage_sz == 0) + return -ENOTSUP; + + /* Assume all memory on each NUMA node available for hugepages, + * because Windows neither advertises additional limits, + * nor provides an API to query them. + */ + for (socket_id = 0; socket_id < rte_socket_count(); socket_id++) { + ULONGLONG bytes; + unsigned int numa_node; + + numa_node = eal_socket_numa_node(socket_id); + if (!GetNumaAvailableMemoryNodeEx(numa_node, &bytes)) { + RTE_LOG_WIN32_ERR("GetNumaAvailableMemoryNodeEx(%u)", + numa_node); + continue; + } + + hpi->num_pages[socket_id] = bytes / hpi->hugepage_sz; + RTE_LOG(DEBUG, EAL, + "Found %u hugepages of %zu bytes on socket %u\n", + hpi->num_pages[socket_id], hpi->hugepage_sz, socket_id); + } + + /* No hugepage filesystem on Windows. */ + hpi->lock_descriptor = -1; + memset(hpi->hugedir, 0, sizeof(hpi->hugedir)); + + return ret; +} + +int +eal_hugepage_info_init(void) +{ + if (hugepage_claim_privilege() < 0) { + RTE_LOG(ERR, EAL, "Cannot claim hugepage privilege\n"); + return -1; + } + + if (hugepage_info_init() < 0) { + RTE_LOG(ERR, EAL, "Cannot get hugepage information\n"); + return -1; + } + + return 0; +} diff --git a/lib/librte_eal/windows/meson.build b/lib/librte_eal/windows/meson.build index adfc8b9b74..52978e9d7e 100644 --- a/lib/librte_eal/windows/meson.build +++ b/lib/librte_eal/windows/meson.build @@ -6,6 +6,7 @@ subdir('include') sources += files( 'eal.c', 'eal_debug.c', + 'eal_hugepages.c', 'eal_lcore.c', 'eal_log.c', 'eal_thread.c',