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:
- Some thread routines have detected that the library hasn't yet
been initialized (_thr_initial == NULL && curthread == NULL), or
- 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?