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