<div dir="auto">Is there a way for drivers to change the semantics of memory mappings to make mremap work? <div dir="auto"><br></div><div dir="auto">Marek</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Oct 24, 2024, 07:08 Derek Lesho <<a href="mailto:dlesho@codeweavers.com">dlesho@codeweavers.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">In my last mail I responded to this approach all the way at the bottom, <br>
so it probably got lost: mremap on Linux as it exists now won't work as <br>
it only supports private anonymous mappings (in conjunction with <br>
MREMAP_DONTUNMAP), which GPU mappings are not.<br>
<br>
Am 10/24/24 um 01:06 schrieb James Jones:<br>
> That makes sense. Reading the man page myself, it does seem like:<br>
><br>
> -If the drivers can guarantee they set MAP_SHARED when creating their <br>
> initial mapping.<br>
><br>
> -If WINE is fine rounding down to page boundaries to deal with <br>
> mappings of suballocations and either using some lookup structure to <br>
> avoid duplicate remappings (probably needed to handle unmap anyway per <br>
> below) or just living with the perf cost and address space <br>
> overconsumption for duplicate remappings.<br>
><br>
> -If mremap() preserves the cache attributes of the original mapping.<br>
><br>
> Then no GL API change would be needed. WINE would just have to do an <br>
> if (addrAbove4G) { mremapStuff() } on map and presumably add some <br>
> tracking to perform an equivalent munmap() when unmapping. I assume <br>
> WINE already has a bunch of vaddr tracking logic in use to manage the <br>
> <4G address space as described elsewhere in the thread. That would be <br>
> pretty ideal from a driver vendor perspective.<br>
><br>
> Does that work?<br>
><br>
> Thanks,<br>
> -James<br>
><br>
> On 10/23/24 06:12, Christian König wrote:<br>
>> I haven't read through the whole mail thread, but if you manage the <br>
>> address space using mmap() then you always run into this issue.<br>
>><br>
>> If you manage the whole 4GiB address space by Wine then you never run <br>
>> into this issue. You would just allocate some address range <br>
>> internally and mremap() into that.<br>
>><br>
>> Regards,<br>
>> Christian.<br>
>><br>
>> Am 22.10.24 um 19:32 schrieb James Jones:<br>
>>> This sounds interesting, but does it come with the same "Only gets <br>
>>> 2GB VA" downside Derek pointed out in the thread fork where he was <br>
>>> responding to Michel?<br>
>>><br>
>>> Thanks,<br>
>>> -James<br>
>>><br>
>>> On 10/22/24 07:14, Christian König wrote:<br>
>>>> Hi guys,<br>
>>>><br>
>>>> one theoretical alternative not mentioned in this thread is the use <br>
>>>> of mremap().<br>
>>>><br>
>>>> In other words you reserve some address space below 2G by using <br>
>>>> mmap(NULL, length, PROT_NONE, MAP_32BIT | MAP_ANONYMOUS, 0, 0) and <br>
>>>> then use mremap(addr64bit, 0, length, MREMAP_FIXED, reserved_addr).<br>
>>>><br>
>>>> I haven't tested this but at least in theory it should give you a <br>
>>>> duplicate of the 64bit mapping in the lower 2G of the address space.<br>
>>>><br>
>>>> Important is that you give 0 as oldsize to mremap() so that the old <br>
>>>> mapping isn't unmapped but rather just a new mapping of the <br>
>>>> existing VMA created.<br>
>>>><br>
>>>> Regards,<br>
>>>> Christian.<br>
>>>><br>
>>>><br>
>>>> Am 18.10.24 um 23:55 schrieb Derek Lesho:<br>
>>>>> Hey everyone 👋,<br>
>>>>><br>
>>>>> I'm Derek from the Wine project, and wanted to start a discussion <br>
>>>>> with y'all about potentially extending the Mesa OGL drivers to <br>
>>>>> help us with a functionality gap we're facing.<br>
>>>>><br>
>>>>> Problem Space:<br>
>>>>><br>
>>>>> In the last few years Wine's support for running 32-bit windows <br>
>>>>> apps in a 64-bit host environment (wow64) has almost reached <br>
>>>>> feature completion, but there remains a pain point with OpenGL <br>
>>>>> applications: Namely that Wine can't return a 64-bit GL <br>
>>>>> implementation's buffer mappings to a 32 bit application when the <br>
>>>>> address is outside of the 32-bit range.<br>
>>>>><br>
>>>>> Currently, we have a workaround that will copy any changes to the <br>
>>>>> mapping back to the host upon glBufferUnmap, but this of course is <br>
>>>>> slow when the implementation directly returns mapped memory, and <br>
>>>>> doesn't work for GL_PERSISTENT_BIT, where directly mapped memory <br>
>>>>> is required.<br>
>>>>><br>
>>>>> A few years ago we also faced this problem with Vulkan's, which <br>
>>>>> was solved through the VK_EXT_map_memory_placed extension Faith <br>
>>>>> drafted, allowing us to use our Wine-internal allocator to provide <br>
>>>>> the pages the driver maps to. I'm now wondering if an GL <br>
>>>>> equivalent would also be seen as feasible amongst the devs here.<br>
>>>>><br>
>>>>> Proposed solution:<br>
>>>>><br>
>>>>> As the GL backend handles host mapping in its own code, only <br>
>>>>> giving suballocations from its mappings back to the App, the <br>
>>>>> problem is a little bit less straight forward in comparison to our <br>
>>>>> Vulkan solution: If we just allowed the application to set its own <br>
>>>>> placed mapping when calling glMapBuffer, the driver might then <br>
>>>>> have to handle moving buffers out of already mapped ranges, and <br>
>>>>> would lose control over its own memory management schemes.<br>
>>>>><br>
>>>>> Therefore, I propose a GL extension that allows the GL client to <br>
>>>>> provide a mapping and unmapping callback to the implementation, to <br>
>>>>> be used whenever the driver needs to perform such operations. This <br>
>>>>> way the driver remains in full control of its memory management <br>
>>>>> affairs, and the amount of work for an implementation as well as <br>
>>>>> potential for bugs is kept minimal. I've written a draft <br>
>>>>> implementation in Zink using map_memory_placed [1] and a <br>
>>>>> corresponding Wine MR utilizing it [2], and would be curious to <br>
>>>>> hear your thoughts. I don't have experience in the Mesa codebase, <br>
>>>>> so I apologize if the branch is a tad messy.<br>
>>>>><br>
>>>>> In theory, the only requirement from drivers from the extension <br>
>>>>> would be that glMapBuffer always return a pointer from within a <br>
>>>>> page allocated through the provided callbacks, so that it can be <br>
>>>>> guaranteed to be positioned within the required address space. <br>
>>>>> Wine would then use it's existing workaround for other types of <br>
>>>>> buffers, but as Mesa seems to often return directly mapped buffers <br>
>>>>> in other cases as well, Wine could also avoid the slowdown that <br>
>>>>> comes with copying in these cases as well.<br>
>>>>><br>
>>>>> Why not use Zink?:<br>
>>>>><br>
>>>>> There's also a proposal to use a 32-bit PE build of Zink in Wine <br>
>>>>> bypassing the need for an extension; I brought this to discussion <br>
>>>>> in this Wine-Devel thread last week [3], which has some arguments <br>
>>>>> against this approach.<br>
>>>>><br>
>>>>><br>
>>>>> If any of you have thoughts, concerns, or questions about this <br>
>>>>> potential approach, please let me know, thanks!<br>
>>>>><br>
>>>>> 1: <br>
>>>>> <a href="https://gitlab.freedesktop.org/Guy1524/mesa/-/commits/placed_allocation" rel="noreferrer noreferrer" target="_blank">https://gitlab.freedesktop.org/Guy1524/mesa/-/commits/placed_allocation</a> <br>
>>>>><br>
>>>>><br>
>>>>> 2: <a href="https://gitlab.winehq.org/wine/wine/-/merge_requests/6663" rel="noreferrer noreferrer" target="_blank">https://gitlab.winehq.org/wine/wine/-/merge_requests/6663</a><br>
>>>>><br>
>>>>> 3: <a href="https://marc.info/?t=172883260300002&r=1&w=2" rel="noreferrer noreferrer" target="_blank">https://marc.info/?t=172883260300002&r=1&w=2</a><br>
>>>>><br>
>>>><br>
>><br>
</blockquote></div>