The modesetting driver corrupts memory when used after a server regeneration because not enough memory is allocated for its pixmap privates. This happens because its call to dixRegisterScreenSpecificPrivateKey() does nothing because key->initialized is still TRUE from the first server generation. However, the key is not in the screen's linked list of screen-specific privates because that's freed and reallocated during the server generation loop in dix_main().
Fix this by clearing key->initialized after CloseScreen. Move the call to dixFreeScreenSpecificPrivates() after the call to CloseScreen, in case a driver's CloseScreen needs a screen private for something. Finally, add a call to dixFreeScreenSpecificPrivates() for GPU screens. Signed-off-by: Aaron Plattner <[email protected]> --- Keith, I was thinking about your suggestion of ignoring key->initialized backwards yesterday. I think that would work too, but I think this is clearer and more explicit. dix/main.c | 3 ++- dix/privates.c | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/dix/main.c b/dix/main.c index 09f9504b8acb..43f176f2d3b3 100644 --- a/dix/main.c +++ b/dix/main.c @@ -338,6 +338,7 @@ dix_main(int argc, char *argv[], char *envp[]) ScreenPtr pScreen = screenInfo.gpuscreens[i]; FreeScratchPixmapsForScreen(pScreen); (*pScreen->CloseScreen) (pScreen); + dixFreeScreenSpecificPrivates(pScreen); dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN); free(pScreen); screenInfo.numGPUScreens = i; @@ -347,8 +348,8 @@ dix_main(int argc, char *argv[], char *envp[]) FreeScratchPixmapsForScreen(screenInfo.screens[i]); FreeGCperDepth(i); FreeDefaultStipple(i); - dixFreeScreenSpecificPrivates(screenInfo.screens[i]); (*screenInfo.screens[i]->CloseScreen) (screenInfo.screens[i]); + dixFreeScreenSpecificPrivates(screenInfo.screens[i]); dixFreePrivates(screenInfo.screens[i]->devPrivates, PRIVATE_SCREEN); free(screenInfo.screens[i]); screenInfo.numScreens = i; diff --git a/dix/privates.c b/dix/privates.c index e03b2255b7f3..969d0141c844 100644 --- a/dix/privates.c +++ b/dix/privates.c @@ -642,6 +642,15 @@ dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen, DevPrivateKey key, void dixFreeScreenSpecificPrivates(ScreenPtr pScreen) { + DevPrivateType t; + + for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) { + DevPrivateKey key; + + for (key = pScreen->screenSpecificPrivates[t].key; key; key = key->next) { + key->initialized = FALSE; + } + } } /* Initialize screen-specific privates in AddScreen */ -- 2.5.2 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
