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 the screen-specific keys during CloseScreen, the same way other privates are cleared during dixResetPrivates(). Finally, add a call to dixFreeScreenSpecificPrivates() for GPU screens. Signed-off-by: Aaron Plattner <[email protected]> --- dix/main.c | 1 + dix/privates.c | 34 +++++++++++++++++++++++----------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/dix/main.c b/dix/main.c index d7a9cdaae8e7..549567660379 100644 --- a/dix/main.c +++ b/dix/main.c @@ -339,6 +339,7 @@ dix_main(int argc, char *argv[], char *envp[]) for (i = screenInfo.numGPUScreens - 1; i >= 0; i--) { ScreenPtr pScreen = screenInfo.gpuscreens[i]; FreeScratchPixmapsForScreen(pScreen); + dixFreeScreenSpecificPrivates(pScreen); (*pScreen->CloseScreen) (pScreen); dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN); free(pScreen); diff --git a/dix/privates.c b/dix/privates.c index e03b2255b7f3..4fd8aeda1202 100644 --- a/dix/privates.c +++ b/dix/privates.c @@ -593,6 +593,26 @@ dixLookupPrivateOffset(RESTYPE type) return -1; } +static void +FreeKeyLists(DevPrivateSetRec keys[PRIVATE_LAST]) +{ + DevPrivateType t; + + for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) { + DevPrivateKey key, next; + + for (key = keys[t].key; key; key = next) { + next = key->next; + key->offset = 0; + key->initialized = FALSE; + key->size = 0; + key->type = 0; + if (key->allocated) + free(key); + } + } +} + /* * Screen-specific privates */ @@ -642,6 +662,7 @@ dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen, DevPrivateKey key, void dixFreeScreenSpecificPrivates(ScreenPtr pScreen) { + FreeKeyLists(pScreen->screenSpecificPrivates); } /* Initialize screen-specific privates in AddScreen */ @@ -751,18 +772,9 @@ dixResetPrivates(void) { DevPrivateType t; - for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) { - DevPrivateKey key, next; + FreeKeyLists(global_keys); - for (key = global_keys[t].key; key; key = next) { - next = key->next; - key->offset = 0; - key->initialized = FALSE; - key->size = 0; - key->type = 0; - if (key->allocated) - free(key); - } + for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) { if (global_keys[t].created) { ErrorF("%d %ss still allocated at reset\n", global_keys[t].created, key_names[t]); -- 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
