eal/windows: initialize hugepage info
authorDmitry Kozlyuk <dmitry.kozliuk@gmail.com>
Mon, 15 Jun 2020 00:43:53 +0000 (03:43 +0300)
committerThomas Monjalon <thomas@monjalon.net>
Mon, 15 Jun 2020 17:30:32 +0000 (19:30 +0200)
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 <dmitry.kozliuk@gmail.com>
MAINTAINERS
config/meson.build
doc/guides/windows_gsg/run_apps.rst
lib/librte_eal/windows/eal.c
lib/librte_eal/windows/eal_hugepages.c [new file with mode: 0644]
lib/librte_eal/windows/meson.build

index 687d5cd..e8ece02 100644 (file)
@@ -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 <dmitry.kozliuk@gmail.com>
+F: lib/librte_eal/windows/eal_hugepages.c
+
 
 Core Libraries
 --------------
index 43ab113..c1e80de 100644 (file)
@@ -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')
index ff4c465..9c9f42e 100644 (file)
@@ -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
 ------------------------------
 
index a81b963..c371c36 100644 (file)
 #include <eal_private.h>
 #include <rte_trace_point.h>
 
+#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 (file)
index 0000000..61d0dcd
--- /dev/null
@@ -0,0 +1,108 @@
+#include <rte_errno.h>
+#include <rte_log.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_os.h>
+
+#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;
+}
index adfc8b9..52978e9 100644 (file)
@@ -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',