Re: [PATCH glx] glx: avoid memory leak when using indirect rendering

2016-05-09 Thread Guilherme Melo
On Mon, May 9, 2016 at 4:41 PM Adam Jackson  wrote:

> On Mon, 2016-04-04 at 19:57 +, Guilherme Melo wrote:
> > Updated patch with some other places with a potential leak.
>
> Apologies for being so slow to look at this.
>
> Unfortunately I think it's incorrect.  lastGLContext is not necessarily
> of __GLXcontext type - glamor sets it a glamor_ctx *, for example - so
> passing it to ->loseCurrent isn't always going to work.
>
>
I think your first patch that only did the loseCurrent from
> __glXForceCurrent was closer to correct.
>


 Thanks for the feedback.

I did not know that lastGLContext was shared with glamor.
So it really seems the first patch is more appropriate. I just thought it
was confusing because it actually needs to lose the same context that it is
currently making current.

I'll resend the patch soon.


Guilherme
___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

Re: [PATCH glx] glx: avoid memory leak when using indirect rendering

2016-05-09 Thread Adam Jackson
On Mon, 2016-04-04 at 19:57 +, Guilherme Melo wrote:
> Updated patch with some other places with a potential leak.

Apologies for being so slow to look at this.

Unfortunately I think it's incorrect.  lastGLContext is not necessarily
of __GLXcontext type - glamor sets it a glamor_ctx *, for example - so
passing it to ->loseCurrent isn't always going to work.

I think your first patch that only did the loseCurrent from
__glXForceCurrent was closer to correct.

- ajax
___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: https://lists.x.org/mailman/listinfo/xorg-devel

Re: [PATCH glx] glx: avoid memory leak when using indirect rendering

2016-04-04 Thread Guilherme Melo
Updated patch with some other places with a potential leak.


On Thu, Mar 24, 2016 at 3:52 AM Guilherme Melo  wrote:

> I've finally got some time to rewrite this patch and now the solution
> makes more sense.
> I'm sending as an attachment.
> I also have some tests on a github repository to check this bug. I don't
> know if it is ok to post the link here though.
>
>
> Guilherme
>
> On Tue, Dec 8, 2015 at 4:48 PM Guilherme Melo  wrote:
>
>>
>> This should be lastGLContext->loseCurrent(lastGLContext) I think. cx
>>
>>
>> Yes, you are right. It seems the right thing to do, but actually this
>> should be done every place where lastGLContext is set, right?
>> It seems to me that every place where lastGLContext is set is a potential
>> leak.
>>
>> While you're at it, it'd be nice to move that big block comment into the
>>> commit message
>>
>>
>> I'll do that, thanks.
>>
>>
>> Guilherme
>>
>>
>>
>> 2015-12-08 14:44 GMT-02:00 Adam Jackson :
>>
>>> On Fri, 2015-12-04 at 14:16 -0200, Guilherme Quentel Melo wrote:
>>>
>>> > diff --git a/glx/glxext.c b/glx/glxext.c
>>> > index e41b881..16b8039 100644
>>> > --- a/glx/glxext.c
>>> > +++ b/glx/glxext.c
>>> > @@ -469,6 +469,24 @@ __glXForceCurrent(__GLXclientState * cl,
>>> GLXContextTag tag, int *error)
>>> >
>>> >  /* Make this context the current one for the GL. */
>>> >  if (!cx->isDirect) {
>>> > +/*
>>> > + ** If we are forcing the context it means someone already
>>> called makeCurrent before. If
>>> > + ** we just call makeCurrent again, the drawable of this
>>> context will be left with one
>>> > + ** refcount more forever and will never be freed.
>>> > + **
>>> > + ** This situation happens when there are many X clients
>>> using GL:
>>> > + **
>>> > + ** 1 - client1: calls glXMakeCurrent
>>> > + **
>>> > + ** 2 - client2: calls glXMakeCurrent
>>> > + ** This is the first context switch for this client. So
>>> old_context_tag=0
>>> > + **
>>> > + ** 3 - client1: calls glXRender
>>> > + ** For the client, its context is already current.
>>> > + ** For the server side lastGLContext points to client2's
>>> context. So the execution path
>>> > + ** will get here.
>>> > + */
>>> > +(*cx->loseCurrent) (cx);
>>>
>>> This should be lastGLContext->loseCurrent(lastGLContext) I think. cx
>>> here is the current context from client2's perspective, you want to
>>> release client1's context.
>>>
>>> While you're at it, it'd be nice to move that big block comment into
>>> the commit message and just note /* drop previous client's context */
>>> or similar in the code.
>>>
>>> - ajax
>>
>>
>>
From 3dc360e2998392d62af7c8272819e2c91350d183 Mon Sep 17 00:00:00 2001
From: Guilherme Quentel Melo 
Date: Thu, 24 Mar 2016 03:13:30 -0300
Subject: [PATCH] glx: avoid memory leak when using indirect rendering

When multiple processes are using GL with indirect rendering a race
condition can make drawables refcount never drop to zero.

This situation could happen when there are many X clients using indirect
GLX:

1 - client1: calls glXMakeCurrent

2 - client2: calls glXMakeCurrent
This is the first context switch for this client. So old_context_tag=0

3 - client1: calls glXRender
For the client, its context is already current.
For the server side lastGLContext points to client2's context.

Signed-off-by: Guilherme Quentel Melo 
---
 glx/glxcmds.c | 20 ++--
 glx/glxext.c  | 18 +++---
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 561faeb..ffc6e9b 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -188,6 +188,11 @@ validGlxDrawable(ClientPtr client, XID id, int type, int access_mode,
 void
 __glXContextDestroy(__GLXcontext * context)
 {
+__GLXcontext *lastglxc;
+if (lastGLContext != NULL && lastGLContext != context) {
+lastglxc = (__GLXcontext*)lastGLContext;
+(*lastglxc->loseCurrent) (lastglxc);
+}
 lastGLContext = NULL;
 }
 
@@ -563,7 +568,7 @@ DoMakeCurrent(__GLXclientState * cl,
 {
 ClientPtr client = cl->client;
 xGLXMakeCurrentReply reply;
-__GLXcontext *glxc, *prevglxc;
+__GLXcontext *glxc, *prevglxc, *lastglxc = NULL;
 __GLXdrawable *drawPriv = NULL;
 __GLXdrawable *readPriv = NULL;
 int error;
@@ -659,13 +664,24 @@ DoMakeCurrent(__GLXclientState * cl,
 if (!(*prevglxc->loseCurrent) (prevglxc)) {
 return __glXError(GLXBadContext);
 }
-lastGLContext = NULL;
 if (!prevglxc->isDirect) {
 prevglxc->drawPriv = NULL;
 prevglxc->readPriv = NULL;
 }
 }
 
+/*
+ ** lastGLContext may be different than prevglxc, so we need lose it to
+ ** avoid a memory leak
+ */
+if (lastGLContext != NULL) {
+lastglxc = (__GLXcontext*)lastGLContext;
+if (!lastglxc->isDirect && lastglxc != prev

Re: [PATCH glx] glx: avoid memory leak when using indirect rendering

2016-03-24 Thread Guilherme Melo
I've finally got some time to rewrite this patch and now the solution makes
more sense.
I'm sending as an attachment.
I also have some tests on a github repository to check this bug. I don't
know if it is ok to post the link here though.


Guilherme

On Tue, Dec 8, 2015 at 4:48 PM Guilherme Melo  wrote:

>
> This should be lastGLContext->loseCurrent(lastGLContext) I think. cx
>
>
> Yes, you are right. It seems the right thing to do, but actually this
> should be done every place where lastGLContext is set, right?
> It seems to me that every place where lastGLContext is set is a potential
> leak.
>
> While you're at it, it'd be nice to move that big block comment into the
>> commit message
>
>
> I'll do that, thanks.
>
>
> Guilherme
>
>
>
> 2015-12-08 14:44 GMT-02:00 Adam Jackson :
>
>> On Fri, 2015-12-04 at 14:16 -0200, Guilherme Quentel Melo wrote:
>>
>> > diff --git a/glx/glxext.c b/glx/glxext.c
>> > index e41b881..16b8039 100644
>> > --- a/glx/glxext.c
>> > +++ b/glx/glxext.c
>> > @@ -469,6 +469,24 @@ __glXForceCurrent(__GLXclientState * cl,
>> GLXContextTag tag, int *error)
>> >
>> >  /* Make this context the current one for the GL. */
>> >  if (!cx->isDirect) {
>> > +/*
>> > + ** If we are forcing the context it means someone already
>> called makeCurrent before. If
>> > + ** we just call makeCurrent again, the drawable of this
>> context will be left with one
>> > + ** refcount more forever and will never be freed.
>> > + **
>> > + ** This situation happens when there are many X clients using
>> GL:
>> > + **
>> > + ** 1 - client1: calls glXMakeCurrent
>> > + **
>> > + ** 2 - client2: calls glXMakeCurrent
>> > + ** This is the first context switch for this client. So
>> old_context_tag=0
>> > + **
>> > + ** 3 - client1: calls glXRender
>> > + ** For the client, its context is already current.
>> > + ** For the server side lastGLContext points to client2's
>> context. So the execution path
>> > + ** will get here.
>> > + */
>> > +(*cx->loseCurrent) (cx);
>>
>> This should be lastGLContext->loseCurrent(lastGLContext) I think. cx
>> here is the current context from client2's perspective, you want to
>> release client1's context.
>>
>> While you're at it, it'd be nice to move that big block comment into
>> the commit message and just note /* drop previous client's context */
>> or similar in the code.
>>
>> - ajax
>
>
>
From b921bbbdb9d3d79d1ff487b4f3270fb675ba69d2 Mon Sep 17 00:00:00 2001
From: Guilherme Quentel Melo 
Date: Thu, 24 Mar 2016 03:13:30 -0300
Subject: [PATCH glx] glx: avoid memory leak when using indirect rendering

When multiple processes are using GL with indirect rendering a race
condition can make drawables refcount never drop to zero.

This situation could happen when there are many X clients using indirect GLX:

1 - client1: calls glXMakeCurrent

2 - client2: calls glXMakeCurrent
This is the first context switch for this client. So old_context_tag=0

3 - client1: calls glXRender
For the client, its context is already current.
For the server side lastGLContext points to client2's context.

Signed-off-by: Guilherme Quentel Melo 
---
 glx/glxcmds.c | 15 +--
 glx/glxext.c  |  6 +-
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index f5f2bab..94b31b8 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -551,7 +551,7 @@ DoMakeCurrent(__GLXclientState * cl,
 {
 ClientPtr client = cl->client;
 xGLXMakeCurrentReply reply;
-__GLXcontext *glxc, *prevglxc;
+__GLXcontext *glxc, *prevglxc, *lastglxc = NULL;
 __GLXdrawable *drawPriv = NULL;
 __GLXdrawable *readPriv = NULL;
 int error;
@@ -642,13 +642,24 @@ DoMakeCurrent(__GLXclientState * cl,
 if (!(*prevglxc->loseCurrent) (prevglxc)) {
 return __glXError(GLXBadContext);
 }
-lastGLContext = NULL;
 if (!prevglxc->isDirect) {
 prevglxc->drawPriv = NULL;
 prevglxc->readPriv = NULL;
 }
 }
 
+/*
+ ** lastGLContext may be different than prevglxc, so we need lose it to
+ ** avoid a memory leak
+ */
+if (lastGLContext != NULL) {
+lastglxc = (__GLXcontext*)lastGLContext;
+if (!lastglxc->isDirect && lastglxc != prevglxc) {
+(*lastglxc->loseCurrent) (lastglxc);
+}
+lastGLContext = NULL;
+}
+
 if ((glxc != 0) && !glxc->isDirect) {
 
 glxc->drawPriv = drawPriv;
diff --git a/glx/glxext.c b/glx/glxext.c
index e41b881..c556489 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -434,7 +434,7 @@ GlxExtensionInit(void)
 __GLXcontext *
 __glXForceCurrent(__GLXclientState * cl, GLXContextTag tag, int *error)
 {
-__GLXcontext *cx;
+__GLXcontext *cx, *lastglxc = NULL;
 
 /*
  ** See if the context tag is legal; it is managed by the extension,
@@ -469

Re: [PATCH glx] glx: avoid memory leak when using indirect rendering

2015-12-08 Thread Guilherme Melo
> This should be lastGLContext->loseCurrent(lastGLContext) I think. cx


Yes, you are right. It seems the right thing to do, but actually this
should be done every place where lastGLContext is set, right?
It seems to me that every place where lastGLContext is set is a potential
leak.

While you're at it, it'd be nice to move that big block comment into the
> commit message


I'll do that, thanks.


Guilherme


2015-12-08 14:44 GMT-02:00 Adam Jackson :

> On Fri, 2015-12-04 at 14:16 -0200, Guilherme Quentel Melo wrote:
>
> > diff --git a/glx/glxext.c b/glx/glxext.c
> > index e41b881..16b8039 100644
> > --- a/glx/glxext.c
> > +++ b/glx/glxext.c
> > @@ -469,6 +469,24 @@ __glXForceCurrent(__GLXclientState * cl,
> GLXContextTag tag, int *error)
> >
> >  /* Make this context the current one for the GL. */
> >  if (!cx->isDirect) {
> > +/*
> > + ** If we are forcing the context it means someone already
> called makeCurrent before. If
> > + ** we just call makeCurrent again, the drawable of this
> context will be left with one
> > + ** refcount more forever and will never be freed.
> > + **
> > + ** This situation happens when there are many X clients using
> GL:
> > + **
> > + ** 1 - client1: calls glXMakeCurrent
> > + **
> > + ** 2 - client2: calls glXMakeCurrent
> > + ** This is the first context switch for this client. So
> old_context_tag=0
> > + **
> > + ** 3 - client1: calls glXRender
> > + ** For the client, its context is already current.
> > + ** For the server side lastGLContext points to client2's
> context. So the execution path
> > + ** will get here.
> > + */
> > +(*cx->loseCurrent) (cx);
>
> This should be lastGLContext->loseCurrent(lastGLContext) I think. cx
> here is the current context from client2's perspective, you want to
> release client1's context.
>
> While you're at it, it'd be nice to move that big block comment into
> the commit message and just note /* drop previous client's context */
> or similar in the code.
>
> - ajax
___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Re: [PATCH glx] glx: avoid memory leak when using indirect rendering

2015-12-08 Thread Adam Jackson
On Fri, 2015-12-04 at 14:16 -0200, Guilherme Quentel Melo wrote:

> diff --git a/glx/glxext.c b/glx/glxext.c
> index e41b881..16b8039 100644
> --- a/glx/glxext.c
> +++ b/glx/glxext.c
> @@ -469,6 +469,24 @@ __glXForceCurrent(__GLXclientState * cl, GLXContextTag 
> tag, int *error)
>  
>  /* Make this context the current one for the GL. */
>  if (!cx->isDirect) {
> +/*
> + ** If we are forcing the context it means someone already called 
> makeCurrent before. If
> + ** we just call makeCurrent again, the drawable of this context 
> will be left with one
> + ** refcount more forever and will never be freed.
> + **
> + ** This situation happens when there are many X clients using GL:
> + **
> + ** 1 - client1: calls glXMakeCurrent
> + **
> + ** 2 - client2: calls glXMakeCurrent
> + ** This is the first context switch for this client. So 
> old_context_tag=0
> + **
> + ** 3 - client1: calls glXRender
> + ** For the client, its context is already current.
> + ** For the server side lastGLContext points to client2's 
> context. So the execution path
> + ** will get here.
> + */
> +(*cx->loseCurrent) (cx);

This should be lastGLContext->loseCurrent(lastGLContext) I think. cx
here is the current context from client2's perspective, you want to
release client1's context.

While you're at it, it'd be nice to move that big block comment into
the commit message and just note /* drop previous client's context */
or similar in the code.

- ajax
___
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel