Re: Helping Wine use 64 bit Mesa OGL drivers for 32-bit Windows applications

2024-10-31 Thread Derek Lesho

Hi Christian,

Thanks for exploring this option, it's great to have a better 
understanding of the capabilities/limits of mremap.


First, a few practical questions:

- How would Wine detect the updated mremap, I suppose we would want to 
create a test persistent mapping on init and see if mremap works on that 
page?


- In my experience Mesa will sometimes return malloc'd pointers from 
glMapBuffer when using the transfer helper, which I assume has to do 
with buffer textures. If wine blindly uses remap for all glMapBuffer 
calls, we'll then end up hitting the private anonymous path, where from 
what I understand page faults are use to preserve the old page, 
potentially slowing things down, thoughts?


Second, in regards to going forward:

I don't have the final call on what path we end up taking 😅. I think it 
would be good if others from wine-devel pitched into what they think, 
but here's my opinion:


I think the mremap approach should definitely be pursued since it looks 
like such a simple Kernel patch, but it may also be good to pursue a 
simple Mesa-Integrated path as well, maybe with Mesa calling into a Wine 
library to allocate 32-bit pages, as we support non-linux OS's as well.


Thanks,
Derek

Am 10/30/24 um 14:03 schrieb Christian König:

Hi guys,

so I looked a bit deeper into the problem of duplicating graphics 
driver mappings with mremap().


This use case of duplicating a mapping into a fixed address is already 
supported quite well using mremap(). This is used by a couple of 
different emulators to re-create the address space like you would find 
it in the specific environment.


The only problem is that this only works for files and shared memory 
at the moment. Graphic driver mappings on the other hand have the 
VM_DONTEXPAND and VM_PFNMAP flag set because their mappings shouldn't 
grow and can also include VRAM.


The attached patch changes this restriction for the mremap() function 
and so also allows duplicating the VMAs of graphics drivers into the 
lower 32bit address space managed by Wine.


I've tested this with some of AMD's GPU unit tests and it actually 
seems to work quite fine.


Derek please let me know if that solution works for you and if you're 
interested in using it. If yes I would go ahead and send the patch to 
the Linux memory management folks for discussion.


Regards,
Christian.

Am 24.10.24 um 17:06 schrieb Christian König:

Darek we are unfortunately both partially right.

Linux supports cloning VMAs using mremap() from userspace by using a 
zero old size, but unfortunately only for SHM areas.


See the code in mm/mremap.c:
    /*
 * We allow a zero old-len as a special case
 * for DOS-emu "duplicate shm area" thing. But
 * a zero new-len is nonsensical.
 */
    if (!new_len)
    return ret;

Going to take a closer look to figure out what would be necessary to 
solve that for GPU drivers as well.


Regards,
Christian.

Am 24.10.24 um 14:56 schrieb Christian König:

I haven't tested it but as far as I know that isn't correct.

As far as I know you can map the same VMA at a different location 
even without MREMAP_DONTUNMAP. And yes MREMAP_DONTUNMAP only work 
with private mappings, but that isn't needed here.


Give me a moment to test this.

Regards,
Christian.

Am 24.10.24 um 10:03 schrieb Derek Lesho:
In my last mail I responded to this approach all the way at the 
bottom, so it probably got lost: mremap on Linux as it exists now 
won't work as it only supports private anonymous mappings (in 
conjunction with MREMAP_DONTUNMAP), which GPU mappings are not.


Am 10/24/24 um 01:06 schrieb James Jones:

That makes sense. Reading the man page myself, it does seem like:

-If the drivers can guarantee they set MAP_SHARED when creating 
their initial mapping.


-If WINE is fine rounding down to page boundaries to deal with 
mappings of suballocations and either using some lookup structure 
to avoid duplicate remappings (probably needed to handle unmap 
anyway per below) or just living with the perf cost and address 
space overconsumption for duplicate remappings.


-If mremap() preserves the cache attributes of the original mapping.

Then no GL API change would be needed. WINE would just have to do 
an if (addrAbove4G) { mremapStuff() } on map and presumably add 
some tracking to perform an equivalent munmap() when unmapping. I 
assume WINE already has a bunch of vaddr tracking logic in use to 
manage the <4G address space as described elsewhere in the thread. 
That would be pretty ideal from a driver vendor perspective.


Does that work?

Thanks,
-James

On 10/23/24 06:12, Christian König wrote:
I haven't read through the whole mail thread, but if you manage 
the address space using mmap() then you always run into this issue.


If you manage the whole 4GiB address space by Wine then you never 
run into this issue. You would just allocate some address range 
internally and mremap() into that.


Regards,
Christian.

Re: Helping Wine use 64 bit Mesa OGL drivers for 32-bit Windows applications

2024-10-31 Thread Christian König

Hi Derek,

Am 31.10.24 um 11:05 schrieb Derek Lesho:

Hi Christian,

Thanks for exploring this option, it's great to have a better 
understanding of the capabilities/limits of mremap.


First, a few practical questions:

- How would Wine detect the updated mremap, I suppose we would want to 
create a test persistent mapping on init and see if mremap works on 
that page?


Good question, I'm not 100% sure. I would need to double check with 
upstream on that, but before I would do this I would first like to know 
if it's really a doable option.


- In my experience Mesa will sometimes return malloc'd pointers from 
glMapBuffer when using the transfer helper, which I assume has to do 
with buffer textures. If wine blindly uses remap for all glMapBuffer 
calls, we'll then end up hitting the private anonymous path, where 
from what I understand page faults are use to preserve the old page, 
potentially slowing things down, thoughts?


Private anonymous means that you *can't* map the memory at two different 
locations because it is actually private and writing into it from a 
second mapping would trigger copy on write.


The name of the MREMAP_DONTUNMAP flag is also really a misleading. 
Instead of "not unmapping" what happens is that you atomically move a 
private anonymous mapping from A to B and at the same time create a new 
mapping at A with zeroed memory. Not really sure what that is good for.



Second, in regards to going forward:

I don't have the final call on what path we end up taking 😅. I think 
it would be good if others from wine-devel pitched into what they 
think, but here's my opinion:


I think the mremap approach should definitely be pursued since it 
looks like such a simple Kernel patch, but it may also be good to 
pursue a simple Mesa-Integrated path as well, maybe with Mesa calling 
into a Wine library to allocate 32-bit pages, as we support non-linux 
OS's as well.


To be honest I can't say what's the right approach either. I've seen the 
mremap() approach being used on emulators before and it's usually really 
useful there.


Just wanted to point out that nobody has mentioned the mremap() 
functionality in the discussion and then became curious why it works for 
files and shared memory but doesn't for GPU driver mappings  :)


Regarding an OpenGL or Vulkan extension based approach it's really 
tricky to do this as well. Basically only the driver knows what and how 
data needs to be mapped and only Wine knows were it can be mapped. So 
you need to exchange a bunch of information like size and alignment of a 
mapping to actually make it work.


Regards,
Christian.



Thanks,
Derek

Am 10/30/24 um 14:03 schrieb Christian König:

Hi guys,

so I looked a bit deeper into the problem of duplicating graphics 
driver mappings with mremap().


This use case of duplicating a mapping into a fixed address is 
already supported quite well using mremap(). This is used by a couple 
of different emulators to re-create the address space like you would 
find it in the specific environment.


The only problem is that this only works for files and shared memory 
at the moment. Graphic driver mappings on the other hand have the 
VM_DONTEXPAND and VM_PFNMAP flag set because their mappings shouldn't 
grow and can also include VRAM.


The attached patch changes this restriction for the mremap() function 
and so also allows duplicating the VMAs of graphics drivers into the 
lower 32bit address space managed by Wine.


I've tested this with some of AMD's GPU unit tests and it actually 
seems to work quite fine.


Derek please let me know if that solution works for you and if you're 
interested in using it. If yes I would go ahead and send the patch to 
the Linux memory management folks for discussion.


Regards,
Christian.

Am 24.10.24 um 17:06 schrieb Christian König:

Darek we are unfortunately both partially right.

Linux supports cloning VMAs using mremap() from userspace by using a 
zero old size, but unfortunately only for SHM areas.


See the code in mm/mremap.c:
    /*
 * We allow a zero old-len as a special case
 * for DOS-emu "duplicate shm area" thing. But
 * a zero new-len is nonsensical.
 */
    if (!new_len)
    return ret;

Going to take a closer look to figure out what would be necessary to 
solve that for GPU drivers as well.


Regards,
Christian.

Am 24.10.24 um 14:56 schrieb Christian König:

I haven't tested it but as far as I know that isn't correct.

As far as I know you can map the same VMA at a different location 
even without MREMAP_DONTUNMAP. And yes MREMAP_DONTUNMAP only work 
with private mappings, but that isn't needed here.


Give me a moment to test this.

Regards,
Christian.

Am 24.10.24 um 10:03 schrieb Derek Lesho:
In my last mail I responded to this approach all the way at the 
bottom, so it probably got lost: mremap on Linux as it exists now 
won't work as it only supports private anonymous mappings (in 
conjunction with MRE