Merge branch 'leak' into 'master'

Some memory leak fixes

See merge request xorg/xserver!273
This commit is contained in:
JeffyChen 2025-11-17 17:01:15 +00:00
commit 0c0840628d
16 changed files with 158 additions and 27 deletions

View file

@ -201,7 +201,11 @@ ShmCloseScreen(ScreenPtr pScreen)
pScreen->CloseScreen = screen_priv->CloseScreen;
dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey, NULL);
free(screen_priv);
return (*pScreen->CloseScreen) (pScreen);
if (!pScreen->CloseScreen)
return (*pScreen->CloseScreen) (pScreen);
return TRUE;
}
static ShmScrPrivateRec *

View file

@ -318,8 +318,8 @@ dix_main(int argc, char *argv[], char *envp[])
for (i = screenInfo.numGPUScreens - 1; i >= 0; i--) {
ScreenPtr pScreen = screenInfo.gpuscreens[i];
dixFreeScreenSpecificPrivates(pScreen);
(*pScreen->CloseScreen) (pScreen);
dixFreeScreenSpecificPrivates(pScreen);
dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN);
free(pScreen);
screenInfo.numGPUScreens = i;
@ -328,8 +328,8 @@ dix_main(int argc, char *argv[], char *envp[])
for (i = screenInfo.numScreens - 1; i >= 0; 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;

View file

@ -36,6 +36,8 @@
#include "exa.h"
DevPrivateKeyRec exaScreenPrivateKeyRec;
DevPrivateKeyRec exaPixmapPrivateKeyRec;
DevPrivateKeyRec exaGcPrivateKeyRec;
#ifdef MITSHM
static ShmFuncs exaShmFuncs = { NULL, NULL };
@ -888,6 +890,9 @@ exaDriverInit(ScreenPtr pScreen, ExaDriverPtr pScreenInfo)
return FALSE;
}
memset(&exaGcPrivateKeyRec, 0, sizeof(exaGcPrivateKeyRec));
memset(&exaPixmapPrivateKeyRec, 0, sizeof(exaPixmapPrivateKeyRec));
pExaScr->info = pScreenInfo;
dixSetPrivate(&pScreen->devPrivates, exaScreenPrivateKey, pExaScr);
@ -897,7 +902,7 @@ exaDriverInit(ScreenPtr pScreen, ExaDriverPtr pScreenInfo)
exaDDXDriverInit(pScreen);
if (!dixRegisterScreenSpecificPrivateKey
(pScreen, &pExaScr->gcPrivateKeyRec, PRIVATE_GC, sizeof(ExaGCPrivRec))) {
(pScreen, &exaGcPrivateKeyRec, PRIVATE_GC, sizeof(ExaGCPrivRec))) {
LogMessage(X_WARNING, "EXA(%d): Failed to allocate GC private\n",
pScreen->myNum);
return FALSE;
@ -946,7 +951,7 @@ exaDriverInit(ScreenPtr pScreen, ExaDriverPtr pScreenInfo)
*/
if (pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) {
if (!dixRegisterScreenSpecificPrivateKey
(pScreen, &pExaScr->pixmapPrivateKeyRec, PRIVATE_PIXMAP,
(pScreen, &exaPixmapPrivateKeyRec, PRIVATE_PIXMAP,
sizeof(ExaPixmapPrivRec))) {
LogMessage(X_WARNING,
"EXA(%d): Failed to allocate pixmap private\n",

View file

@ -209,19 +209,18 @@ typedef struct {
RegionRec maskReg;
PixmapPtr srcPix;
PixmapPtr maskPix;
DevPrivateKeyRec pixmapPrivateKeyRec;
DevPrivateKeyRec gcPrivateKeyRec;
} ExaScreenPrivRec, *ExaScreenPrivPtr;
extern DevPrivateKeyRec exaScreenPrivateKeyRec;
extern DevPrivateKeyRec exaPixmapPrivateKeyRec;
extern DevPrivateKeyRec exaGcPrivateKeyRec;
#define exaScreenPrivateKey (&exaScreenPrivateKeyRec)
#define ExaGetScreenPriv(s) ((ExaScreenPrivPtr)dixGetPrivate(&(s)->devPrivates, exaScreenPrivateKey))
#define ExaScreenPriv(s) ExaScreenPrivPtr pExaScr = ExaGetScreenPriv(s)
#define ExaGetGCPriv(gc) ((ExaGCPrivPtr)dixGetPrivateAddr(&(gc)->devPrivates, &ExaGetScreenPriv(gc->pScreen)->gcPrivateKeyRec))
#define ExaGetGCPriv(gc) ((ExaGCPrivPtr)dixGetPrivateAddr(&(gc)->devPrivates, &exaGcPrivateKeyRec))
#define ExaGCPriv(gc) ExaGCPrivPtr pExaGC = ExaGetGCPriv(gc)
/*
@ -272,7 +271,7 @@ extern DevPrivateKeyRec exaScreenPrivateKeyRec;
#define EXA_PIXMAP_SCORE_PINNED 1000
#define EXA_PIXMAP_SCORE_INIT 1001
#define ExaGetPixmapPriv(p) ((ExaPixmapPrivPtr)dixGetPrivateAddr(&(p)->devPrivates, &ExaGetScreenPriv((p)->drawable.pScreen)->pixmapPrivateKeyRec))
#define ExaGetPixmapPriv(p) ((ExaPixmapPrivPtr)dixGetPrivateAddr(&(p)->devPrivates, &exaPixmapPrivateKeyRec))
#define ExaPixmapPriv(p) ExaPixmapPrivPtr pExaPixmap = ExaGetPixmapPriv(p)
#define EXA_RANGE_PITCH (1 << 0)

View file

@ -26,19 +26,36 @@
#include "fb.h"
/* per-screen private data */
static DevPrivateKeyRec fbScreenPrivKeyRec;
#define fbScreenPrivKey (&fbScreenPrivKeyRec)
typedef struct {
CloseScreenProcPtr CloseScreen;
} fbScreenRec, *fbScreenPtr;
#define fbGetScreenPriv(s) ((fbScreenPtr)(dixLookupPrivate(&(s)->devPrivates, fbScreenPrivKey)))
Bool
fbCloseScreen(ScreenPtr pScreen)
{
int d;
DepthPtr depths = pScreen->allowedDepths;
fbScreenPtr pScreenPriv = fbGetScreenPriv(pScreen);
fbDestroyGlyphCache();
for (d = 0; d < pScreen->numDepths; d++)
free(depths[d].vids);
free(depths);
free(pScreen->visuals);
if (pScreen->devPrivate)
FreePixmap((PixmapPtr)pScreen->devPrivate);
pScreen->CloseScreen = pScreenPriv->CloseScreen;
free(pScreenPriv);
if (pScreen->CloseScreen)
return (*pScreen->CloseScreen) (pScreen);
return TRUE;
}
@ -97,8 +114,20 @@ fbSetupScreen(ScreenPtr pScreen, void *pbits, /* pointer to screen bitmap */
int dpiy, int width, /* pixel width of frame buffer */
int bpp)
{ /* bits per pixel for screen */
fbScreenPtr pScreenPriv;
if (!fbAllocatePrivates(pScreen))
return FALSE;
if (!dixRegisterPrivateKey(&fbScreenPrivKeyRec, PRIVATE_SCREEN, 0))
return FALSE;
pScreenPriv = calloc(1, sizeof(fbScreenRec));
if (!pScreenPriv)
return FALSE;
dixSetPrivate(&pScreen->devPrivates, fbScreenPrivKey, pScreenPriv);
pScreen->defColormap = FakeClientID(0);
if (bpp > 1) {
/* let CreateDefColormap do whatever it wants for pixels */
@ -156,6 +185,7 @@ fbFinishScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize,
int ndepths;
int rootdepth;
VisualID defaultVisual;
fbScreenPtr pScreenPriv = fbGetScreenPriv(pScreen);
#ifdef FB_DEBUG
int stride;
@ -184,6 +214,7 @@ fbFinishScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize,
defaultVisual, nvisuals, visuals))
return FALSE;
/* overwrite miCloseScreen with our own */
pScreenPriv->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = fbCloseScreen;
return TRUE;
}

View file

@ -823,6 +823,11 @@ glamor_egl_close_screen(ScreenPtr screen)
eglDestroyImageKHR(glamor_egl->display, pixmap_priv->image);
pixmap_priv->image = NULL;
if (glamor_egl->device_path) {
free(glamor_egl->device_path);
glamor_egl->device_path = NULL;
}
screen->CloseScreen = glamor_egl->saved_close_screen;
return screen->CloseScreen(screen);
@ -971,7 +976,6 @@ static void glamor_egl_cleanup(struct glamor_egl_screen_private *glamor_egl)
}
if (glamor_egl->gbm)
gbm_device_destroy(glamor_egl->gbm);
free(glamor_egl->device_path);
free(glamor_egl);
}

View file

@ -111,6 +111,7 @@ typedef struct _DRI2Screen {
unsigned int numDrivers;
const char **driverNames;
const char *deviceName;
const char *driverName;
int fd;
unsigned int lastSequence;
int prime_id;
@ -1454,7 +1455,7 @@ dri2_probe_driver_name(ScreenPtr pScreen, DRI2InfoPtr info)
#ifdef WITH_LIBDRM
int i, j;
char *driver = NULL;
drmDevicePtr dev;
drmDevicePtr dev = NULL;
/* For non-PCI devices and drmGetDevice fail, just assume that
* the 3D driver is named the same as the kernel driver. This is
@ -1472,6 +1473,7 @@ dri2_probe_driver_name(ScreenPtr pScreen, DRI2InfoPtr info)
driver = strndup(version->name, version->name_len);
drmFreeVersion(version);
drmFreeDevice(&dev);
return driver;
}
@ -1615,9 +1617,8 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
if (info->driverName) {
ds->driverNames[0] = info->driverName;
} else {
/* FIXME dri2_probe_driver_name() returns a strdup-ed string,
* currently this gets leaked */
ds->driverNames[0] = ds->driverNames[1] = dri2_probe_driver_name(pScreen, info);
ds->driverName = dri2_probe_driver_name(pScreen, info);
ds->driverNames[0] = ds->driverNames[1] = ds->driverName;
if (!ds->driverNames[0])
return FALSE;
@ -1673,6 +1674,7 @@ DRI2CloseScreen(ScreenPtr pScreen)
if (ds->prime_id)
prime_id_allocate_bitmask &= ~(1 << ds->prime_id);
free(ds->driverNames);
free((char *)ds->driverName);
free(ds);
dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, NULL);
}

View file

@ -1063,6 +1063,7 @@ ms_dri2_screen_init(ScreenPtr screen)
info.fd = ms->fd;
info.driverName = NULL; /* Compat field, unused. */
info.deviceName = drmGetDeviceNameFromFd(ms->fd);
ms->drmmode.dri2_device_name = info.deviceName;
info.version = 9;
info.CreateBuffer = ms_dri2_create_buffer;
@ -1108,7 +1109,12 @@ ms_dri2_screen_init(ScreenPtr screen)
void
ms_dri2_close_screen(ScreenPtr screen)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
modesettingPtr ms = modesettingPTR(scrn);
DRI2CloseScreen(screen);
free((char *)ms->drmmode.dri2_device_name);
}
#endif /* GLAMOR_HAS_GBM */

View file

@ -57,7 +57,6 @@
#include "xf86Crtc.h"
#include "miscstruct.h"
#include "dixstruct.h"
#include "xf86xv.h"
#include <xorg-config.h>
#ifdef XSERVER_PLATFORM_BUS
#include "xf86platformBus.h"
@ -2135,11 +2134,9 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
#ifdef GLAMOR_HAS_GBM
if (ms->drmmode.glamor) {
XF86VideoAdaptorPtr glamor_adaptor;
glamor_adaptor = ms->glamor.xv_init(pScreen, 16);
if (glamor_adaptor != NULL)
xf86XVScreenInit(pScreen, &glamor_adaptor, 1);
ms->adaptor = ms->glamor.xv_init(pScreen, 16);
if (ms->adaptor != NULL)
xf86XVScreenInit(pScreen, &ms->adaptor, 1);
else
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to initialize XV support.\n");
@ -2327,6 +2324,11 @@ CloseScreen(ScreenPtr pScreen)
PointPriv->spriteFuncs = ms->SpriteFuncs;
}
if (ms->adaptor) {
free(ms->adaptor);
ms->adaptor = NULL;
}
if (pScrn->vtSema) {
LeaveVT(pScrn);
}
@ -2334,6 +2336,8 @@ CloseScreen(ScreenPtr pScreen)
pScreen->CreateScreenResources = ms->createScreenResources;
pScreen->BlockHandler = ms->BlockHandler;
xf86_cursors_fini(pScreen);
pScrn->vtSema = FALSE;
pScreen->CloseScreen = ms->CloseScreen;
return (*pScreen->CloseScreen) (pScreen);

View file

@ -32,6 +32,7 @@
#include <errno.h>
#include <drm.h>
#include <xf86drm.h>
#include <xf86xv.h>
#include <xf86Crtc.h>
#include <damage.h>
#include <X11/extensions/dpmsconst.h>
@ -181,6 +182,8 @@ typedef struct _modesettingRec {
const char *(*egl_get_driver_name)(ScreenPtr);
} glamor;
#endif
XF86VideoAdaptorPtr adaptor;
} modesettingRec, *modesettingPtr;
#define glamor_finish(screen) ms->glamor.finish(screen)

View file

@ -3030,6 +3030,10 @@ drmmode_output_create_resources(xf86OutputPtr output)
drmModePropertyPtr drmmode_prop;
int i, j, err;
/* already created */
if (drmmode_output->props)
return;
drmmode_output->props =
calloc(mode_output->count_props, sizeof(drmmode_prop_rec));
if (!drmmode_output->props)
@ -3511,6 +3515,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r
DRM_MODE_OBJECT_CONNECTOR);
drmmode_prop_info_update(drmmode, drmmode_output->props_connector,
DRMMODE_CONNECTOR__COUNT, props);
drmModeFreeObjectProperties(props);
} else {
drmmode_output->dpms_enum_id =
koutput_get_prop_id(drmmode->fd, koutput, DRM_MODE_PROP_ENUM,

View file

@ -127,6 +127,8 @@ typedef struct {
PixmapPtr fbcon_pixmap;
const char *dri2_device_name;
Bool dri2_flipping;
Bool present_flipping;
Bool flip_bo_import_failed;

View file

@ -170,9 +170,11 @@ ms_pageflip_abort(void *data)
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
modesettingPtr ms = modesettingPTR(scrn);
if (flipdata->flip_count == 1)
if (flipdata->flip_count == 1) {
flipdata->abort_handler(ms, flipdata->event);
drmModeRmFB(ms->fd, flipdata->old_fb_id);
}
ms_pageflip_free(flip);
}

View file

@ -305,8 +305,20 @@ xf86RotateCloseScreen(ScreenPtr screen)
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
int c;
/* This has already been destroyed when the root window was destroyed */
xf86_config->rotation_damage = NULL;
if (xf86_config->rotation_damage) {
if (xf86_config->rotation_damage_registered) {
/*
* This has already been destroyed when the root window
* was destroyed
*/
xf86_config->rotation_damage_registered = FALSE;
} else {
/* Free damage structure */
DamageDestroy(xf86_config->rotation_damage);
}
xf86_config->rotation_damage = NULL;
}
for (c = 0; c < xf86_config->num_crtc; c++)
xf86RotateDestroy(xf86_config->crtc[c]);
}

View file

@ -53,6 +53,17 @@ from The Open Group.
* detail to the whole server.
*/
/* per-screen private data */
static DevPrivateKeyRec miScreenPrivKeyRec;
#define miScreenPrivKey (&miScreenPrivKeyRec)
typedef struct {
CloseScreenProcPtr CloseScreen;
} miScreenRec, *miScreenPtr;
#define miGetScreenPriv(s) ((miScreenPtr)(dixLookupPrivate(&(s)->devPrivates, miScreenPrivKey)))
typedef struct {
void *pbits; /* pointer to framebuffer */
int width; /* delta to add to a framebuffer addr to move one row down */
@ -126,7 +137,18 @@ miModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
static Bool
miCloseScreen(ScreenPtr pScreen)
{
return ((*pScreen->DestroyPixmap) ((PixmapPtr) pScreen->devPrivate));
miScreenPtr pScreenPriv = miGetScreenPriv(pScreen);
((*pScreen->DestroyPixmap) ((PixmapPtr) pScreen->devPrivate));
pScreen->CloseScreen = pScreenPriv->CloseScreen;
free(pScreenPriv);
if (pScreen->CloseScreen)
return (*pScreen->CloseScreen) (pScreen);
return TRUE;
}
static Bool
@ -235,6 +257,17 @@ miScreenInit(ScreenPtr pScreen, void *pbits, /* pointer to screen bits */
VisualRec * visuals /* supported visuals */
)
{
miScreenPtr pScreenPriv;
if (!dixRegisterPrivateKey(&miScreenPrivKeyRec, PRIVATE_SCREEN, 0))
return FALSE;
pScreenPriv = calloc(1, sizeof(miScreenRec));
if (!pScreenPriv)
return FALSE;
dixSetPrivate(&pScreen->devPrivates, miScreenPrivKey, pScreenPriv);
pScreen->width = xsize;
pScreen->height = ysize;
pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10);
@ -259,6 +292,7 @@ miScreenInit(ScreenPtr pScreen, void *pbits, /* pointer to screen bits */
#ifdef MITSHM
ShmRegisterFbFuncs(pScreen);
#endif
pScreenPriv->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = miCloseScreen;
}
/* else CloseScreen */

View file

@ -34,6 +34,7 @@ static DevPrivateKeyRec syncFdScreenPrivateKey;
typedef struct _SyncFdScreenPrivate {
SyncFdScreenFuncsRec funcs;
CloseScreenProcPtr CloseScreen;
} SyncFdScreenPrivateRec, *SyncFdScreenPrivatePtr;
static inline SyncFdScreenPrivatePtr sync_fd_screen_priv(ScreenPtr pScreen)
@ -66,6 +67,20 @@ miSyncFDFromFence(DrawablePtr pDraw, SyncFence *pFence)
return (*priv->funcs.GetFenceFd)(pDraw->pScreen, pFence);
}
static Bool
miSyncFdCloseScreen(ScreenPtr pScreen)
{
SyncFdScreenPrivatePtr priv = sync_fd_screen_priv(pScreen);
pScreen->CloseScreen = priv->CloseScreen;
free(priv);
if (pScreen->CloseScreen)
return (*pScreen->CloseScreen) (pScreen);
return TRUE;
}
Bool miSyncFdScreenInit(ScreenPtr pScreen,
const SyncFdScreenFuncsRec *funcs)
{
@ -93,6 +108,9 @@ Bool miSyncFdScreenInit(ScreenPtr pScreen,
priv->funcs = *funcs;
priv->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = miSyncFdCloseScreen;
dixSetPrivate(&pScreen->devPrivates, &syncFdScreenPrivateKey, priv);
return TRUE;