Re: [RFC] glx: fix DRI2 memory leak

2009-04-09 Thread Kristian Høgsberg
On Wed, Mar 25, 2009 at 10:21:51AM -0700, Jesse Barnes wrote:
 In trying to track down the memory leak in 20704, I found that the DRI2
 drawable destroy routine doesn't seem to get called when new drawables
 are created and old ones destroyed (as in the glViewport case in the
 bug).

Ok, sorry for taking so long on this.  Here's the patch I'd like to push
to fix the problem - let me know if it works alright.

thanks,
Kristian

From 2f2538d20291ead2187087228a391dade1a0434f Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Kristian=20H=C3=B8gsberg?= k...@redhat.com
Date: Thu, 9 Apr 2009 13:16:37 -0400
Subject: [PATCH] glx: Fix drawable private leak on destroy

When a drawable goes away, we don't destroy the GLX drawable in full,
since it may be current for a context.  This means that when the drawable
is destroyed in full later, the backend doesn't get a chance to
destroy resources associated with the drawable (the DRI2Drawable).

With this patch, we destroy the GLX drawable in full when it goes away
and then track down all contexts that reference it and NULL their
pointers.
---
 glx/Makefile.am|1 -
 glx/glxcmds.c  |   44 --
 glx/glxdrawable.h  |5 ---
 glx/glxdri.c   |2 +
 glx/glxdri2.c  |2 +
 glx/glxdriswrast.c |2 +
 glx/glxext.c   |   42 +
 glx/glxext.h   |1 +
 glx/glxutil.c  |   74 
 glx/glxutil.h  |9 +-
 10 files changed, 67 insertions(+), 115 deletions(-)
 delete mode 100644 glx/glxutil.c

diff --git a/glx/Makefile.am b/glx/Makefile.am
index 2537db8..a23ae0a 100644
--- a/glx/Makefile.am
+++ b/glx/Makefile.am
@@ -80,7 +80,6 @@ libglx_la_SOURCES = \
 glxscreens.c \
 glxscreens.h \
 glxserver.h \
-glxutil.c \
 glxutil.h \
 render2.c \
 render2swap.c \
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index e21f0f0..86e8dd8 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -193,18 +193,9 @@ validGlxDrawable(ClientPtr client, XID id, int type, int 
access_mode,
 void
 __glXContextDestroy(__GLXcontext *context)
 {
-if (!context-isDirect) {
-   if (context-drawPriv)
-   __glXUnrefDrawable(context-drawPriv);
-   if (context-readPriv)
-   __glXUnrefDrawable(context-readPriv);
-   context-drawPriv = NULL;
-   context-readPriv = NULL;
-}
 __glXFlushContextCache();
 }
 
-
 static void __glXdirectContextDestroy(__GLXcontext *context)
 {
 __glXContextDestroy(context);
@@ -320,6 +311,8 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
 glxc-isDirect = isDirect;
 glxc-renderMode = GL_RENDER;
 
+__glXAddToContextList(glxc);
+
 return Success;
 }
 
@@ -639,10 +632,6 @@ DoMakeCurrent(__GLXclientState *cl,
}
__glXFlushContextCache();
if (!prevglxc-isDirect) {
-   if (prevglxc-drawPriv)
-   __glXUnrefDrawable(prevglxc-drawPriv);
-   if (prevglxc-readPriv)
-   __glXUnrefDrawable(prevglxc-readPriv);
prevglxc-drawPriv = NULL;
prevglxc-readPriv = NULL;
}
@@ -662,8 +651,6 @@ DoMakeCurrent(__GLXclientState *cl,
}
 
glxc-isCurrent = GL_TRUE;
-   __glXRefDrawable(glxc-drawPriv);
-   __glXRefDrawable(glxc-readPriv);
 }
 
 if (prevglxc) {
@@ -1090,6 +1077,33 @@ int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, 
GLbyte *pc)
 return DoGetFBConfigs(cl, req-screen);
 }
 
+GLboolean
+__glXDrawableInit(__GLXdrawable *drawable,
+ __GLXscreen *screen, DrawablePtr pDraw, int type,
+ XID drawId, __GLXconfig *config)
+{
+drawable-pDraw = pDraw;
+drawable-type = type;
+drawable-drawId = drawId;
+drawable-config = config;
+drawable-eventMask = 0;
+
+return GL_TRUE;
+}
+
+void
+__glXDrawableRelease(__GLXdrawable *drawable)
+{
+ScreenPtr pScreen = drawable-pDraw-pScreen;
+
+switch (drawable-type) {
+case GLX_DRAWABLE_PIXMAP:
+case GLX_DRAWABLE_PBUFFER:
+   (*pScreen-DestroyPixmap)((PixmapPtr) drawable-pDraw);
+   break;
+}
+}
+
 static int 
 DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig 
*config,
DrawablePtr pDraw, XID glxDrawableId, int type)
diff --git a/glx/glxdrawable.h b/glx/glxdrawable.h
index b64ff35..0215b3b 100644
--- a/glx/glxdrawable.h
+++ b/glx/glxdrawable.h
@@ -67,11 +67,6 @@ struct __GLXdrawable {
 */
 __GLXconfig *config;
 
-/*
-** reference count
-*/
-int refCount;
-
 GLenum target;
 GLenum format;
 
diff --git a/glx/glxdri.c b/glx/glxdri.c
index cc6d939..eeac7fc 100644
--- a/glx/glxdri.c
+++ b/glx/glxdri.c
@@ -238,6 +238,8 @@ __glXDRIdrawableDestroy(__GLXdrawable *drawable)
__glXleaveServer(GL_FALSE);
 }
 
+__glXDrawableRelease(drawable);
+
 xfree(private);
 }
 
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index c896536..44c2337 100644

Re: [RFC] glx: fix DRI2 memory leak

2009-04-07 Thread Michel Dänzer
On Mon, 2009-04-06 at 14:57 -0700, Jesse Barnes wrote:
 On Wed, 01 Apr 2009 17:46:08 +0200
 Michel Dänzer mic...@daenzer.net wrote:
  The real problem was pointed out by Pierre Willenbrock: If
  glxPriv-pDraw is a pixmap, DrawableGone() destroys it, then later
  DRI2DestroyDrawable dereferences it... The patch below seems to work
  here - at least it hasn't crashed in a couple of hours, not sure about
  the leak yet.
  
  Note that unless I'm missing something, it might still be possible for
  this to occur with windows if the underlying DrawableRec is freed
  before this code is reached.
  
  Also, I don't really understand the logic behind clearing
  glxPriv-pDraw and -drawId here. In particular, I'm not sure
  DrawableGone will ever be called with glxPriv-refCount  1. If it
  won't, this change makes the assignments unreachable. And if it will,
  we'll again leak because the cleanup code won't be able to get to the
  underlying DrawableRec?
 
 So are you happy enough with this fix to push it, Michel?  Memory usage
 is still high on Intel after the fix, but that may be due to bo
 caching, and this is an important fix...

Feel free to push it. It's not really my fix, I just combined the fixes
and suggestions from others. :)


-- 
Earthling Michel Dänzer   |http://www.vmware.com
Libre software enthusiast |  Debian, X and DRI developer
___
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg

Re: [RFC] glx: fix DRI2 memory leak

2009-04-06 Thread Jesse Barnes
On Wed, 01 Apr 2009 17:46:08 +0200
Michel Dänzer mic...@daenzer.net wrote:
 The real problem was pointed out by Pierre Willenbrock: If
 glxPriv-pDraw is a pixmap, DrawableGone() destroys it, then later
 DRI2DestroyDrawable dereferences it... The patch below seems to work
 here - at least it hasn't crashed in a couple of hours, not sure about
 the leak yet.
 
 Note that unless I'm missing something, it might still be possible for
 this to occur with windows if the underlying DrawableRec is freed
 before this code is reached.
 
 Also, I don't really understand the logic behind clearing
 glxPriv-pDraw and -drawId here. In particular, I'm not sure
 DrawableGone will ever be called with glxPriv-refCount  1. If it
 won't, this change makes the assignments unreachable. And if it will,
 we'll again leak because the cleanup code won't be able to get to the
 underlying DrawableRec?

So are you happy enough with this fix to push it, Michel?  Memory usage
is still high on Intel after the fix, but that may be due to bo
caching, and this is an important fix...

Thanks,
-- 
Jesse Barnes, Intel Open Source Technology Center
___
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg

Re: [RFC] glx: fix DRI2 memory leak

2009-04-02 Thread Kristian Høgsberg
2009/4/1 Michel Dänzer mic...@daenzer.net:
 On Mon, 2009-03-30 at 13:04 +0800, Shuang He wrote:
 Shuang He wrote:
  Jesse Barnes wrote:
   On Fri, 27 Mar 2009 13:20:25 -0400
   Kristian Høgsberg k...@bitplanet.net wrote:
   
The leak is (as you pointed out before) because we NULL the pDraw
pointer before calling the backend destructor, which then can't unref
the DRI2Drawable, which we then leak.  You had the right fix in the
originial post, we just need to not touch glxPriv after
__glXUnrefDrawable if it got destroyed.  I suggest this change to
DrawableGone in irc:
   
    refcount = glxPriv-refcount;
    __glXUnrefDrawable(glxPriv);
    if (refcount  1) {
        glxPriv-pDraw = NULL;
        glxPriv-drawId = 0;
    }
   
  
   Yep, that seems to work too...  Magnus or Vasily can you guys confirm?
  
  Memory leak problem seems resolved, but I still see X crash with:
  (gdb) bt
  #0  0xb7fd5424 in __kernel_vsyscall ()
  #1  0x03155660 in raise () from /lib/libc.so.6
  #2  0x03157028 in abort () from /lib/libc.so.6
  #3  0x031925bd in __libc_message () from /lib/libc.so.6
  #4  0x031987e4 in malloc_printerr () from /lib/libc.so.6
  #5  0x0319c441 in _int_realloc () from /lib/libc.so.6
  #6  0x0319d176 in realloc () from /lib/libc.so.6
  #7  0x08131002 in Xrealloc (ptr=0x6, amount=0) at utils.c:1133
  #8  0x0806d10b in dixAllocatePrivate (privates=0x91487c8, key=0xb7e90a3c)
      at privates.c:129
  #9  0x0806d1cc in dixSetPrivate (privates=0x91487c8, key=0xb7e90a3c, 
  val=0x0)
      at privates.c:193
  #10 0xb7e8eca1 in DRI2DestroyDrawable (pDraw=0x91487b0) at dri2.c:218
  #11 0xb7eee668 in __glXDRIdrawableDestroy (drawable=0x9205ff0) at 
  glxdri2.c:108
  #12 0xb7ee49bb in __glXUnrefDrawable (glxPriv=0x9205ff0) at glxutil.c:58
  #13 0xb7ee3183 in DrawableGone (glxPriv=0x9205ff0, xid=12583326)
      at glxext.c:131
  #14 0x0806efdc in FreeResource (id=12583326, skipDeleteFuncType=0)
      at resource.c:561
  #15 0xb7edffa6 in DoDestroyDrawable (cl=value optimized out,
      glxdrawable=12583326, type=1) at glxcmds.c:1225
  #16 0xb7ee340a in __glXDispatch (client=0x8d79db8) at glxext.c:523
  #17 0x080874cf in Dispatch () at dispatch.c:437
  ---Type return to continue, or q return to quit---
  #18 0x0806c69d in main (argc=2, argv=0xbf9d2754, envp=Cannot access memory 
  at
  address 0xbde

 Just debug a bit, check out this series of calls in DRI2DestroyDrawable when 
 X
 crashed:
 in (*ds-DestroyBuffers)(pDraw, pPriv-buffers, pPriv-bufferCount);
   Xfree: free(0x9eef330)
   Xfree: free(0x9eeef20)
   Xfree: free(0x9efdde0)
   Xfree: free(0x9efce08)
   Xfree: free(0x9eee8b0)
   Xrealloc: ptr = 0x9efaf20
   Xrealloc: amount = 384
   Xfree: free(0x9efcd18)
   Xfree: free(0x9ef8468)
   Xrealloc: ptr = 0x9efa278
   Xrealloc: amount = 384
   Xfree: free(0x9efcd18)
   Xfree: free(0x9ef9808)
   Xfree: free(0x9eeef38)
   Xfree: free(0x9efa648)
   Xfree: free(0x9efd788)
 in dixSetPrivate(pPixmap-devPrivates, dri2PixmapPrivateKey, NULL);
   Xrealloc: ptr = 0x9efce08
   Xrealloc: amount = 512

 So dixSetPrivate is trying to realloc memory at 0x9efce08, which is alreay
 freed  in DetroyBuffers. So maybe we should also do this: [...]

 The real problem was pointed out by Pierre Willenbrock: If
 glxPriv-pDraw is a pixmap, DrawableGone() destroys it, then later
 DRI2DestroyDrawable dereferences it... The patch below seems to work
 here - at least it hasn't crashed in a couple of hours, not sure about
 the leak yet.

 Note that unless I'm missing something, it might still be possible for
 this to occur with windows if the underlying DrawableRec is freed before
 this code is reached.

 Also, I don't really understand the logic behind clearing glxPriv-pDraw
 and -drawId here. In particular, I'm not sure DrawableGone will ever be
 called with glxPriv-refCount  1. If it won't, this change makes the
 assignments unreachable. And if it will, we'll again leak because the
 cleanup code won't be able to get to the underlying DrawableRec?

We reference the glxPriv when we make it current for a context.  If
the drawable is destroyed while it's current for a context,
DrawableGone will be called with refcount at least 2.  Clearing
glxPriv-pDraw is done in this case so that when the context the
drawable is current for is destroyed, we don't try to dereference the
pointer to the destroyed drawable.  But yes, as you mention, then
there's a leak when the glxdri2.c destroy function can't get at the
pDraw to destroy the DRI2Drawable.

 diff --git a/glx/glxext.c b/glx/glxext.c
 index c882372..e74d00e 100644
 --- a/glx/glxext.c
 +++ b/glx/glxext.c
 @@ -119,17 +119,25 @@ static int ContextGone(__GLXcontext* cx, XID id)
  static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
  {
     ScreenPtr pScreen = glxPriv-pDraw-pScreen;
 +    PixmapPtr pPixmap = NULL;
 +    int refcount;

     switch (glxPriv-type) {
        case GLX_DRAWABLE_PIXMAP:
        case GLX_DRAWABLE_PBUFFER:
 -           

Re: [RFC] glx: fix DRI2 memory leak

2009-04-01 Thread Michel Dänzer
On Mon, 2009-03-30 at 13:04 +0800, Shuang He wrote:
 Shuang He wrote: 
  Jesse Barnes wrote: 
   On Fri, 27 Mar 2009 13:20:25 -0400
   Kristian Høgsberg k...@bitplanet.net wrote:

The leak is (as you pointed out before) because we NULL the pDraw
pointer before calling the backend destructor, which then can't unref
the DRI2Drawable, which we then leak.  You had the right fix in the
originial post, we just need to not touch glxPriv after
__glXUnrefDrawable if it got destroyed.  I suggest this change to
DrawableGone in irc:

refcount = glxPriv-refcount;
__glXUnrefDrawable(glxPriv);
if (refcount  1) {
glxPriv-pDraw = NULL;
glxPriv-drawId = 0;
}

   
   Yep, that seems to work too...  Magnus or Vasily can you guys confirm?
 
  Memory leak problem seems resolved, but I still see X crash with:
  (gdb) bt
  #0  0xb7fd5424 in __kernel_vsyscall ()
  #1  0x03155660 in raise () from /lib/libc.so.6
  #2  0x03157028 in abort () from /lib/libc.so.6
  #3  0x031925bd in __libc_message () from /lib/libc.so.6
  #4  0x031987e4 in malloc_printerr () from /lib/libc.so.6
  #5  0x0319c441 in _int_realloc () from /lib/libc.so.6
  #6  0x0319d176 in realloc () from /lib/libc.so.6
  #7  0x08131002 in Xrealloc (ptr=0x6, amount=0) at utils.c:1133
  #8  0x0806d10b in dixAllocatePrivate (privates=0x91487c8, key=0xb7e90a3c)
  at privates.c:129
  #9  0x0806d1cc in dixSetPrivate (privates=0x91487c8, key=0xb7e90a3c, 
  val=0x0)
  at privates.c:193
  #10 0xb7e8eca1 in DRI2DestroyDrawable (pDraw=0x91487b0) at dri2.c:218
  #11 0xb7eee668 in __glXDRIdrawableDestroy (drawable=0x9205ff0) at 
  glxdri2.c:108
  #12 0xb7ee49bb in __glXUnrefDrawable (glxPriv=0x9205ff0) at glxutil.c:58
  #13 0xb7ee3183 in DrawableGone (glxPriv=0x9205ff0, xid=12583326)
  at glxext.c:131
  #14 0x0806efdc in FreeResource (id=12583326, skipDeleteFuncType=0)
  at resource.c:561
  #15 0xb7edffa6 in DoDestroyDrawable (cl=value optimized out,
  glxdrawable=12583326, type=1) at glxcmds.c:1225
  #16 0xb7ee340a in __glXDispatch (client=0x8d79db8) at glxext.c:523
  #17 0x080874cf in Dispatch () at dispatch.c:437
  ---Type return to continue, or q return to quit---
  #18 0x0806c69d in main (argc=2, argv=0xbf9d2754, envp=Cannot access memory 
  at
  address 0xbde
 
 Just debug a bit, check out this series of calls in DRI2DestroyDrawable when X
 crashed:
 in (*ds-DestroyBuffers)(pDraw, pPriv-buffers, pPriv-bufferCount);
   Xfree: free(0x9eef330)
   Xfree: free(0x9eeef20)
   Xfree: free(0x9efdde0)
   Xfree: free(0x9efce08)
   Xfree: free(0x9eee8b0)
   Xrealloc: ptr = 0x9efaf20
   Xrealloc: amount = 384
   Xfree: free(0x9efcd18)
   Xfree: free(0x9ef8468)
   Xrealloc: ptr = 0x9efa278
   Xrealloc: amount = 384
   Xfree: free(0x9efcd18)
   Xfree: free(0x9ef9808)
   Xfree: free(0x9eeef38)
   Xfree: free(0x9efa648)
   Xfree: free(0x9efd788)
 in dixSetPrivate(pPixmap-devPrivates, dri2PixmapPrivateKey, NULL);
   Xrealloc: ptr = 0x9efce08
   Xrealloc: amount = 512
 
 So dixSetPrivate is trying to realloc memory at 0x9efce08, which is alreay
 freed  in DetroyBuffers. So maybe we should also do this: [...]

The real problem was pointed out by Pierre Willenbrock: If
glxPriv-pDraw is a pixmap, DrawableGone() destroys it, then later
DRI2DestroyDrawable dereferences it... The patch below seems to work
here - at least it hasn't crashed in a couple of hours, not sure about
the leak yet.

Note that unless I'm missing something, it might still be possible for
this to occur with windows if the underlying DrawableRec is freed before
this code is reached.

Also, I don't really understand the logic behind clearing glxPriv-pDraw
and -drawId here. In particular, I'm not sure DrawableGone will ever be
called with glxPriv-refCount  1. If it won't, this change makes the
assignments unreachable. And if it will, we'll again leak because the
cleanup code won't be able to get to the underlying DrawableRec?


diff --git a/glx/glxext.c b/glx/glxext.c
index c882372..e74d00e 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -119,17 +119,25 @@ static int ContextGone(__GLXcontext* cx, XID id)
 static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
 {
 ScreenPtr pScreen = glxPriv-pDraw-pScreen;
+PixmapPtr pPixmap = NULL;
+int refcount;
 
 switch (glxPriv-type) {
case GLX_DRAWABLE_PIXMAP:
case GLX_DRAWABLE_PBUFFER:
-   (*pScreen-DestroyPixmap)((PixmapPtr) glxPriv-pDraw);
+   pPixmap = (PixmapPtr) glxPriv-pDraw;
break;
 }
 
-glxPriv-pDraw = NULL;
-glxPriv-drawId = 0;
+refcount = glxPriv-refCount;
 __glXUnrefDrawable(glxPriv);
+if (refcount  1) {
+   glxPriv-pDraw = NULL;
+   glxPriv-drawId = 0;
+}
+
+if (pPixmap)
+   (*pScreen-DestroyPixmap)(pPixmap);
 
 return True;
 }


-- 
Earthling Michel Dänzer   |http://www.vmware.com
Libre software enthusiast |  

Re: [RFC] glx: fix DRI2 memory leak

2009-04-01 Thread Shuang He

Michel Dänzer wrote:

On Mon, 2009-03-30 at 13:04 +0800, Shuang He wrote:
  
Shuang He wrote: 

Jesse Barnes wrote: 
  

On Fri, 27 Mar 2009 13:20:25 -0400
Kristian Høgsberg k...@bitplanet.net wrote:


The leak is (as you pointed out before) because we NULL the pDraw
pointer before calling the backend destructor, which then can't unref
the DRI2Drawable, which we then leak.  You had the right fix in the
originial post, we just need to not touch glxPriv after
__glXUnrefDrawable if it got destroyed.  I suggest this change to
DrawableGone in irc:

refcount = glxPriv-refcount;
__glXUnrefDrawable(glxPriv);
if (refcount  1) {
glxPriv-pDraw = NULL;
glxPriv-drawId = 0;
}

  

Yep, that seems to work too...  Magnus or Vasily can you guys confirm?
  


Memory leak problem seems resolved, but I still see X crash with:
(gdb) bt
#0  0xb7fd5424 in __kernel_vsyscall ()
#1  0x03155660 in raise () from /lib/libc.so.6
#2  0x03157028 in abort () from /lib/libc.so.6
#3  0x031925bd in __libc_message () from /lib/libc.so.6
#4  0x031987e4 in malloc_printerr () from /lib/libc.so.6
#5  0x0319c441 in _int_realloc () from /lib/libc.so.6
#6  0x0319d176 in realloc () from /lib/libc.so.6
#7  0x08131002 in Xrealloc (ptr=0x6, amount=0) at utils.c:1133
#8  0x0806d10b in dixAllocatePrivate (privates=0x91487c8, key=0xb7e90a3c)
at privates.c:129
#9  0x0806d1cc in dixSetPrivate (privates=0x91487c8, key=0xb7e90a3c, val=0x0)
at privates.c:193
#10 0xb7e8eca1 in DRI2DestroyDrawable (pDraw=0x91487b0) at dri2.c:218
#11 0xb7eee668 in __glXDRIdrawableDestroy (drawable=0x9205ff0) at glxdri2.c:108
#12 0xb7ee49bb in __glXUnrefDrawable (glxPriv=0x9205ff0) at glxutil.c:58
#13 0xb7ee3183 in DrawableGone (glxPriv=0x9205ff0, xid=12583326)
at glxext.c:131
#14 0x0806efdc in FreeResource (id=12583326, skipDeleteFuncType=0)
at resource.c:561
#15 0xb7edffa6 in DoDestroyDrawable (cl=value optimized out,
glxdrawable=12583326, type=1) at glxcmds.c:1225
#16 0xb7ee340a in __glXDispatch (client=0x8d79db8) at glxext.c:523
#17 0x080874cf in Dispatch () at dispatch.c:437
---Type return to continue, or q return to quit---
#18 0x0806c69d in main (argc=2, argv=0xbf9d2754, envp=Cannot access memory at
address 0xbde
  

Just debug a bit, check out this series of calls in DRI2DestroyDrawable when X
crashed:
in (*ds-DestroyBuffers)(pDraw, pPriv-buffers, pPriv-bufferCount);
  Xfree: free(0x9eef330)
  Xfree: free(0x9eeef20)
  Xfree: free(0x9efdde0)
  Xfree: free(0x9efce08)
  Xfree: free(0x9eee8b0)
  Xrealloc: ptr = 0x9efaf20
  Xrealloc: amount = 384
  Xfree: free(0x9efcd18)
  Xfree: free(0x9ef8468)
  Xrealloc: ptr = 0x9efa278
  Xrealloc: amount = 384
  Xfree: free(0x9efcd18)
  Xfree: free(0x9ef9808)
  Xfree: free(0x9eeef38)
  Xfree: free(0x9efa648)
  Xfree: free(0x9efd788)
in dixSetPrivate(pPixmap-devPrivates, dri2PixmapPrivateKey, NULL);
  Xrealloc: ptr = 0x9efce08
  Xrealloc: amount = 512

So dixSetPrivate is trying to realloc memory at 0x9efce08, which is alreay
freed  in DetroyBuffers. So maybe we should also do this: [...]



The real problem was pointed out by Pierre Willenbrock: If
glxPriv-pDraw is a pixmap, DrawableGone() destroys it, then later
DRI2DestroyDrawable dereferences it... The patch below seems to work
here - at least it hasn't crashed in a couple of hours, not sure about
the leak yet.

Note that unless I'm missing something, it might still be possible for
this to occur with windows if the underlying DrawableRec is freed before
this code is reached.

Also, I don't really understand the logic behind clearing glxPriv-pDraw
and -drawId here. In particular, I'm not sure DrawableGone will ever be
called with glxPriv-refCount  1. If it won't, this change makes the
assignments unreachable. And if it will, we'll again leak because the
cleanup code won't be able to get to the underlying DrawableRec?


diff --git a/glx/glxext.c b/glx/glxext.c
index c882372..e74d00e 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -119,17 +119,25 @@ static int ContextGone(__GLXcontext* cx, XID id)
 static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
 {
 ScreenPtr pScreen = glxPriv-pDraw-pScreen;
+PixmapPtr pPixmap = NULL;
+int refcount;
 
 switch (glxPriv-type) {

case GLX_DRAWABLE_PIXMAP:
case GLX_DRAWABLE_PBUFFER:
-   (*pScreen-DestroyPixmap)((PixmapPtr) glxPriv-pDraw);
+   pPixmap = (PixmapPtr) glxPriv-pDraw;
break;
 }
 
-glxPriv-pDraw = NULL;

-glxPriv-drawId = 0;
+refcount = glxPriv-refCount;
 __glXUnrefDrawable(glxPriv);
+if (refcount  1) {
+   glxPriv-pDraw = NULL;
+   glxPriv-drawId = 0;
+}
+
+if (pPixmap)

+   (*pScreen-DestroyPixmap)(pPixmap);
 
 return True;

 }


  

This works for me. I don't see the memory leaks or X crashes.

Thanks
   --Shuang
___
xorg mailing list
xorg@lists.freedesktop.org

Re: [RFC] glx: fix DRI2 memory leak

2009-03-30 Thread Magnus Kessler
On Monday 30 March 2009, Shuang He wrote:
 Jesse Barnes wrote:
  On Fri, 27 Mar 2009 13:20:25 -0400
 
  Kristian Høgsberg k...@bitplanet.net wrote:
  On Thu, Mar 26, 2009 at 6:33 PM, Jesse Barnes
 
  jbar...@virtuousgeek.org wrote:
  Ok, I think this is where the leak was:
  __glXUnrefDrawable-DrawableGone-__glXUnrefDrawable.  This sequence
  meant the glxPriv would stay around (since it was used), but
  DrawableGone had generally already disposed of the pDrawable before
  the call to Unref, so we never got into DRI2DestroyBuffers, thus
  the leak.
 
  The loop seems broken to me.  It *looks* like DrawableGone should be
  the real free routine, only called when a drawable really is free,
  so I've fixed up the code to conform to that.  This means removing
  the GLX priv frees from DRI and DRI2 routines and putting them here
  and using the GLX unref routine everwhere (since it will only free
  the resource when the refcount reaches 0).
 
  Any thoughts?  I'd appreciate some more testers too...  I'm not
  quite sure about the generic DoDestroyDrawable change, but if the
  refcount is always 1 there anyway it shouldn't make a difference
  and seems more correct.
 
  The __GLXdrawable is a reference counted object, and the glx code
  references it in a couple of places: when there's an X resource
  pointing to it (a GLXWindow, GLXPixmap or GLXPbuffer) and when it's
  the current drawable or readable for a context.  The __GLXdrawable is
  allocated by the backend in use (dri, dri2 or swrast) and must be
  freed by the same backend (don't mix alloc and free across abstraction
  barriers).  We unref the __GLXdrawable when we either set a different
  drawable/readable and when the X resource goes away.
 
  The leak is (as you pointed out before) because we NULL the pDraw
  pointer before calling the backend destructor, which then can't unref
  the DRI2Drawable, which we then leak.  You had the right fix in the
  originial post, we just need to not touch glxPriv after
  __glXUnrefDrawable if it got destroyed.  I suggest this change to
  DrawableGone in irc:
 
  refcount = glxPriv-refcount;
  __glXUnrefDrawable(glxPriv);
  if (refcount  1) {
  glxPriv-pDraw = NULL;
  glxPriv-drawId = 0;
  }
 
  Yep, that seems to work too...  Magnus or Vasily can you guys confirm?
 
  Thanks,

 Memory leak problem seems resolved, but I still see X crash with:

 (gdb) bt
 #0  0xb7fd5424 in __kernel_vsyscall ()
 #1  0x03155660 in raise () from /lib/libc.so.6
 #2  0x03157028 in abort () from /lib/libc.so.6
 #3  0x031925bd in __libc_message () from /lib/libc.so.6
 #4  0x031987e4 in malloc_printerr () from /lib/libc.so.6
 #5  0x0319c441 in _int_realloc () from /lib/libc.so.6
 #6  0x0319d176 in realloc () from /lib/libc.so.6
 #7  0x08131002 in Xrealloc (ptr=0x6, amount=0) at utils.c:1133
 #8  0x0806d10b in dixAllocatePrivate (privates=0x91487c8, key=0xb7e90a3c)
 at privates.c:129
 #9  0x0806d1cc in dixSetPrivate (privates=0x91487c8, key=0xb7e90a3c,
 val=0x0) at privates.c:193
 #10 0xb7e8eca1 in DRI2DestroyDrawable (pDraw=0x91487b0) at dri2.c:218
 #11 0xb7eee668 in __glXDRIdrawableDestroy (drawable=0x9205ff0) at
 glxdri2.c:108 #12 0xb7ee49bb in __glXUnrefDrawable (glxPriv=0x9205ff0) at
 glxutil.c:58 #13 0xb7ee3183 in DrawableGone (glxPriv=0x9205ff0,
 xid=12583326) at glxext.c:131
 #14 0x0806efdc in FreeResource (id=12583326, skipDeleteFuncType=0)
 at resource.c:561
 #15 0xb7edffa6 in DoDestroyDrawable (cl=value optimized out,
 glxdrawable=12583326, type=1) at glxcmds.c:1225
 #16 0xb7ee340a in __glXDispatch (client=0x8d79db8) at glxext.c:523
 #17 0x080874cf in Dispatch () at dispatch.c:437
 ---Type return to continue, or q return to quit---
 #18 0x0806c69d in main (argc=2, argv=0xbf9d2754, envp=Cannot access
 memory at address 0xbde

 Thanks
   --Shuang
 ) at main.c:397

I have observed this crash once as well, but haven't yet found a way to 
reproduce it. Can you post a few steps that make this crash more likely? On 
the bug report (http://bugs.freedesktop.org/show_bug.cgi?id=20704) you 
mention it has something to do with resizing by small amounts.

Thanks

Magnus


___
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg


Re: [RFC] glx: fix DRI2 memory leak

2009-03-30 Thread Shuang He

Magnus Kessler wrote:

On Monday 30 March 2009, Shuang He wrote:
  

Jesse Barnes wrote:


On Fri, 27 Mar 2009 13:20:25 -0400

Kristian Høgsberg k...@bitplanet.net wrote:
  

On Thu, Mar 26, 2009 at 6:33 PM, Jesse Barnes

jbar...@virtuousgeek.org wrote:


Ok, I think this is where the leak was:
__glXUnrefDrawable-DrawableGone-__glXUnrefDrawable.  This sequence
meant the glxPriv would stay around (since it was used), but
DrawableGone had generally already disposed of the pDrawable before
the call to Unref, so we never got into DRI2DestroyBuffers, thus
the leak.

The loop seems broken to me.  It *looks* like DrawableGone should be
the real free routine, only called when a drawable really is free,
so I've fixed up the code to conform to that.  This means removing
the GLX priv frees from DRI and DRI2 routines and putting them here
and using the GLX unref routine everwhere (since it will only free
the resource when the refcount reaches 0).

Any thoughts?  I'd appreciate some more testers too...  I'm not
quite sure about the generic DoDestroyDrawable change, but if the
refcount is always 1 there anyway it shouldn't make a difference
and seems more correct.
  

The __GLXdrawable is a reference counted object, and the glx code
references it in a couple of places: when there's an X resource
pointing to it (a GLXWindow, GLXPixmap or GLXPbuffer) and when it's
the current drawable or readable for a context.  The __GLXdrawable is
allocated by the backend in use (dri, dri2 or swrast) and must be
freed by the same backend (don't mix alloc and free across abstraction
barriers).  We unref the __GLXdrawable when we either set a different
drawable/readable and when the X resource goes away.

The leak is (as you pointed out before) because we NULL the pDraw
pointer before calling the backend destructor, which then can't unref
the DRI2Drawable, which we then leak.  You had the right fix in the
originial post, we just need to not touch glxPriv after
__glXUnrefDrawable if it got destroyed.  I suggest this change to
DrawableGone in irc:

refcount = glxPriv-refcount;
__glXUnrefDrawable(glxPriv);
if (refcount  1) {
glxPriv-pDraw = NULL;
glxPriv-drawId = 0;
}


Yep, that seems to work too...  Magnus or Vasily can you guys confirm?

Thanks,
  

Memory leak problem seems resolved, but I still see X crash with:

(gdb) bt
#0  0xb7fd5424 in __kernel_vsyscall ()
#1  0x03155660 in raise () from /lib/libc.so.6
#2  0x03157028 in abort () from /lib/libc.so.6
#3  0x031925bd in __libc_message () from /lib/libc.so.6
#4  0x031987e4 in malloc_printerr () from /lib/libc.so.6
#5  0x0319c441 in _int_realloc () from /lib/libc.so.6
#6  0x0319d176 in realloc () from /lib/libc.so.6
#7  0x08131002 in Xrealloc (ptr=0x6, amount=0) at utils.c:1133
#8  0x0806d10b in dixAllocatePrivate (privates=0x91487c8, key=0xb7e90a3c)
at privates.c:129
#9  0x0806d1cc in dixSetPrivate (privates=0x91487c8, key=0xb7e90a3c,
val=0x0) at privates.c:193
#10 0xb7e8eca1 in DRI2DestroyDrawable (pDraw=0x91487b0) at dri2.c:218
#11 0xb7eee668 in __glXDRIdrawableDestroy (drawable=0x9205ff0) at
glxdri2.c:108 #12 0xb7ee49bb in __glXUnrefDrawable (glxPriv=0x9205ff0) at
glxutil.c:58 #13 0xb7ee3183 in DrawableGone (glxPriv=0x9205ff0,
xid=12583326) at glxext.c:131
#14 0x0806efdc in FreeResource (id=12583326, skipDeleteFuncType=0)
at resource.c:561
#15 0xb7edffa6 in DoDestroyDrawable (cl=value optimized out,
glxdrawable=12583326, type=1) at glxcmds.c:1225
#16 0xb7ee340a in __glXDispatch (client=0x8d79db8) at glxext.c:523
#17 0x080874cf in Dispatch () at dispatch.c:437
---Type return to continue, or q return to quit---
#18 0x0806c69d in main (argc=2, argv=0xbf9d2754, envp=Cannot access
memory at address 0xbde

Thanks
--Shuang
) at main.c:397



I have observed this crash once as well, but haven't yet found a way to 
reproduce it. Can you post a few steps that make this crash more likely? On 
the bug report (http://bugs.freedesktop.org/show_bug.cgi?id=20704) you 
mention it has something to do with resizing by small amounts.


Thanks

Magnus
  
I could easily reproduce this by just resizing the window several 
times.  Most of times, it's just costing 1 or 2 minutes.


Thanks
   --Shuang


___
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg
  


___
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg

Re: [RFC] glx: fix DRI2 memory leak

2009-03-29 Thread Shuang He

Jesse Barnes wrote:

On Fri, 27 Mar 2009 13:20:25 -0400
Kristian Høgsberg k...@bitplanet.net wrote:

  

On Thu, Mar 26, 2009 at 6:33 PM, Jesse Barnes
jbar...@virtuousgeek.org wrote:


Ok, I think this is where the leak was:
__glXUnrefDrawable-DrawableGone-__glXUnrefDrawable.  This sequence
meant the glxPriv would stay around (since it was used), but
DrawableGone had generally already disposed of the pDrawable before
the call to Unref, so we never got into DRI2DestroyBuffers, thus
the leak.

The loop seems broken to me.  It *looks* like DrawableGone should be
the real free routine, only called when a drawable really is free,
so I've fixed up the code to conform to that.  This means removing
the GLX priv frees from DRI and DRI2 routines and putting them here
and using the GLX unref routine everwhere (since it will only free
the resource when the refcount reaches 0).

Any thoughts?  I'd appreciate some more testers too...  I'm not
quite sure about the generic DoDestroyDrawable change, but if the
refcount is always 1 there anyway it shouldn't make a difference
and seems more correct.
  

The __GLXdrawable is a reference counted object, and the glx code
references it in a couple of places: when there's an X resource
pointing to it (a GLXWindow, GLXPixmap or GLXPbuffer) and when it's
the current drawable or readable for a context.  The __GLXdrawable is
allocated by the backend in use (dri, dri2 or swrast) and must be
freed by the same backend (don't mix alloc and free across abstraction
barriers).  We unref the __GLXdrawable when we either set a different
drawable/readable and when the X resource goes away.

The leak is (as you pointed out before) because we NULL the pDraw
pointer before calling the backend destructor, which then can't unref
the DRI2Drawable, which we then leak.  You had the right fix in the
originial post, we just need to not touch glxPriv after
__glXUnrefDrawable if it got destroyed.  I suggest this change to
DrawableGone in irc:

refcount = glxPriv-refcount;
__glXUnrefDrawable(glxPriv);
if (refcount  1) {
glxPriv-pDraw = NULL;
glxPriv-drawId = 0;
}



Yep, that seems to work too...  Magnus or Vasily can you guys confirm?

Thanks,
  

Memory leak problem seems resolved, but I still see X crash with:

(gdb) bt
#0  0xb7fd5424 in __kernel_vsyscall ()
#1  0x03155660 in raise () from /lib/libc.so.6
#2  0x03157028 in abort () from /lib/libc.so.6
#3  0x031925bd in __libc_message () from /lib/libc.so.6
#4  0x031987e4 in malloc_printerr () from /lib/libc.so.6
#5  0x0319c441 in _int_realloc () from /lib/libc.so.6
#6  0x0319d176 in realloc () from /lib/libc.so.6
#7  0x08131002 in Xrealloc (ptr=0x6, amount=0) at utils.c:1133
#8  0x0806d10b in dixAllocatePrivate (privates=0x91487c8, key=0xb7e90a3c)
   at privates.c:129
#9  0x0806d1cc in dixSetPrivate (privates=0x91487c8, key=0xb7e90a3c, val=0x0)
   at privates.c:193
#10 0xb7e8eca1 in DRI2DestroyDrawable (pDraw=0x91487b0) at dri2.c:218
#11 0xb7eee668 in __glXDRIdrawableDestroy (drawable=0x9205ff0) at glxdri2.c:108
#12 0xb7ee49bb in __glXUnrefDrawable (glxPriv=0x9205ff0) at glxutil.c:58
#13 0xb7ee3183 in DrawableGone (glxPriv=0x9205ff0, xid=12583326)
   at glxext.c:131
#14 0x0806efdc in FreeResource (id=12583326, skipDeleteFuncType=0)
   at resource.c:561
#15 0xb7edffa6 in DoDestroyDrawable (cl=value optimized out,
   glxdrawable=12583326, type=1) at glxcmds.c:1225
#16 0xb7ee340a in __glXDispatch (client=0x8d79db8) at glxext.c:523
#17 0x080874cf in Dispatch () at dispatch.c:437
---Type return to continue, or q return to quit---
#18 0x0806c69d in main (argc=2, argv=0xbf9d2754, envp=Cannot access memory at
address 0xbde

Thanks
--Shuang
) at main.c:397


___
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg

Re: [RFC] glx: fix DRI2 memory leak

2009-03-29 Thread Shuang He

Shuang He wrote:

Jesse Barnes wrote:

On Fri, 27 Mar 2009 13:20:25 -0400
Kristian Høgsberg k...@bitplanet.net wrote:

  

On Thu, Mar 26, 2009 at 6:33 PM, Jesse Barnes
jbar...@virtuousgeek.org wrote:


Ok, I think this is where the leak was:
__glXUnrefDrawable-DrawableGone-__glXUnrefDrawable.  This sequence
meant the glxPriv would stay around (since it was used), but
DrawableGone had generally already disposed of the pDrawable before
the call to Unref, so we never got into DRI2DestroyBuffers, thus
the leak.

The loop seems broken to me.  It *looks* like DrawableGone should be
the real free routine, only called when a drawable really is free,
so I've fixed up the code to conform to that.  This means removing
the GLX priv frees from DRI and DRI2 routines and putting them here
and using the GLX unref routine everwhere (since it will only free
the resource when the refcount reaches 0).

Any thoughts?  I'd appreciate some more testers too...  I'm not
quite sure about the generic DoDestroyDrawable change, but if the
refcount is always 1 there anyway it shouldn't make a difference
and seems more correct.
  

The __GLXdrawable is a reference counted object, and the glx code
references it in a couple of places: when there's an X resource
pointing to it (a GLXWindow, GLXPixmap or GLXPbuffer) and when it's
the current drawable or readable for a context.  The __GLXdrawable is
allocated by the backend in use (dri, dri2 or swrast) and must be
freed by the same backend (don't mix alloc and free across abstraction
barriers).  We unref the __GLXdrawable when we either set a different
drawable/readable and when the X resource goes away.

The leak is (as you pointed out before) because we NULL the pDraw
pointer before calling the backend destructor, which then can't unref
the DRI2Drawable, which we then leak.  You had the right fix in the
originial post, we just need to not touch glxPriv after
__glXUnrefDrawable if it got destroyed.  I suggest this change to
DrawableGone in irc:

refcount = glxPriv-refcount;
__glXUnrefDrawable(glxPriv);
if (refcount  1) {
glxPriv-pDraw = NULL;
glxPriv-drawId = 0;
}



Yep, that seems to work too...  Magnus or Vasily can you guys confirm?

Thanks,
  

Memory leak problem seems resolved, but I still see X crash with:
(gdb) bt
#0  0xb7fd5424 in __kernel_vsyscall ()
#1  0x03155660 in raise () from /lib/libc.so.6
#2  0x03157028 in abort () from /lib/libc.so.6
#3  0x031925bd in __libc_message () from /lib/libc.so.6
#4  0x031987e4 in malloc_printerr () from /lib/libc.so.6
#5  0x0319c441 in _int_realloc () from /lib/libc.so.6
#6  0x0319d176 in realloc () from /lib/libc.so.6
#7  0x08131002 in Xrealloc (ptr=0x6, amount=0) at utils.c:1133
#8  0x0806d10b in dixAllocatePrivate (privates=0x91487c8, key=0xb7e90a3c)
at privates.c:129
#9  0x0806d1cc in dixSetPrivate (privates=0x91487c8, key=0xb7e90a3c, val=0x0)
at privates.c:193
#10 0xb7e8eca1 in DRI2DestroyDrawable (pDraw=0x91487b0) at dri2.c:218
#11 0xb7eee668 in __glXDRIdrawableDestroy (drawable=0x9205ff0) at glxdri2.c:108
#12 0xb7ee49bb in __glXUnrefDrawable (glxPriv=0x9205ff0) at glxutil.c:58
#13 0xb7ee3183 in DrawableGone (glxPriv=0x9205ff0, xid=12583326)
at glxext.c:131
#14 0x0806efdc in FreeResource (id=12583326, skipDeleteFuncType=0)
at resource.c:561
#15 0xb7edffa6 in DoDestroyDrawable (cl=value optimized out,
glxdrawable=12583326, type=1) at glxcmds.c:1225
#16 0xb7ee340a in __glXDispatch (client=0x8d79db8) at glxext.c:523
#17 0x080874cf in Dispatch () at dispatch.c:437
---Type return to continue, or q return to quit---
#18 0x0806c69d in main (argc=2, argv=0xbf9d2754, envp=Cannot access memory at
address 0xbde

Thanks
--Shuang
) at main.c:397
  



Just debug a bit, check out this series of calls in DRI2DestroyDrawable when X
crashed:
in (*ds-DestroyBuffers)(pDraw, pPriv-buffers, pPriv-bufferCount);
 Xfree: free(0x9eef330)
 Xfree: free(0x9eeef20)
 Xfree: free(0x9efdde0)
 Xfree: free(0x9efce08)
 Xfree: free(0x9eee8b0)
 Xrealloc: ptr = 0x9efaf20
 Xrealloc: amount = 384
 Xfree: free(0x9efcd18)
 Xfree: free(0x9ef8468)
 Xrealloc: ptr = 0x9efa278
 Xrealloc: amount = 384
 Xfree: free(0x9efcd18)
 Xfree: free(0x9ef9808)
 Xfree: free(0x9eeef38)
 Xfree: free(0x9efa648)
 Xfree: free(0x9efd788)
in dixSetPrivate(pPixmap-devPrivates, dri2PixmapPrivateKey, NULL);
 Xrealloc: ptr = 0x9efce08
 Xrealloc: amount = 512

So dixSetPrivate is trying to realloc memory at 0x9efce08, which is alreay
freed  in DetroyBuffers. So maybe we should also do this:

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 0f2e24b..dddcfdc 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -204,9 +204,6 @@ DRI2DestroyDrawable(DrawablePtr pDraw)
if (pPriv-refCount  0)
   return;

-(*ds-DestroyBuffers)(pDraw, pPriv-buffers, pPriv-bufferCount);
-xfree(pPriv);
-
if (pDraw-type == DRAWABLE_WINDOW)
{
   pWin = (WindowPtr) pDraw;
@@ -217,6 +214,9 @@ 

Re: [RFC] glx: fix DRI2 memory leak

2009-03-28 Thread Adam Lantos
Jesse,

Thanks for the patch, I'm testing it now - it looks promising :)

X memory usage is more stable, but lsof | grep drm mm | wc -l still
increases - after 10 minutes it went up from 100 to 500... Is this
normal?


cheers,
 Adam


2009/3/28 Jesse Barnes jbar...@virtuousgeek.org:
 On Fri, 27 Mar 2009 13:20:25 -0400
 Kristian Høgsberg k...@bitplanet.net wrote:

 On Thu, Mar 26, 2009 at 6:33 PM, Jesse Barnes
 jbar...@virtuousgeek.org wrote:
  Ok, I think this is where the leak was:
  __glXUnrefDrawable-DrawableGone-__glXUnrefDrawable.  This sequence
  meant the glxPriv would stay around (since it was used), but
  DrawableGone had generally already disposed of the pDrawable before
  the call to Unref, so we never got into DRI2DestroyBuffers, thus
  the leak.
 
  The loop seems broken to me.  It *looks* like DrawableGone should be
  the real free routine, only called when a drawable really is free,
  so I've fixed up the code to conform to that.  This means removing
  the GLX priv frees from DRI and DRI2 routines and putting them here
  and using the GLX unref routine everwhere (since it will only free
  the resource when the refcount reaches 0).
 
  Any thoughts?  I'd appreciate some more testers too...  I'm not
  quite sure about the generic DoDestroyDrawable change, but if the
  refcount is always 1 there anyway it shouldn't make a difference
  and seems more correct.

 The __GLXdrawable is a reference counted object, and the glx code
 references it in a couple of places: when there's an X resource
 pointing to it (a GLXWindow, GLXPixmap or GLXPbuffer) and when it's
 the current drawable or readable for a context.  The __GLXdrawable is
 allocated by the backend in use (dri, dri2 or swrast) and must be
 freed by the same backend (don't mix alloc and free across abstraction
 barriers).  We unref the __GLXdrawable when we either set a different
 drawable/readable and when the X resource goes away.

 The leak is (as you pointed out before) because we NULL the pDraw
 pointer before calling the backend destructor, which then can't unref
 the DRI2Drawable, which we then leak.  You had the right fix in the
 originial post, we just need to not touch glxPriv after
 __glXUnrefDrawable if it got destroyed.  I suggest this change to
 DrawableGone in irc:

     refcount = glxPriv-refcount;
     __glXUnrefDrawable(glxPriv);
     if (refcount  1) {
         glxPriv-pDraw = NULL;
         glxPriv-drawId = 0;
     }

 Yep, that seems to work too...  Magnus or Vasily can you guys confirm?

 Thanks,
 --
 Jesse Barnes, Intel Open Source Technology Center

 diff --git a/glx/glxext.c b/glx/glxext.c
 index c882372..fec45b7 100644
 --- a/glx/glxext.c
 +++ b/glx/glxext.c
 @@ -119,6 +119,7 @@ static int ContextGone(__GLXcontext* cx, XID id)
  static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
  {
     ScreenPtr pScreen = glxPriv-pDraw-pScreen;
 +    int refcount;

     switch (glxPriv-type) {
        case GLX_DRAWABLE_PIXMAP:
 @@ -127,9 +128,12 @@ static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
            break;
     }

 -    glxPriv-pDraw = NULL;
 -    glxPriv-drawId = 0;
 +    refcount = glxPriv-refCount;
     __glXUnrefDrawable(glxPriv);
 +    if (refcount  1) {
 +       glxPriv-pDraw = NULL;
 +       glxPriv-drawId = 0;
 +    }

     return True;
  }

 ___
 xorg mailing list
 xorg@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/xorg
___
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg

Re: [RFC] glx: fix DRI2 memory leak

2009-03-28 Thread Vasily Khoruzhick
On Saturday 28 March 2009 02:42:53 Jesse Barnes wrote:
 Yep, that seems to work too...  Magnus or Vasily can you guys confirm?

I've just got xorg-server crash. Here's trace (not very usefull I think):

Backtrace:
0: /usr/bin/X(xorg_backtrace+0x3c) [0x813344c]
1: /usr/bin/X(xf86SigHandler+0x52) [0x80d47b2]
2: [0xb80c6400]
3: /usr/lib/xorg/modules/extensions//libdri2.so [0xb7b5f89f]
4: /usr/bin/X(Dispatch+0x33f) [0x808b48f]
5: /usr/bin/X(main+0x3bd) [0x80700fd]
6: /lib/libc.so.6(__libc_start_main+0xe5) [0xb7bd4725]
7: /usr/bin/X [0x806f581]

Fatal server error:
Caught signal 11.  Server aborting



signature.asc
Description: This is a digitally signed message part.
___
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg

Re: [RFC] glx: fix DRI2 memory leak

2009-03-28 Thread Magnus Kessler
On Saturday 28 Mar 2009 00:42:53 Jesse Barnes wrote:
 Yep, that seems to work too...  Magnus or Vasily can you guys confirm?

Seems to work fine for me, although I'm going to have an eye open for bugs that 
might have previously been hidden in the now exposed code paths.

Is there any good documentation about resource handling in the server 
available? I must admit that I get slightly nervous about the loops of 
function calls that occur when resources are freed.

Magnus

___
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg


Re: [RFC] glx: fix DRI2 memory leak

2009-03-28 Thread Jesse Barnes
On Sat, 28 Mar 2009 11:35:20 +0100
Adam Lantos h...@playma.org wrote:

 Jesse,
 
 Thanks for the patch, I'm testing it now - it looks promising :)
 
 X memory usage is more stable, but lsof | grep drm mm | wc -l still
 increases - after 10 minutes it went up from 100 to 500... Is this
 normal?

Yeah that's probably due to our bo cache.  We could probably make it
smarter, but right now it'll continue to grow (theoretically more and
more slowly over time).

-- 
Jesse Barnes, Intel Open Source Technology Center
___
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg


Re: [RFC] glx: fix DRI2 memory leak

2009-03-27 Thread Jesse Barnes
On Fri, 27 Mar 2009 13:20:25 -0400
Kristian Høgsberg k...@bitplanet.net wrote:

 On Thu, Mar 26, 2009 at 6:33 PM, Jesse Barnes
 jbar...@virtuousgeek.org wrote:
  Ok, I think this is where the leak was:
  __glXUnrefDrawable-DrawableGone-__glXUnrefDrawable.  This sequence
  meant the glxPriv would stay around (since it was used), but
  DrawableGone had generally already disposed of the pDrawable before
  the call to Unref, so we never got into DRI2DestroyBuffers, thus
  the leak.
 
  The loop seems broken to me.  It *looks* like DrawableGone should be
  the real free routine, only called when a drawable really is free,
  so I've fixed up the code to conform to that.  This means removing
  the GLX priv frees from DRI and DRI2 routines and putting them here
  and using the GLX unref routine everwhere (since it will only free
  the resource when the refcount reaches 0).
 
  Any thoughts?  I'd appreciate some more testers too...  I'm not
  quite sure about the generic DoDestroyDrawable change, but if the
  refcount is always 1 there anyway it shouldn't make a difference
  and seems more correct.
 
 The __GLXdrawable is a reference counted object, and the glx code
 references it in a couple of places: when there's an X resource
 pointing to it (a GLXWindow, GLXPixmap or GLXPbuffer) and when it's
 the current drawable or readable for a context.  The __GLXdrawable is
 allocated by the backend in use (dri, dri2 or swrast) and must be
 freed by the same backend (don't mix alloc and free across abstraction
 barriers).  We unref the __GLXdrawable when we either set a different
 drawable/readable and when the X resource goes away.

Yeah it does violate the layering...  but the uref-drawablegone-unref
is a bit convoluted too.

 The leak is (as you pointed out before) because we NULL the pDraw
 pointer before calling the backend destructor, which then can't unref
 the DRI2Drawable, which we then leak.  You had the right fix in the
 originial post, we just need to not touch glxPriv after
 __glXUnrefDrawable if it got destroyed.  I suggest this change to
 DrawableGone in irc:
 
 refcount = glxPriv-refcount;
 __glXUnrefDrawable(glxPriv);
 if (refcount  1) {
 glxPriv-pDraw = NULL;
 glxPriv-drawId = 0;
 }
 
 Did you try that?

Ah no I think I had either = 1 or == 1 which clearly wouldn't work
since the glxPriv would be gone in the == 1 case.  I'll try the 1 test.

Thanks,
-- 
Jesse Barnes, Intel Open Source Technology Center
___
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg

Re: [RFC] glx: fix DRI2 memory leak

2009-03-27 Thread Jesse Barnes
On Fri, 27 Mar 2009 13:20:25 -0400
Kristian Høgsberg k...@bitplanet.net wrote:

 On Thu, Mar 26, 2009 at 6:33 PM, Jesse Barnes
 jbar...@virtuousgeek.org wrote:
  Ok, I think this is where the leak was:
  __glXUnrefDrawable-DrawableGone-__glXUnrefDrawable.  This sequence
  meant the glxPriv would stay around (since it was used), but
  DrawableGone had generally already disposed of the pDrawable before
  the call to Unref, so we never got into DRI2DestroyBuffers, thus
  the leak.
 
  The loop seems broken to me.  It *looks* like DrawableGone should be
  the real free routine, only called when a drawable really is free,
  so I've fixed up the code to conform to that.  This means removing
  the GLX priv frees from DRI and DRI2 routines and putting them here
  and using the GLX unref routine everwhere (since it will only free
  the resource when the refcount reaches 0).
 
  Any thoughts?  I'd appreciate some more testers too...  I'm not
  quite sure about the generic DoDestroyDrawable change, but if the
  refcount is always 1 there anyway it shouldn't make a difference
  and seems more correct.
 
 The __GLXdrawable is a reference counted object, and the glx code
 references it in a couple of places: when there's an X resource
 pointing to it (a GLXWindow, GLXPixmap or GLXPbuffer) and when it's
 the current drawable or readable for a context.  The __GLXdrawable is
 allocated by the backend in use (dri, dri2 or swrast) and must be
 freed by the same backend (don't mix alloc and free across abstraction
 barriers).  We unref the __GLXdrawable when we either set a different
 drawable/readable and when the X resource goes away.
 
 The leak is (as you pointed out before) because we NULL the pDraw
 pointer before calling the backend destructor, which then can't unref
 the DRI2Drawable, which we then leak.  You had the right fix in the
 originial post, we just need to not touch glxPriv after
 __glXUnrefDrawable if it got destroyed.  I suggest this change to
 DrawableGone in irc:
 
 refcount = glxPriv-refcount;
 __glXUnrefDrawable(glxPriv);
 if (refcount  1) {
 glxPriv-pDraw = NULL;
 glxPriv-drawId = 0;
 }

Yep, that seems to work too...  Magnus or Vasily can you guys confirm?

Thanks,
-- 
Jesse Barnes, Intel Open Source Technology Center

diff --git a/glx/glxext.c b/glx/glxext.c
index c882372..fec45b7 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -119,6 +119,7 @@ static int ContextGone(__GLXcontext* cx, XID id)
 static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
 {
 ScreenPtr pScreen = glxPriv-pDraw-pScreen;
+int refcount;
 
 switch (glxPriv-type) {
case GLX_DRAWABLE_PIXMAP:
@@ -127,9 +128,12 @@ static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
break;
 }
 
-glxPriv-pDraw = NULL;
-glxPriv-drawId = 0;
+refcount = glxPriv-refCount;
 __glXUnrefDrawable(glxPriv);
+if (refcount  1) {
+   glxPriv-pDraw = NULL;
+   glxPriv-drawId = 0;
+}
 
 return True;
 }

___
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg

Re: [RFC] glx: fix DRI2 memory leak

2009-03-26 Thread Magnus Kessler
On Wednesday 25 March 2009, Jesse Barnes wrote:
 In trying to track down the memory leak in 20704, I found that the DRI2
 drawable destroy routine doesn't seem to get called when new drawables
 are created and old ones destroyed (as in the glViewport case in the
 bug).

 The GLX core code takes care of destroying drawables correctly though,
 and even calls DestroyPixmap at the right time.  However, DRI2
 drawables have more state associated with them than just a single
 pixmap, so we have a __glXDRIdrawableDestroy function that takes care
 of that.  However, by the time we get there, the GLX drawable is gone,
 so I never saw the
 if (drawable-pDraw != NULL)
   DRI2DestroyDrawable(drawable-pDraw);
 case get triggered...

 The simple patch below fixed that, but apparently isn't correct (see
 the bug report) since it causes crashes after a time.  My patch was
 missing another change to set the private-count correctly in
 dri2GetBuffers though, which may be part of the fix as well.

 Has anyone else seen this leak?  Anyone care to educate me a bit more
 about GLX drawable lifetime rules?

 Thanks,
 Jesse

Hi Jesse,

This memory leak has troubled me for some time, as it forces me to log out 
of my X sessions on a regular basis. I have tested your patch and it seems 
to help tremendously. However, digging through the git commits for glxext.c 
it appears that the line setting glxPriv-pDraw to NULL was added as part of 
commit 
http://cgit.freedesktop.org/xorg/xserver/commit/?id=30bcaa966d6b00f1630609a78db18dee683cc43d
 
which aims to Make glx destroy path handle cases where the X window goes 
away first. So it might be that the commenter on bug 20704 who observes a 
crash hits this condition. Maybe Kristian Høgsberg can comment some more.

Thanks,

Magnus



 diff --git a/glx/glxext.c b/glx/glxext.c
 index c882372..73e5a9b 100644
 --- a/glx/glxext.c
 +++ b/glx/glxext.c
 @@ -127,9 +127,9 @@ static Bool DrawableGone(__GLXdrawable *glxPriv, XID
 xid) break;
  }

 -glxPriv-pDraw = NULL;
  glxPriv-drawId = 0;
  __glXUnrefDrawable(glxPriv);
 +glxPriv-pDraw = NULL;

  return True;
  }
 ___
 xorg mailing list
 xorg@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/xorg




signature.asc
Description: This is a digitally signed message part.
___
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg

Re: [RFC] glx: fix DRI2 memory leak

2009-03-26 Thread Vasily Khoruzhick
On Wednesday 25 March 2009 19:21:51 Jesse Barnes wrote:

 Has anyone else seen this leak?  Anyone care to educate me a bit more
 about GLX drawable lifetime rules?

Yep, my system suffer from this leak too.


 Thanks,
 Jesse

 diff --git a/glx/glxext.c b/glx/glxext.c
 index c882372..73e5a9b 100644
 --- a/glx/glxext.c
 +++ b/glx/glxext.c
 @@ -127,9 +127,9 @@ static Bool DrawableGone(__GLXdrawable *glxPriv, XID
 xid) break;
  }

 -glxPriv-pDraw = NULL;
  glxPriv-drawId = 0;
  __glXUnrefDrawable(glxPriv);

Maybe, we should somehow check if glxPriv is still valid after Unref before 
assigning something to the pDraw? (I'm not sure, I'm not familiar with X 
internals)

 +glxPriv-pDraw = NULL;

  return True;
  }
 ___
 xorg mailing list
 xorg@lists.freedesktop.org
 http://lists.freedesktop.org/mailman/listinfo/xorg



signature.asc
Description: This is a digitally signed message part.
___
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg

Re: [RFC] glx: fix DRI2 memory leak

2009-03-26 Thread Jesse Barnes
On Thu, 26 Mar 2009 22:02:52 +0200
Vasily Khoruzhick anars...@gmail.com wrote:

 On Wednesday 25 March 2009 19:21:51 Jesse Barnes wrote:
 
  Has anyone else seen this leak?  Anyone care to educate me a bit
  more about GLX drawable lifetime rules?
 
 Yep, my system suffer from this leak too.

Yeah sounds pretty widespread; it'll only get worse as the radeon DRI2
bits become more common.

  diff --git a/glx/glxext.c b/glx/glxext.c
  index c882372..73e5a9b 100644
  --- a/glx/glxext.c
  +++ b/glx/glxext.c
  @@ -127,9 +127,9 @@ static Bool DrawableGone(__GLXdrawable
  *glxPriv, XID xid) break;
   }
 
  -glxPriv-pDraw = NULL;
   glxPriv-drawId = 0;
   __glXUnrefDrawable(glxPriv);
 
 Maybe, we should somehow check if glxPriv is still valid after Unref
 before assigning something to the pDraw? (I'm not sure, I'm not
 familiar with X internals)

Yeah, I'm just learning this stuff too...  Now that I've walked through
the life of a GLX pixmap a bit things look even more convoluted.  GLX
pixmaps are created by __glXDRIscreenCreateDrawable at various times,
either explicitly by something like __glXGetDrawable or implicitly by a
glXCreateWindow call.  All of these end up in DRI2CreateDrawable which
either bumps the refcount of an existing pixmap or creates a new one
(though with no buffers attached).

The drawables get destroyed by their own destroy hook, which points at
__glXDRIdrawableDestroy (yes this and the one above should probably
have been called glXDRI2...), which is either explicitly called by a
cleanup routine (error handling in drawable creation for example), free
context time, free screen time, or when a drawable is deref'd and the
count drops to 0.

What's weird is that __glXUnrefDrawable might be called by DrawableGone
(the top level X managed resource for glx drawables) due to
__glXUnrefDrawable calling FreeResourceByType, but then DrawableGone
will again call __glXUnrefDrawable... I think krh noticed this today
and suggested we check the refcount in DrawableGone... But it seems
like since __glXUnrefDrawable only frees the resource if the refcount
reaches 0, we shouldn't need another unref in DrawableGone...  So maybe
that's what my fix was running into.

Anyway back to more testing  reading.

-- 
Jesse Barnes, Intel Open Source Technology Center
___
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg


Re: [RFC] glx: fix DRI2 memory leak

2009-03-26 Thread Jesse Barnes
On Thu, 26 Mar 2009 14:20:07 -0700
Jesse Barnes jbar...@virtuousgeek.org wrote:
 What's weird is that __glXUnrefDrawable might be called by
 DrawableGone (the top level X managed resource for glx drawables) due
 to __glXUnrefDrawable calling FreeResourceByType, but then
 DrawableGone will again call __glXUnrefDrawable... I think krh
 noticed this today and suggested we check the refcount in
 DrawableGone... But it seems like since __glXUnrefDrawable only frees
 the resource if the refcount reaches 0, we shouldn't need another
 unref in DrawableGone...  So maybe that's what my fix was running
 into.

Ok, I think this is where the leak was:
__glXUnrefDrawable-DrawableGone-__glXUnrefDrawable.  This sequence
meant the glxPriv would stay around (since it was used), but
DrawableGone had generally already disposed of the pDrawable before the
call to Unref, so we never got into DRI2DestroyBuffers, thus the leak.

The loop seems broken to me.  It *looks* like DrawableGone should be
the real free routine, only called when a drawable really is free, so
I've fixed up the code to conform to that.  This means removing the GLX
priv frees from DRI and DRI2 routines and putting them here and using
the GLX unref routine everwhere (since it will only free the resource
when the refcount reaches 0).

Any thoughts?  I'd appreciate some more testers too...  I'm not quite
sure about the generic DoDestroyDrawable change, but if the refcount is
always 1 there anyway it shouldn't make a difference and seems more
correct.

Thanks,
-- 
Jesse Barnes, Intel Open Source Technology Center


diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index ab2d91b..08b866d 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -1222,7 +1222,7 @@ static int DoDestroyDrawable(__GLXclientState *cl, XID 
glxdrawable, int type)
}
 }
 
-FreeResource(glxdrawable, FALSE);
+__glXUnrefDrawable(pGlxDraw);
 
 return Success;
 }
diff --git a/glx/glxdri.c b/glx/glxdri.c
index 223b06e..253d868 100644
--- a/glx/glxdri.c
+++ b/glx/glxdri.c
@@ -237,8 +237,6 @@ __glXDRIdrawableDestroy(__GLXdrawable *drawable)
   serverClient, drawable-pDraw);
__glXleaveServer(GL_FALSE);
 }
-
-xfree(private);
 }
 
 static GLboolean
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 4e76c71..4fdc7df 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -106,8 +106,6 @@ __glXDRIdrawableDestroy(__GLXdrawable *drawable)
  * aready have taken care of this, so only call if pDraw isn't NULL. */
 if (drawable-pDraw != NULL)
DRI2DestroyDrawable(drawable-pDraw);
-
-xfree(private);
 }
 
 static void
diff --git a/glx/glxext.c b/glx/glxext.c
index c882372..0b6c752 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -120,6 +120,8 @@ static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
 {
 ScreenPtr pScreen = glxPriv-pDraw-pScreen;
 
+glxPriv-destroy(glxPriv);
+
 switch (glxPriv-type) {
case GLX_DRAWABLE_PIXMAP:
case GLX_DRAWABLE_PBUFFER:
@@ -129,7 +131,7 @@ static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
 
 glxPriv-pDraw = NULL;
 glxPriv-drawId = 0;
-__glXUnrefDrawable(glxPriv);
+xfree(glxPriv);
 
 return True;
 }
diff --git a/glx/glxutil.c b/glx/glxutil.c
index bc71087..61323f5 100644
--- a/glx/glxutil.c
+++ b/glx/glxutil.c
@@ -52,11 +52,9 @@ void
 __glXUnrefDrawable(__GLXdrawable *glxPriv)
 {
 glxPriv-refCount--;
-if (glxPriv-refCount == 0) {
+if (glxPriv-refCount == 0)
/* remove the drawable from the drawable list */
FreeResourceByType(glxPriv-drawId, __glXDrawableRes, FALSE);
-   glxPriv-destroy(glxPriv);
-}
 }
 
 GLboolean
___
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg


[RFC] glx: fix DRI2 memory leak

2009-03-25 Thread Jesse Barnes
In trying to track down the memory leak in 20704, I found that the DRI2
drawable destroy routine doesn't seem to get called when new drawables
are created and old ones destroyed (as in the glViewport case in the
bug).

The GLX core code takes care of destroying drawables correctly though,
and even calls DestroyPixmap at the right time.  However, DRI2
drawables have more state associated with them than just a single
pixmap, so we have a __glXDRIdrawableDestroy function that takes care
of that.  However, by the time we get there, the GLX drawable is gone,
so I never saw the
if (drawable-pDraw != NULL)
DRI2DestroyDrawable(drawable-pDraw);
case get triggered...

The simple patch below fixed that, but apparently isn't correct (see
the bug report) since it causes crashes after a time.  My patch was
missing another change to set the private-count correctly in
dri2GetBuffers though, which may be part of the fix as well.

Has anyone else seen this leak?  Anyone care to educate me a bit more
about GLX drawable lifetime rules?

Thanks,
Jesse

diff --git a/glx/glxext.c b/glx/glxext.c
index c882372..73e5a9b 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -127,9 +127,9 @@ static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid)
break;
 }
 
-glxPriv-pDraw = NULL;
 glxPriv-drawId = 0;
 __glXUnrefDrawable(glxPriv);
+glxPriv-pDraw = NULL;
 
 return True;
 }
___
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg