[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