[dpdk-dev] [PATCH v3 06/10] eal: introduce memory management wrappers
Ranjit Menon
ranjit.menon at intel.com
Wed Apr 22 02:55:03 CEST 2020
On 4/14/2020 12:44 PM, Dmitry Kozlyuk wrote:
> System meory management is implemented differently for POSIX and
> Windows. Introduce wrapper functions for operations used across DPDK:
>
> * rte_mem_map()
> Create memory mapping for a regular file or a page file (swap).
> This supports mapping to a reserved memory region even on Windows.
>
> * rte_mem_unmap()
> Remove mapping created with rte_mem_map().
>
> * rte_get_page_size()
> Obtain default system page size.
>
> * rte_mem_lock()
> Make arbitrary-sized memory region non-swappable.
>
> Wrappers follow POSIX semantics limited to DPDK tasks, but their
> signatures deliberately differ from POSIX ones to be more safe and
> expressive.
>
> Signed-off-by: Dmitry Kozlyuk <dmitry.kozliuk at gmail.com>
<Snip!>
> diff --git a/lib/librte_eal/windows/eal_memory.c b/lib/librte_eal/windows/eal_memory.c
> new file mode 100644
> index 000000000..5697187ce
> --- /dev/null
> +++ b/lib/librte_eal/windows/eal_memory.c
> @@ -0,0 +1,437 @@
> +#include <io.h>
> +
> +#include <rte_errno.h>
> +#include <rte_memory.h>
> +
> +#include "eal_private.h"
> +#include "eal_windows.h"
> +
> +/* MinGW-w64 headers lack VirtualAlloc2() in some distributions.
> + * Provide a copy of definitions and code to load it dynamically.
> + * Note: definitions are copied verbatim from Microsoft documentation
> + * and don't follow DPDK code style.
> + */
> +#ifndef MEM_PRESERVE_PLACEHOLDER
> +
> +/* https://docs.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-mem_extended_parameter_type */
> +typedef enum MEM_EXTENDED_PARAMETER_TYPE {
> + MemExtendedParameterInvalidType,
> + MemExtendedParameterAddressRequirements,
> + MemExtendedParameterNumaNode,
> + MemExtendedParameterPartitionHandle,
> + MemExtendedParameterMax,
> + MemExtendedParameterUserPhysicalHandle,
> + MemExtendedParameterAttributeFlags
> +} *PMEM_EXTENDED_PARAMETER_TYPE;
> +
> +#define MEM_EXTENDED_PARAMETER_TYPE_BITS 4
> +
> +/* https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-mem_extended_parameter */
> +typedef struct MEM_EXTENDED_PARAMETER {
> + struct {
> + DWORD64 Type : MEM_EXTENDED_PARAMETER_TYPE_BITS;
> + DWORD64 Reserved : 64 - MEM_EXTENDED_PARAMETER_TYPE_BITS;
> + } DUMMYSTRUCTNAME;
> + union {
> + DWORD64 ULong64;
> + PVOID Pointer;
> + SIZE_T Size;
> + HANDLE Handle;
> + DWORD ULong;
> + } DUMMYUNIONNAME;
> +} MEM_EXTENDED_PARAMETER, *PMEM_EXTENDED_PARAMETER;
> +
> +/* https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualalloc2 */
> +typedef PVOID (*VirtualAlloc2_type)(
> + HANDLE Process,
> + PVOID BaseAddress,
> + SIZE_T Size,
> + ULONG AllocationType,
> + ULONG PageProtection,
> + MEM_EXTENDED_PARAMETER *ExtendedParameters,
> + ULONG ParameterCount
> +);
> +
> +/* VirtualAlloc2() flags. */
> +#define MEM_COALESCE_PLACEHOLDERS 0x00000001
> +#define MEM_PRESERVE_PLACEHOLDER 0x00000002
> +#define MEM_REPLACE_PLACEHOLDER 0x00004000
> +#define MEM_RESERVE_PLACEHOLDER 0x00040000
> +
> +/* Named exactly as the function, so that user code does not depend
> + * on it being found at compile time or dynamically.
> + */
> +static VirtualAlloc2_type VirtualAlloc2;
> +
> +int
> +eal_mem_win32api_init(void)
> +{
> + static const char library_name[] = "kernelbase.dll";
> + static const char function[] = "VirtualAlloc2";
> +
> + OSVERSIONINFO info;
> + HMODULE library = NULL;
> + int ret = 0;
> +
> + /* Already done. */
> + if (VirtualAlloc2 != NULL)
> + return 0;
> +
> + /* IsWindows10OrGreater() may also be unavailable. */
> + memset(&info, 0, sizeof(info));
> + info.dwOSVersionInfoSize = sizeof(info);
> + GetVersionEx(&info);
> +
> + /* Checking for Windows 10+ will also detect Windows Server 2016+.
> + * Do not abort, because Windows may report false version depending
> + * on executable manifest, compatibility mode, etc.
> + */
> + if (info.dwMajorVersion < 10)
> + RTE_LOG(DEBUG, EAL, "Windows 10+ or Windows Server 2016+ "
> + "is required for advanced memory features\n");
> +
> + library = LoadLibraryA(library_name);
> + if (library == NULL) {
> + RTE_LOG_WIN32_ERR("LoadLibraryA(\"%s\")", library_name);
> + return -1;
> + }
> +
> + VirtualAlloc2 = (VirtualAlloc2_type)(
> + (void *)GetProcAddress(library, function));
> + if (VirtualAlloc2 == NULL) {
> + RTE_LOG_WIN32_ERR("GetProcAddress(\"%s\", \"%s\")\n",
> + library_name, function);
> + ret = -1;
> + }
> +
> + FreeLibrary(library);
> +
> + return ret;
> +}
> +
> +#else
> +
> +/* Stub in case VirtualAlloc2() is provided by the compiler. */
> +int
> +eal_mem_win32api_init(void)
> +{
> + return 0;
> +}
> +
> +#endif /* no VirtualAlloc2() */
Can you fix this comment to match the #ifndef definition above?
BTW...Why use MEM_PRESERVE_PLACEHOLDER (which is also defined within the
block?)
ranjit m.
More information about the dev
mailing list