[PATCH] privates: Clear screen-specific keys during CloseScreen
Aaron Plattner
aplattner at nvidia.com
Wed Sep 16 13:26:52 PDT 2015
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 <aplattner at nvidia.com>
---
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
More information about the xorg-devel
mailing list