Re: [PATCH v2 1/2] build: fix list_dir_globs failure in MSYS2

2023-10-24 Thread Ric Li



On 2023/10/11 23:34, Bruce Richardson wrote:
> On Wed, Oct 11, 2023 at 05:27:22PM +0200, Thomas Monjalon wrote:
>> 20/09/2023 16:18, Ric Li:
>>> When running 'meson setup' on Windows with MSYS2,
>>> "list-dir-globs.py * failed with status 1".
>>
>> We don't know why it is failing?
>> What about other usages of list_dir_globs in drivers and lib?

Looks lile MSYS2 shell expands this wildcard automatically
before passing it to the child process.

I print the args in list-dir-globs.py and found that args are
the expanded dir names, so the len(sys.argv) is larger than 2,
which makes this script fail. The '*/*' arg in drivers/meson.build
works well just as expected, and no '*' used in lib.

This is from MSYS2 documentation:
"Windows programs parse the command line themselves, it isn't parsed for them by
the calling process, as on Linux. This means that if wildcards (glob patterns) 
are
to be accepted by the program, it has to be able to expand them somehow. 
MinGW-w64
supplies the correct start-up code, so it happens automatically, in a manner
compatible with MSVC-compiled programs. If undesirable, the behavior can be
disabled at program build."

I think this fix is not needed if we can find a way to disable the 
auto-expanding
behaviour of the MSYS2 program. I've tried the runtime way by setting
"MSYS=noglob" envvar but not working here...

>>
>>> Avoid using globbing to get components for app build
>>> since they are already listed in the meson file.
>>
>> I don't understand the logic.
>>
>>> +disable_apps = ',' + get_option('disable_apps')
>>> +disable_apps = run_command(list_dir_globs, disable_apps, check: 
>>> true).stdout().split()
>>
>> This could fail.>>
>>> +
>>> +enable_apps = ',' + get_option('enable_apps')
>>> +enable_apps = run_command(list_dir_globs, enable_apps, check: 
>>> true).stdout().split()
>>> +if enable_apps.length() == 0
>>> +enable_apps = apps
>>> +endif
>>
>> If nothing is enabled, we enable all?
>>
> Yes, if the enable_apps list is empty we should enable everything.
> However, on reviewing the v2, I missed the fact that this patch is
> removing the expansion of the disable_apps value.> 
> Given your comment, this check can probably also be improved by checking
> the get_option('enable_apps') length, rather than the expanded version.
> 
> /Bruce


[PATCH] windows/virt2phys: fix block MDL not updated

2023-09-11 Thread Ric Li
The virt2phys_translate function previously scanned existing blocks,
returning the physical address from the stored MDL info if present.
This method was problematic when a virtual address pointed to a freed
and reallocated memory segment, potentially changing the physical
address mapping. Yet, virt2phys_translate would consistently return
the originally stored physical address, which could be invalid.

This issue surfaced when allocating a memory region larger than 2MB
using rte_malloc. This action would allocate a new memory segment
and use virt2phy to set the iova. The driver would store the MDL
and lock the pages initially. When this region was freed, the memory
segment used as a whole page could be freed, invalidating the virtual
to physical mapping. It then needed to be deleted from the driver's
block MDL info. Before this fix, the driver would only return the
initial physical address, leading to illegal iova for some pages when
allocating a new memory region of the same size.

To address this, a refresh function has been added. If a block with the
same base address is detected in the driver's context, the MDL's
physical address is compared with the real physical address.
If they don't match, the MDL within the block is released and rebuilt
to store the correct mapping.

Also refine the access of MDL StartVa field and fix the printing
of PVOID type.

Signed-off-by: Ric Li 
---
 windows/virt2phys/virt2phys.c   |  7 ++--
 windows/virt2phys/virt2phys_logic.c | 60 +
 2 files changed, 57 insertions(+), 10 deletions(-)

diff --git a/windows/virt2phys/virt2phys.c b/windows/virt2phys/virt2phys.c
index f4d5298..b64a13d 100644
--- a/windows/virt2phys/virt2phys.c
+++ b/windows/virt2phys/virt2phys.c
@@ -182,7 +182,7 @@ virt2phys_device_EvtIoInCallerContext(WDFDEVICE device, 
WDFREQUEST request)
 {
WDF_REQUEST_PARAMETERS params;
ULONG code;
-   PVOID *virt;
+   PVOID *pvirt, virt;
PHYSICAL_ADDRESS *phys;
size_t size;
NTSTATUS status;
@@ -207,12 +207,13 @@ virt2phys_device_EvtIoInCallerContext(WDFDEVICE device, 
WDFREQUEST request)
}
 
status = WdfRequestRetrieveInputBuffer(
-   request, sizeof(*virt), (PVOID *)&virt, &size);
+   request, sizeof(*pvirt), (PVOID *)&pvirt, &size);
if (!NT_SUCCESS(status)) {
TraceWarning("Retrieving input buffer: %!STATUS!", status);
WdfRequestComplete(request, status);
return;
}
+   virt = *pvirt;
 
status = WdfRequestRetrieveOutputBuffer(
request, sizeof(*phys), (PVOID *)&phys, &size);
@@ -222,7 +223,7 @@ virt2phys_device_EvtIoInCallerContext(WDFDEVICE device, 
WDFREQUEST request)
return;
}
 
-   status = virt2phys_translate(*virt, phys);
+   status = virt2phys_translate(virt, phys);
if (NT_SUCCESS(status))
WdfRequestSetInformation(request, sizeof(*phys));
 
diff --git a/windows/virt2phys/virt2phys_logic.c 
b/windows/virt2phys/virt2phys_logic.c
index e3ff293..5bf6734 100644
--- a/windows/virt2phys/virt2phys_logic.c
+++ b/windows/virt2phys/virt2phys_logic.c
@@ -40,7 +40,7 @@ virt2phys_block_create(PMDL mdl)
 static void
 virt2phys_block_free(struct virt2phys_block *block, BOOLEAN unmap)
 {
-   TraceInfo("VA = %p, unmap = %!bool!", block->mdl->StartVa, unmap);
+   TraceInfo("VA = %p, unmap = %!bool!", MmGetMdlBaseVa(block->mdl), 
unmap);
 
if (unmap)
MmUnlockPages(block->mdl);
@@ -114,7 +114,7 @@ virt2phys_process_find_block(struct virt2phys_process 
*process, PVOID virt)
 
for (node = process->blocks.Next; node != NULL; node = node->Next) {
cur = CONTAINING_RECORD(node, struct virt2phys_block, next);
-   if (cur->mdl->StartVa == virt)
+   if (MmGetMdlBaseVa(cur->mdl) == virt)
return cur;
}
return NULL;
@@ -182,7 +182,7 @@ virt2phys_process_cleanup(HANDLE process_id)
 }
 
 static struct virt2phys_block *
-virt2phys_find_block(HANDLE process_id, void *virt,
+virt2phys_find_block(HANDLE process_id, PVOID virt,
struct virt2phys_process **process)
 {
PLIST_ENTRY node;
@@ -214,7 +214,7 @@ virt2phys_add_block(struct virt2phys_process *process,
struct virt2phys_process *existing;
size_t size;
 
-   TraceInfo("ID = %p, VA = %p", process->id, block->mdl->StartVa);
+   TraceInfo("ID = %p, VA = %p", process->id, MmGetMdlBaseVa(block->mdl));
 
existing = virt2phys_process_find(process->id);
*process_exists = existing != NULL;
@@ -250,7 +250,7 @@ virt2phys_add_block(struct virt2phys_process *process,
 }
 
 static NTSTATUS
-virt2phys_query_memory(void *virt, void **base, size_t *size)
+virt2ph

[PATCH v2] windows/virt2phys: fix block MDL not updated

2023-09-11 Thread Ric Li
The virt2phys_translate function previously scanned existing blocks,
returning the physical address from the stored MDL info if present.
This method was problematic when a virtual address pointed to a freed
and reallocated memory segment, potentially changing the physical
address mapping. Yet, virt2phys_translate would consistently return
the originally stored physical address, which could be invalid.

This issue surfaced when allocating a memory region larger than 2MB
using rte_malloc. This action would allocate a new memory segment
and use virt2phy to set the iova. The driver would store the MDL
and lock the pages initially. When this region was freed, the memory
segment used as a whole page could be freed, invalidating the virtual
to physical mapping. It then needed to be deleted from the driver's
block MDL info. Before this fix, the driver would only return the
initial physical address, leading to illegal iova for some pages when
allocating a new memory region of the same size.

To address this, a refresh function has been added. If a block with the
same base address is detected in the driver's context, the MDL's
physical address is compared with the real physical address.
If they don't match, the MDL within the block is released and rebuilt
to store the correct mapping.

Also fix the printing of PVOID type.

Signed-off-by: Ric Li 
---
 windows/virt2phys/virt2phys.c   |  7 ++--
 windows/virt2phys/virt2phys_logic.c | 54 ++---
 2 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/windows/virt2phys/virt2phys.c b/windows/virt2phys/virt2phys.c
index f4d5298..b64a13d 100644
--- a/windows/virt2phys/virt2phys.c
+++ b/windows/virt2phys/virt2phys.c
@@ -182,7 +182,7 @@ virt2phys_device_EvtIoInCallerContext(WDFDEVICE device, 
WDFREQUEST request)
 {
WDF_REQUEST_PARAMETERS params;
ULONG code;
-   PVOID *virt;
+   PVOID *pvirt, virt;
PHYSICAL_ADDRESS *phys;
size_t size;
NTSTATUS status;
@@ -207,12 +207,13 @@ virt2phys_device_EvtIoInCallerContext(WDFDEVICE device, 
WDFREQUEST request)
}
 
status = WdfRequestRetrieveInputBuffer(
-   request, sizeof(*virt), (PVOID *)&virt, &size);
+   request, sizeof(*pvirt), (PVOID *)&pvirt, &size);
if (!NT_SUCCESS(status)) {
TraceWarning("Retrieving input buffer: %!STATUS!", status);
WdfRequestComplete(request, status);
return;
}
+   virt = *pvirt;
 
status = WdfRequestRetrieveOutputBuffer(
request, sizeof(*phys), (PVOID *)&phys, &size);
@@ -222,7 +223,7 @@ virt2phys_device_EvtIoInCallerContext(WDFDEVICE device, 
WDFREQUEST request)
return;
}
 
-   status = virt2phys_translate(*virt, phys);
+   status = virt2phys_translate(virt, phys);
if (NT_SUCCESS(status))
WdfRequestSetInformation(request, sizeof(*phys));
 
diff --git a/windows/virt2phys/virt2phys_logic.c 
b/windows/virt2phys/virt2phys_logic.c
index e3ff293..8529a2b 100644
--- a/windows/virt2phys/virt2phys_logic.c
+++ b/windows/virt2phys/virt2phys_logic.c
@@ -182,7 +182,7 @@ virt2phys_process_cleanup(HANDLE process_id)
 }
 
 static struct virt2phys_block *
-virt2phys_find_block(HANDLE process_id, void *virt,
+virt2phys_find_block(HANDLE process_id, PVOID virt,
struct virt2phys_process **process)
 {
PLIST_ENTRY node;
@@ -250,7 +250,7 @@ virt2phys_add_block(struct virt2phys_process *process,
 }
 
 static NTSTATUS
-virt2phys_query_memory(void *virt, void **base, size_t *size)
+virt2phys_query_memory(PVOID virt, PVOID *base, size_t *size)
 {
MEMORY_BASIC_INFORMATION info;
SIZE_T info_size;
@@ -321,7 +321,7 @@ virt2phys_check_memory(PMDL mdl)
 }
 
 static NTSTATUS
-virt2phys_lock_memory(void *virt, size_t size, PMDL *mdl)
+virt2phys_lock_memory(PVOID virt, size_t size, PMDL *mdl)
 {
*mdl = IoAllocateMdl(virt, (ULONG)size, FALSE, FALSE, NULL);
if (*mdl == NULL)
@@ -346,12 +346,53 @@ virt2phys_unlock_memory(PMDL mdl)
IoFreeMdl(mdl);
 }
 
+static NTSTATUS
+virt2phys_block_refresh(struct virt2phys_block *block, PVOID base, size_t size)
+{
+   NTSTATUS status;
+   PMDL mdl = block->mdl;
+
+   /*
+* Check if we need to refresh MDL in block.
+* The virtual to physical memory mapping may be changed when the
+* virtual memory region is freed by the user process and malloc again,
+* then we need to unlock the physical memory and lock again to
+* refresh the MDL information stored in block.
+*/
+   PHYSICAL_ADDRESS block_phys, real_phys;
+
+   block_phys = virt2phys_block_translate(block, base);
+   real_phys = MmGetPhysicalAddress(base);
+
+   if (block_phys.QuadPart == real_phys.QuadPart)
+   /* No need to refresh block. */
+   return STATUS_SUC

[PATCH v3] windows/virt2phys: fix block MDL not updated

2023-09-12 Thread Ric Li
The virt2phys_translate function previously scanned existing blocks,
returning the physical address from the stored MDL info if present.
This method was problematic when a virtual address pointed to a freed
and reallocated memory segment, potentially changing the physical
address mapping. Yet, virt2phys_translate would consistently return
the originally stored physical address, which could be invalid.

This issue surfaced when allocating a memory region larger than 2MB
using rte_malloc. This action would allocate a new memory segment
and use virt2phy to set the IOVA. The driver would store the MDL
and lock the pages initially. When this region was freed, the memory
segment used as a whole page could be freed, invalidating the virtual
to physical mapping. Before this fix, the driver would only return the
initial physical address, leading to illegal IOVA for some pages when
allocating a new memory region larger than the hugepage size (2MB).

To address this, a function to check block physical address has been
added. If a block with the same base address is detected in the
driver's context, the MDL's physical address is compared with the real
physical address. If they don't match, the block is removed and a new
one is created to store the correct mapping. To make the removal action
clear, the list to store MDL blocks is chenged to a double linked list.

Also fix the printing of PVOID type.

Bugzilla ID: 1201
Bugzilla ID: 1213

Signed-off-by: Ric Li 
---
v3:
* Change refresh action to block removal
* Change block list to double linked list

v2:
* Revert wrong usage of MmGetMdlStartVa

 windows/virt2phys/virt2phys.c   |  7 +--
 windows/virt2phys/virt2phys_logic.c | 70 ++---
 2 files changed, 57 insertions(+), 20 deletions(-)

diff --git a/windows/virt2phys/virt2phys.c b/windows/virt2phys/virt2phys.c
index f4d5298..b64a13d 100644
--- a/windows/virt2phys/virt2phys.c
+++ b/windows/virt2phys/virt2phys.c
@@ -182,7 +182,7 @@ virt2phys_device_EvtIoInCallerContext(WDFDEVICE device, 
WDFREQUEST request)
 {
WDF_REQUEST_PARAMETERS params;
ULONG code;
-   PVOID *virt;
+   PVOID *pvirt, virt;
PHYSICAL_ADDRESS *phys;
size_t size;
NTSTATUS status;
@@ -207,12 +207,13 @@ virt2phys_device_EvtIoInCallerContext(WDFDEVICE device, 
WDFREQUEST request)
}
 
status = WdfRequestRetrieveInputBuffer(
-   request, sizeof(*virt), (PVOID *)&virt, &size);
+   request, sizeof(*pvirt), (PVOID *)&pvirt, &size);
if (!NT_SUCCESS(status)) {
TraceWarning("Retrieving input buffer: %!STATUS!", status);
WdfRequestComplete(request, status);
return;
}
+   virt = *pvirt;
 
status = WdfRequestRetrieveOutputBuffer(
request, sizeof(*phys), (PVOID *)&phys, &size);
@@ -222,7 +223,7 @@ virt2phys_device_EvtIoInCallerContext(WDFDEVICE device, 
WDFREQUEST request)
return;
}
 
-   status = virt2phys_translate(*virt, phys);
+   status = virt2phys_translate(virt, phys);
if (NT_SUCCESS(status))
WdfRequestSetInformation(request, sizeof(*phys));
 
diff --git a/windows/virt2phys/virt2phys_logic.c 
b/windows/virt2phys/virt2phys_logic.c
index e3ff293..531f08c 100644
--- a/windows/virt2phys/virt2phys_logic.c
+++ b/windows/virt2phys/virt2phys_logic.c
@@ -12,13 +12,13 @@
 struct virt2phys_process {
HANDLE id;
LIST_ENTRY next;
-   SINGLE_LIST_ENTRY blocks;
+   LIST_ENTRY blocks;
ULONG64 memory;
 };
 
 struct virt2phys_block {
PMDL mdl;
-   SINGLE_LIST_ENTRY next;
+   LIST_ENTRY next;
 };
 
 static struct virt2phys_params g_params;
@@ -69,24 +69,28 @@ virt2phys_process_create(HANDLE process_id)
struct virt2phys_process *process;
 
process = ExAllocatePoolZero(NonPagedPool, sizeof(*process), 'pp2v');
-   if (process != NULL)
+   if (process != NULL) {
process->id = process_id;
+   InitializeListHead(&process->blocks);
+   }
+
return process;
 }
 
 static void
 virt2phys_process_free(struct virt2phys_process *process, BOOLEAN unmap)
 {
-   PSINGLE_LIST_ENTRY node;
+   PLIST_ENTRY node, next;
struct virt2phys_block *block;
 
TraceInfo("ID = %p, unmap = %!bool!", process->id, unmap);
 
-   node = process->blocks.Next;
-   while (node != NULL) {
+   for (node = process->blocks.Flink; node != &process->blocks; node = 
next) {
+   next = node->Flink;
block = CONTAINING_RECORD(node, struct virt2phys_block, next);
-   node = node->Next;
-   virt2phys_block_free(block, unmap);
+   RemoveEntryList(&block->next);
+
+   virt2phys_block_free(block, TRUE);
}
 
ExFreeP

[PATCH 1/2] build: fix list_dir_globs failure in MSYS2

2023-09-16 Thread Ric Li
When running 'meson build' in MSYS2,
"list-dir-globs.py * failed with status 1".

Signed-off-by: Ric Li 
---
 app/meson.build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/meson.build b/app/meson.build
index e4bf5c531c..73e5138301 100644
--- a/app/meson.build
+++ b/app/meson.build
@@ -11,7 +11,7 @@ disable_apps = run_command(list_dir_globs, disable_apps, 
check: true).stdout().s
 enable_apps = ',' + get_option('enable_apps')
 enable_apps = run_command(list_dir_globs, enable_apps, check: 
true).stdout().split()
 if enable_apps.length() == 0
-enable_apps = run_command(list_dir_globs, '*', check: 
true).stdout().split()
+enable_apps = run_command(list_dir_globs, '*/', check: 
true).stdout().split()
 endif
 
 apps = [
-- 
2.42.0



[PATCH 2/2] doc: add MSYS2 building guide

2023-09-16 Thread Ric Li
Introduce guide for using MSYS2 to build DPDK on Windows.
MSYS2 provides a Unix-like environment on Windows and
its package manager simplifies tool and dependency
installation, aiding Linux program migration.

Signed-off-by: Ric Li 
---
 doc/guides/windows_gsg/build_dpdk.rst | 36 +++
 1 file changed, 36 insertions(+)

diff --git a/doc/guides/windows_gsg/build_dpdk.rst 
b/doc/guides/windows_gsg/build_dpdk.rst
index 29f2b38feb..27dff76efe 100644
--- a/doc/guides/windows_gsg/build_dpdk.rst
+++ b/doc/guides/windows_gsg/build_dpdk.rst
@@ -12,6 +12,7 @@ environments:
 
 * The Clang-LLVM C compiler and Microsoft MSVC linker.
 * The MinGW-w64 toolchain (either native or cross).
+* MSYS2 with the MINGW64/UCRT64 environment.
 
 The Meson Build system is used to prepare the sources for compilation
 with the Ninja backend.
@@ -55,6 +56,39 @@ Install to a folder without spaces in its name, like 
``C:\MinGW``.
 This path is assumed for the rest of this guide.
 
 
+Option 3. MSYS2 with the MINGW64/UCRT64 Environment
+---
+
+Install MSYS2
+~
+
+Download and install MSYS2 from
+`MSYS2 website <https://www.msys2.org>`_.
+
+Follow the installation instructions provided on the MSYS2 website
+to set up the base system.
+Make sure to update the package database using the
+following commands in the MSYS2 terminal:
+
+.. code-block:: console
+
+pacman -Syu
+
+Install Build Dependencies
+~~
+
+Open the MSYS2 MINGW64/UCRT64 terminal and use the package manager
+to install the required build tools and dependencies:
+
+.. code-block:: console
+
+pacman -S git pactoys
+pacboy -S meson:p gcc:p pkg-config:p
+
+Meson and Ninja are already installed via the package manager,
+so you can proceed with building the code.
+
+
 Install the Build System
 
 
@@ -99,6 +133,8 @@ When using MinGW-w64, it is sufficient to have toolchain 
executables in PATH:
 
 set PATH=C:\MinGW\mingw64\bin;%PATH%
 
+When using MSYS2, perform in the MSYS2 MINGW64/UCRT64 terminal.
+
 To compile the examples, the flag ``-Dexamples`` is required.
 
 .. code-block:: console
-- 
2.42.0



Re: [PATCH 1/2] build: fix list_dir_globs failure in MSYS2

2023-09-19 Thread Ric Li



On 2023/9/19 16:12, Bruce Richardson wrote:
> On Sat, Sep 16, 2023 at 09:15:19PM +0800, Ric Li wrote:
>> When running 'meson build' in MSYS2,
>> "list-dir-globs.py * failed with status 1".
>>
>> Signed-off-by: Ric Li 
>> ---
>>  app/meson.build | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/app/meson.build b/app/meson.build
>> index e4bf5c531c..73e5138301 100644
>> --- a/app/meson.build
>> +++ b/app/meson.build
>> @@ -11,7 +11,7 @@ disable_apps = run_command(list_dir_globs, disable_apps, 
>> check: true).stdout().s
>>  enable_apps = ',' + get_option('enable_apps')
>>  enable_apps = run_command(list_dir_globs, enable_apps, check: 
>> true).stdout().split()
>>  if enable_apps.length() == 0
>> -enable_apps = run_command(list_dir_globs, '*', check: 
>> true).stdout().split()
>> +enable_apps = run_command(list_dir_globs, '*/', check: 
>> true).stdout().split()
>>  endif
>>  
> 
> Do we know more about why this particular failure is happening with MSYS2?
> Can you try running the script manually to see what the specific python
> error is, and if we can make the script more robust generally?
> 

Running the script manually showed nothing but the Usage log.
The arguments here are not accepted by this python script.

MSYS2 does mention some command line parsing issues, see:
https://www.msys2.org/wiki/Porting/
"Windows programs parse the command line themselves,
it isn't parsed for them by the calling process, as on Linux.
This means that if wildcards (glob patterns) are to be accepted by the program,
it has to be able to expand them somehow."

> In terms of the fix, I actually think we should not be using a glob here at
> all. Since we already have the list of apps present in the file, I think
> that we should move the app list to the top of the file and then change the
> code to be:
> 
> if enable_apps.length() == 0
> enable_apps = apps
> endif
> 
> This sidesteps any issues with globbing, and also makes the code a bit
> faster as we don't have to shell-out to a python script.
> 
> /Bruce

That sounds reasonable. I'll test it and provide an update to the patch.

Thanks,
Ric


[PATCH v2 1/2] build: fix list_dir_globs failure in MSYS2

2023-09-20 Thread Ric Li
When running 'meson setup' on Windows with MSYS2,
"list-dir-globs.py * failed with status 1".

Avoid using globbing to get components for app build
since they are already listed in the meson file.

Signed-off-by: Ric Li 
---
 app/meson.build | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/app/meson.build b/app/meson.build
index e4bf5c531c..75ac37bef9 100644
--- a/app/meson.build
+++ b/app/meson.build
@@ -5,15 +5,6 @@ if is_ms_compiler
 subdir_done()
 endif
 
-disable_apps = ',' + get_option('disable_apps')
-disable_apps = run_command(list_dir_globs, disable_apps, check: 
true).stdout().split()
-
-enable_apps = ',' + get_option('enable_apps')
-enable_apps = run_command(list_dir_globs, enable_apps, check: 
true).stdout().split()
-if enable_apps.length() == 0
-enable_apps = run_command(list_dir_globs, '*', check: 
true).stdout().split()
-endif
-
 apps = [
 'dumpcap',
 'pdump',
@@ -41,6 +32,15 @@ if get_option('tests')
 apps += 'test'
 endif
 
+disable_apps = ',' + get_option('disable_apps')
+disable_apps = run_command(list_dir_globs, disable_apps, check: 
true).stdout().split()
+
+enable_apps = ',' + get_option('enable_apps')
+enable_apps = run_command(list_dir_globs, enable_apps, check: 
true).stdout().split()
+if enable_apps.length() == 0
+enable_apps = apps
+endif
+
 default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
 default_ldflags = []
 if get_option('default_library') == 'static' and not is_windows
-- 
2.42.0



[PATCH v2 2/2] doc: add MSYS2 building guide

2023-09-20 Thread Ric Li
Introduce guide for using MSYS2 to build DPDK on Windows.
MSYS2 provides a Unix-like environment on Windows and
its package manager simplifies tool and dependency
installation, aiding Linux program migration.

Signed-off-by: Ric Li 
---
 doc/guides/windows_gsg/build_dpdk.rst | 36 +++
 1 file changed, 36 insertions(+)

diff --git a/doc/guides/windows_gsg/build_dpdk.rst 
b/doc/guides/windows_gsg/build_dpdk.rst
index 29f2b38feb..27dff76efe 100644
--- a/doc/guides/windows_gsg/build_dpdk.rst
+++ b/doc/guides/windows_gsg/build_dpdk.rst
@@ -12,6 +12,7 @@ environments:
 
 * The Clang-LLVM C compiler and Microsoft MSVC linker.
 * The MinGW-w64 toolchain (either native or cross).
+* MSYS2 with the MINGW64/UCRT64 environment.
 
 The Meson Build system is used to prepare the sources for compilation
 with the Ninja backend.
@@ -55,6 +56,39 @@ Install to a folder without spaces in its name, like 
``C:\MinGW``.
 This path is assumed for the rest of this guide.
 
 
+Option 3. MSYS2 with the MINGW64/UCRT64 Environment
+---
+
+Install MSYS2
+~
+
+Download and install MSYS2 from
+`MSYS2 website <https://www.msys2.org>`_.
+
+Follow the installation instructions provided on the MSYS2 website
+to set up the base system.
+Make sure to update the package database using the
+following commands in the MSYS2 terminal:
+
+.. code-block:: console
+
+pacman -Syu
+
+Install Build Dependencies
+~~
+
+Open the MSYS2 MINGW64/UCRT64 terminal and use the package manager
+to install the required build tools and dependencies:
+
+.. code-block:: console
+
+pacman -S git pactoys
+pacboy -S meson:p gcc:p pkg-config:p
+
+Meson and Ninja are already installed via the package manager,
+so you can proceed with building the code.
+
+
 Install the Build System
 
 
@@ -99,6 +133,8 @@ When using MinGW-w64, it is sufficient to have toolchain 
executables in PATH:
 
 set PATH=C:\MinGW\mingw64\bin;%PATH%
 
+When using MSYS2, perform in the MSYS2 MINGW64/UCRT64 terminal.
+
 To compile the examples, the flag ``-Dexamples`` is required.
 
 .. code-block:: console
-- 
2.42.0



[PATCH v4] windows/virt2phys: fix block MDL not updated

2023-12-04 Thread Ric Li
The virt2phys_translate function previously scanned existing blocks,
returning the physical address from the stored MDL info if present.
This method was problematic when a virtual address pointed to a freed
and reallocated memory segment, potentially changing the physical
address mapping. Yet, virt2phys_translate would consistently return
the originally stored physical address, which could be invalid.

This issue surfaced when allocating a memory region larger than 2MB
using rte_malloc. This action would allocate a new memory segment
and use virt2phy to set the IOVA. The driver would store the MDL
and lock the pages initially. When this region was freed, the memory
segment used as a whole page could be freed, invalidating the virtual
to physical mapping. Before this fix, the driver would only return the
initial physical address, leading to illegal IOVA for some pages when
allocating a new memory region larger than the hugepage size (2MB).

To address this, a function to check block physical address has been
added. If a block with the same base address is detected in the
driver's context, the MDL's physical address is compared with the real
physical address. If they don't match, the block is removed and a new
one is created to store the correct mapping. To make the removal action
clear, the list to store MDL blocks is changed to a double linked list.

Also fix the printing of PVOID type.

Bugzilla ID: 1201
Bugzilla ID: 1213

Signed-off-by: Ric Li 
---
 windows/virt2phys/virt2phys.c   |  7 +--
 windows/virt2phys/virt2phys_logic.c | 70 ++---
 2 files changed, 57 insertions(+), 20 deletions(-)

diff --git a/windows/virt2phys/virt2phys.c b/windows/virt2phys/virt2phys.c
index f4d5298..b64a13d 100644
--- a/windows/virt2phys/virt2phys.c
+++ b/windows/virt2phys/virt2phys.c
@@ -182,7 +182,7 @@ virt2phys_device_EvtIoInCallerContext(WDFDEVICE device, 
WDFREQUEST request)
 {
WDF_REQUEST_PARAMETERS params;
ULONG code;
-   PVOID *virt;
+   PVOID *pvirt, virt;
PHYSICAL_ADDRESS *phys;
size_t size;
NTSTATUS status;
@@ -207,12 +207,13 @@ virt2phys_device_EvtIoInCallerContext(WDFDEVICE device, 
WDFREQUEST request)
}
 
status = WdfRequestRetrieveInputBuffer(
-   request, sizeof(*virt), (PVOID *)&virt, &size);
+   request, sizeof(*pvirt), (PVOID *)&pvirt, &size);
if (!NT_SUCCESS(status)) {
TraceWarning("Retrieving input buffer: %!STATUS!", status);
WdfRequestComplete(request, status);
return;
}
+   virt = *pvirt;
 
status = WdfRequestRetrieveOutputBuffer(
request, sizeof(*phys), (PVOID *)&phys, &size);
@@ -222,7 +223,7 @@ virt2phys_device_EvtIoInCallerContext(WDFDEVICE device, 
WDFREQUEST request)
return;
}
 
-   status = virt2phys_translate(*virt, phys);
+   status = virt2phys_translate(virt, phys);
if (NT_SUCCESS(status))
WdfRequestSetInformation(request, sizeof(*phys));
 
diff --git a/windows/virt2phys/virt2phys_logic.c 
b/windows/virt2phys/virt2phys_logic.c
index e3ff293..175924a 100644
--- a/windows/virt2phys/virt2phys_logic.c
+++ b/windows/virt2phys/virt2phys_logic.c
@@ -12,13 +12,13 @@
 struct virt2phys_process {
HANDLE id;
LIST_ENTRY next;
-   SINGLE_LIST_ENTRY blocks;
+   LIST_ENTRY blocks;
ULONG64 memory;
 };
 
 struct virt2phys_block {
PMDL mdl;
-   SINGLE_LIST_ENTRY next;
+   LIST_ENTRY next;
 };
 
 static struct virt2phys_params g_params;
@@ -69,24 +69,28 @@ virt2phys_process_create(HANDLE process_id)
struct virt2phys_process *process;
 
process = ExAllocatePoolZero(NonPagedPool, sizeof(*process), 'pp2v');
-   if (process != NULL)
+   if (process != NULL) {
process->id = process_id;
+   InitializeListHead(&process->blocks);
+   }
+   
return process;
 }
 
 static void
 virt2phys_process_free(struct virt2phys_process *process, BOOLEAN unmap)
 {
-   PSINGLE_LIST_ENTRY node;
+   PLIST_ENTRY node, next;
struct virt2phys_block *block;
 
TraceInfo("ID = %p, unmap = %!bool!", process->id, unmap);
 
-   node = process->blocks.Next;
-   while (node != NULL) {
+   for (node = process->blocks.Flink; node != &process->blocks; node = 
next) {
+   next = node->Flink;
block = CONTAINING_RECORD(node, struct virt2phys_block, next);
-   node = node->Next;
-   virt2phys_block_free(block, unmap);
+   RemoveEntryList(&block->next);
+
+   virt2phys_block_free(block, TRUE);
}
 
ExFreePool(process);
@@ -109,10 +113,10 @@ virt2phys_process_find(HANDLE process_id)
 static struct virt2phys_block *
 vi

[PATCH v4] windows/virt2phys: fix block MDL not updated

2023-12-04 Thread Ric Li
The virt2phys_translate function previously scanned existing blocks,
returning the physical address from the stored MDL info if present.
This method was problematic when a virtual address pointed to a freed
and reallocated memory segment, potentially changing the physical
address mapping. Yet, virt2phys_translate would consistently return
the originally stored physical address, which could be invalid.

This issue surfaced when allocating a memory region larger than 2MB
using rte_malloc. This action would allocate a new memory segment
and use virt2phy to set the IOVA. The driver would store the MDL
and lock the pages initially. When this region was freed, the memory
segment used as a whole page could be freed, invalidating the virtual
to physical mapping. Before this fix, the driver would only return the
initial physical address, leading to illegal IOVA for some pages when
allocating a new memory region larger than the hugepage size (2MB).

To address this, a function to check block physical address has been
added. If a block with the same base address is detected in the
driver's context, the MDL's physical address is compared with the real
physical address. If they don't match, the block is removed and a new
one is created to store the correct mapping. To make the removal action
clear, the list to store MDL blocks is changed to a double linked list.

Also fix the printing of PVOID type.

Bugzilla ID: 1201
Bugzilla ID: 1213

Signed-off-by: Ric Li 
---
 windows/virt2phys/virt2phys.c   |  7 +--
 windows/virt2phys/virt2phys_logic.c | 70 ++---
 2 files changed, 57 insertions(+), 20 deletions(-)

diff --git a/windows/virt2phys/virt2phys.c b/windows/virt2phys/virt2phys.c
index f4d5298..b64a13d 100644
--- a/windows/virt2phys/virt2phys.c
+++ b/windows/virt2phys/virt2phys.c
@@ -182,7 +182,7 @@ virt2phys_device_EvtIoInCallerContext(WDFDEVICE device, 
WDFREQUEST request)
 {
WDF_REQUEST_PARAMETERS params;
ULONG code;
-   PVOID *virt;
+   PVOID *pvirt, virt;
PHYSICAL_ADDRESS *phys;
size_t size;
NTSTATUS status;
@@ -207,12 +207,13 @@ virt2phys_device_EvtIoInCallerContext(WDFDEVICE device, 
WDFREQUEST request)
}
 
status = WdfRequestRetrieveInputBuffer(
-   request, sizeof(*virt), (PVOID *)&virt, &size);
+   request, sizeof(*pvirt), (PVOID *)&pvirt, &size);
if (!NT_SUCCESS(status)) {
TraceWarning("Retrieving input buffer: %!STATUS!", status);
WdfRequestComplete(request, status);
return;
}
+   virt = *pvirt;
 
status = WdfRequestRetrieveOutputBuffer(
request, sizeof(*phys), (PVOID *)&phys, &size);
@@ -222,7 +223,7 @@ virt2phys_device_EvtIoInCallerContext(WDFDEVICE device, 
WDFREQUEST request)
return;
}
 
-   status = virt2phys_translate(*virt, phys);
+   status = virt2phys_translate(virt, phys);
if (NT_SUCCESS(status))
WdfRequestSetInformation(request, sizeof(*phys));
 
diff --git a/windows/virt2phys/virt2phys_logic.c 
b/windows/virt2phys/virt2phys_logic.c
index e3ff293..f867a31 100644
--- a/windows/virt2phys/virt2phys_logic.c
+++ b/windows/virt2phys/virt2phys_logic.c
@@ -12,13 +12,13 @@
 struct virt2phys_process {
HANDLE id;
LIST_ENTRY next;
-   SINGLE_LIST_ENTRY blocks;
+   LIST_ENTRY blocks;
ULONG64 memory;
 };
 
 struct virt2phys_block {
PMDL mdl;
-   SINGLE_LIST_ENTRY next;
+   LIST_ENTRY next;
 };
 
 static struct virt2phys_params g_params;
@@ -69,24 +69,28 @@ virt2phys_process_create(HANDLE process_id)
struct virt2phys_process *process;
 
process = ExAllocatePoolZero(NonPagedPool, sizeof(*process), 'pp2v');
-   if (process != NULL)
+   if (process != NULL) {
process->id = process_id;
+   InitializeListHead(&process->blocks);
+   }
+
return process;
 }
 
 static void
 virt2phys_process_free(struct virt2phys_process *process, BOOLEAN unmap)
 {
-   PSINGLE_LIST_ENTRY node;
+   PLIST_ENTRY node, next;
struct virt2phys_block *block;
 
TraceInfo("ID = %p, unmap = %!bool!", process->id, unmap);
 
-   node = process->blocks.Next;
-   while (node != NULL) {
+   for (node = process->blocks.Flink; node != &process->blocks; node = 
next) {
+   next = node->Flink;
block = CONTAINING_RECORD(node, struct virt2phys_block, next);
-   node = node->Next;
-   virt2phys_block_free(block, unmap);
+   RemoveEntryList(&block->next);
+
+   virt2phys_block_free(block, TRUE);
}
 
ExFreePool(process);
@@ -109,10 +113,10 @@ virt2phys_process_find(HANDLE process_id)
 static struct virt2phys_block *
 virt2phys_process_find_block