libwine: Only partially reserve memory beyond 0x80000000 on FreeBSD.
Tijl Coosemans
tijl at ulyssis.org
Wed Mar 18 14:31:35 CDT 2009
On Wednesday 18 March 2009 16:36:29 Francois Gouget wrote:
> Tijl Coosemans a écrit :
>> After enabling the memory reservation code on FreeBSD last week,
>> several games either suffer a performance loss or simply crash,
>> often with GL_OUT_OF_MEMORY errors or similar out of memory errors
>> from X libs. (Tested with nvidia driver and opensource r300 dri
>> driver.)
>
> Which games can be used to reproduce this issue? Is one of them
> freely downloadable? Even better, can this issue be reproduced with a
> non-game application?
Puzzle Quest is a game that starts up slowly and locks up before
getting to the game menu.
http://www.infinite-interactive.com/puzzlequest.php?page=demo
Alex Kozlov (CCed) can give you more examples. He mentioned StarWolves,
Warlords4, Erherlords, Soldier of Fortune Gold, Fall: Last Days og
Gaia, Dominions3...
Normal applications all seem to work.
> Also, won't this patch be obsolete once Alexandre completes his
> current OpenGL memory allocation work? That is, doesn't it just hide
> the problem rather than solving it?
I don't know what Alexandre's work involves, but the problem here are
malloc(3) and mmap(2) calls in code outside Wine. On FreeBSD mmap
allocates upwards starting after the location of the executable + some
malloc heap space. With everything above 0x80000000 reserved and the
wine executable located at 0x7bf00000, there's only about 64MiB of
address space left of which about 32MiB is currently designated malloc
heap (loader/main.c:RLIMIT_DATA). The 32MiB that is left is just enough
to contain all unix and Wine libs, and a 32MiB malloc heap seems to be
enough for all normal applications. I attached a typical layout.
>> It also causes other problems like:
>> http://bugs.winehq.org/show_bug.cgi?id=17718
>
> This bug mentions the following error:
> Fatal error 'Cannot allocate red zone for initial thread' at line 384
> in file /usr/src/lib/libthr/thread/thr_init.c (errno = 2)
>
> It would be nice to figure out how we get in init_main_thread().
> Apparently there are only two possible cases:
> * 1) Some thread routines have detected that the library hasn't yet
> * been initialized (_thr_initial == NULL && curthread == NULL), or
> *
> * 2) An explicit call to reinitialize after a fork (indicated
> * by curthread != NULL)
>
> I don't really understand why we would reallocate the stack in the
> first case so my guess is this happens through a fork.
I've never been able to reproduce this and haven't looked at it very
closely because the problem went away with this patch, but my best
guess is case 1. The threading lib is only initialized when actually
needed. And then perhaps it fails to allocate the red zone for the main
process stack because that page has already been reserved. That doesn't
explain why I can't reproduce it though.
>> This patch only partially reserves memory, enough for the shared
>> heap, virtual heap and wine top-down allocations, and leaves the
>> majority unreserved.
>
> Isn't the memory reservation supposed to prevent Unix libraries from
> being mapped in this memory range? If so, won't leaving holes open us
> to this sort of trouble again?
>
> Also, besides FreeBSD's braindead stack allocation routines, why
> should this patch only be used on FreeBSD? If it's supposed to help
> with OpenGL memory allocation then shouldn't it be used on Linux too
> (which has the same issue with OpenGL)?
The memory reservation is needed on Linux because mmap allocates
downwards from the end of address space, so without reservation all
libs end up far beyond 0x80000000 close to the stack. On FreeBSD mmap
allocates upwards so the layout in the attached file for instance looks
the same with or without reservation. On FreeBSD the memory reservation
doesn't really solve any problem.
What exactly is the issue with OpenGL on Linux?
-------------- next part --------------
Module Address Debug info Name (99 modules)
PE 3a0000- 3c6000 Deferred 3dfpfpu
PE 3d0000- 3ea000 Deferred 2dintmmx
PE 400000- 83b000 Export etherlords
PE 10000000-10059000 Deferred binkw32
PE 21000000-21056000 Deferred mss32
PE 22000000-22026000 Deferred mp3dec.asi
ELF 7bf00000-7bf03000 Deferred <wine-loader>
ELF 7df02000-7df2d000 Deferred ld-elf.so.1
ELF 7df3e000-7e078000 Deferred libwine.so.1
ELF 7e078000-7e08b000 Deferred libthr.so.2
ELF 7e08b000-7e175000 Deferred libc.so.6
ELF 7e176000-7e21c000 Deferred ntdll<elf>
\-PE 7e190000-7e21c000 \ ntdll
ELF 7e21c000-7e232000 Deferred libm.so.4
ELF 7e232000-7e365000 Deferred kernel32<elf>
\-PE 7e250000-7e365000 \ kernel32
ELF 7e365000-7e37f000 Deferred wsock32<elf>
\-PE 7e370000-7e37f000 \ wsock32
ELF 7e37f000-7e3ab000 Deferred ws2_32<elf>
\-PE 7e390000-7e3ab000 \ ws2_32
ELF 7e3ab000-7e3c9000 Deferred iphlpapi<elf>
\-PE 7e3b0000-7e3c9000 \ iphlpapi
ELF 7e3c9000-7e41b000 Deferred advapi32<elf>
\-PE 7e3d0000-7e41b000 \ advapi32
ELF 7e41b000-7e466000 Deferred dsound<elf>
\-PE 7e420000-7e466000 \ dsound
ELF 7e466000-7e4f6000 Deferred winmm<elf>
\-PE 7e470000-7e4f6000 \ winmm
ELF 7e4f6000-7e637000 Deferred user32<elf>
\-PE 7e510000-7e637000 \ user32
ELF 7e637000-7e6d2000 Deferred gdi32<elf>
\-PE 7e650000-7e6d2000 \ gdi32
ELF 7e6d2000-7e7c0000 Deferred ole32<elf>
\-PE 7e6f0000-7e7c0000 \ ole32
ELF 7e7c0000-7e824000 Deferred rpcrt4<elf>
\-PE 7e7d0000-7e824000 \ rpcrt4
ELF 7e824000-7e87a000 Deferred ddraw<elf>
\-PE 7e830000-7e87a000 \ ddraw
ELF 7e87a000-7e929000 Deferred comdlg32<elf>
\-PE 7e880000-7e929000 \ comdlg32
ELF 7e929000-7eab1000 Deferred shell32<elf>
\-PE 7e940000-7eab1000 \ shell32
ELF 7eab1000-7eb0a000 Deferred shlwapi<elf>
\-PE 7eac0000-7eb0a000 \ shlwapi
ELF 7eb0a000-7ebce000 Deferred comctl32<elf>
\-PE 7eb10000-7ebce000 \ comctl32
ELF 7ebce000-7ec02000 Deferred winspool<elf>
\-PE 7ebe0000-7ec02000 \ winspool
ELF 7ec02000-7ece0000 Deferred oleaut32<elf>
\-PE 7ec20000-7ece0000 \ oleaut32
ELF 7ece0000-7ed4f000 Deferred libfreetype.so.9
ELF 7ed4f000-7ed60000 Deferred libz.so.3
ELF 7ed60000-7ed88000 Deferred libfontconfig.so.1
ELF 7ed88000-7eda7000 Deferred libexpat.so.6
ELF 7edb8000-7ee4e000 Deferred winex11<elf>
\-PE 7edd0000-7ee4e000 \ winex11
ELF 7ee4e000-7ee56000 Deferred libsm.so.6
ELF 7ee56000-7ee6d000 Deferred libice.so.6
ELF 7ee6d000-7ee7b000 Deferred libxext.so.6
ELF 7ee7b000-7ef92000 Deferred libx11.so.6
ELF 7ef92000-7efa8000 Deferred libxcb.so.2
ELF 7efa8000-7efad000 Deferred libxdmcp.so.6
ELF 7efad000-7efaf000 Deferred libpthread-stubs.so.0
ELF 7efaf000-7efb7000 Deferred librpcsvc.so.3
ELF 7efb7000-7efba000 Deferred libxau.so.6
ELF 7efba000-7efda000 Deferred imm32<elf>
\-PE 7efc0000-7efda000 \ imm32
ELF 7efda000-7efdd000 Deferred libxinerama.so.1
ELF 7efdd000-7efe2000 Deferred libxxf86vm.so.1
ELF 7efe2000-7efeb000 Deferred libxrender.so.1
ELF 7efeb000-7eff2000 Deferred libxrandr.so.2
ELF 7eff2000-7eff5000 Deferred libxcomposite.so.1
ELF 7eff5000-7effa000 Deferred libxfixes.so.3
ELF 7effa000-7f003000 Deferred libxcursor.so.1
ELF 7f018000-7f054000 Deferred wineoss<elf>
\-PE 7f020000-7f054000 \ wineoss
ELF 7f054000-7f06c000 Deferred msacm32<elf>
\-PE 7f060000-7f06c000 \ msacm32
ELF 7f06c000-7f090000 Deferred msacm32<elf>
\-PE 7f070000-7f090000 \ msacm32
ELF 7f090000-7f0a5000 Deferred midimap<elf>
\-PE 7f0a0000-7f0a5000 \ midimap
ELF 7f0a5000-7f0d8000 Deferred uxtheme<elf>
\-PE 7f0b0000-7f0d8000 \ uxtheme
ELF 7f0eb000-7f0ed000 Deferred libnvidia-tls.so.1
ELF 7f11d000-7f16b000 Deferred msxml3<elf>
\-PE 7f130000-7f16b000 \ msxml3
ELF 7f16b000-7f28d000 Deferred libxml2.so.5
ELF 7f28d000-7f383000 Deferred libiconv.so.3
ELF 7f383000-7f3c1000 Deferred urlmon<elf>
\-PE 7f390000-7f3c1000 \ urlmon
ELF 7f3c1000-7f411000 Deferred wininet<elf>
\-PE 7f3d0000-7f411000 \ wininet
ELF 7f411000-7f433000 Deferred mpr<elf>
\-PE 7f420000-7f433000 \ mpr
ELF 7f433000-7f544000 Deferred wined3d<elf>
\-PE 7f440000-7f544000 \ wined3d
ELF 7f544000-7f5d9000 Deferred libgl.so.1
ELF 7f5d9000-7fdf6000 Deferred libglcore.so.1
More information about the wine-devel
mailing list