@@ -263,6 +263,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')
@@ -111,23 +111,3 @@ Depending on the distribution, paths in this file may need adjustments.
meson --cross-file config/x86/meson_mingw.txt -Dexamples=helloworld build
ninja -C build
-
-
-Run the helloworld example
-==========================
-
-Navigate to the examples in the build directory and run `dpdk-helloworld.exe`.
-
-.. code-block:: console
-
- cd C:\Users\me\dpdk\build\examples
- dpdk-helloworld.exe
- hello from core 1
- hello from core 3
- hello from core 0
- hello from core 2
-
-Note for MinGW-w64: applications are linked to ``libwinpthread-1.dll``
-by default. To run the example, either add toolchain executables directory
-to the PATH or copy the library to the working directory.
-Alternatively, static linking may be used (mind the LGPLv2.1 license).
@@ -12,3 +12,4 @@ Getting Started Guide for Windows
intro
build_dpdk
+ run_apps
new file mode 100644
@@ -0,0 +1,47 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2020 Dmitry Kozlyuk
+
+Running DPDK Applications
+=========================
+
+Grant *Lock pages in memory* Privilege
+--------------------------------------
+
+Use of hugepages ("large pages" in Windows terminolocy) 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
+------------------------------
+
+Navigate to the examples in the build directory and run `dpdk-helloworld.exe`.
+
+.. code-block:: console
+
+ cd C:\Users\me\dpdk\build\examples
+ dpdk-helloworld.exe
+ hello from core 1
+ hello from core 3
+ hello from core 0
+ hello from core 2
+
+Note for MinGW-w64: applications are linked to ``libwinpthread-1.dll``
+by default. To run the example, either add toolchain executables directory
+to the PATH or copy the library to the working directory.
+Alternatively, static linking may be used (mind the LGPLv2.1 license).
@@ -18,8 +18,11 @@
#include <eal_options.h>
#include <eal_private.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;
@@ -242,6 +245,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) {
new file mode 100644
@@ -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 in 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 in 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;
+}
@@ -6,6 +6,7 @@ subdir('include')
sources += files(
'eal.c',
'eal_debug.c',
+ 'eal_hugepages.c',
'eal_lcore.c',
'eal_thread.c',
'getopt.c',