Re: Helping Wine use 64 bit Mesa OGL drivers for 32-bit Windows applications
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
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