Re: [Mesa-dev] [PATCH] glx: block attempt to swapbuffer on pixmap. (v2)

2011-12-19 Thread Dave Airlie
On Wed, Dec 7, 2011 at 6:32 PM, Eric Anholt e...@anholt.net wrote:
 On Wed,  7 Dec 2011 10:24:09 +, Dave Airlie airl...@gmail.com wrote:
 From: Dave Airlie airl...@redhat.com

 This keeps track of the creation process and stores a drawable type,
 it then blocks DRI2 from getting called if the drawable is a pixmap.

 v2: check if we have a GLX drawable, which means we aren't a pbuffer,
 avoid doing flush at all since its meant to be a no-op.

 I still think this is the wrong way to go.  As ajax pointed out, there's
 all sorts of races available from trying to guess client-side, and
 there's no way anybody's relying on the current (print an error message
 in the xorg log) behavior of the DRI2 protocol for single-buffered, so
 we might as well resolve that DRI2 protocol should do what we want for
 GLX.

I've been thinking about the races, and I'm not sure they really
apply, like we would have all those races now with the current code,

Look at the patch, when the glx_drawable struct is created we record
the type of the pixmap, we then call GetGLXDrawable, which looks the
XID up in the hash,
so if the XID has been reused or raced, then we would have to expect
the hash to be incorrect, or else avoid using it in a lot of other
places.

Dave.
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] glx: block attempt to swapbuffer on pixmap. (v2)

2011-12-19 Thread Adam Jackson
On Mon, 2011-12-19 at 09:40 +, Dave Airlie wrote:
 On Wed, Dec 7, 2011 at 6:32 PM, Eric Anholt e...@anholt.net wrote:
  On Wed,  7 Dec 2011 10:24:09 +, Dave Airlie airl...@gmail.com wrote:
  From: Dave Airlie airl...@redhat.com
 
  This keeps track of the creation process and stores a drawable type,
  it then blocks DRI2 from getting called if the drawable is a pixmap.
 
  v2: check if we have a GLX drawable, which means we aren't a pbuffer,
  avoid doing flush at all since its meant to be a no-op.
 
  I still think this is the wrong way to go.  As ajax pointed out, there's
  all sorts of races available from trying to guess client-side, and
  there's no way anybody's relying on the current (print an error message
  in the xorg log) behavior of the DRI2 protocol for single-buffered, so
  we might as well resolve that DRI2 protocol should do what we want for
  GLX.
 
 I've been thinking about the races, and I'm not sure they really
 apply, like we would have all those races now with the current code,
 
 Look at the patch, when the glx_drawable struct is created we record
 the type of the pixmap, we then call GetGLXDrawable, which looks the
 XID up in the hash,
 so if the XID has been reused or raced, then we would have to expect
 the hash to be incorrect, or else avoid using it in a lot of other
 places.

True, but we could fix that by moving the UnlockDisplay() to after the
DRI2 stanza (and fixing the called code to not try to take the lock
itself).  There'd still be a race between the GLX and DRI2 requests, in
that someone else could Destroy that which you just created, but that's
a race against an actively malicious client; it would have to be
spamming the server with Destroy requests, since there's no way it can
know what XIDs you're going to pick.

In contrast, trying to track pixmapness like you're doing here races
against at least two app programming techniques that GLX allows and apps
actually use: multiple threads, and XID passing between applications.
In the latter case you'll not have fixed anything: glx_draw will be NULL
because we've not tracked this pixmap since its creation, so we'll carry
on with the DRI request.

The server is the only thing that knows how to handle this scenario, and
it _can_ get this request, so you have to fix it there anyway.  All you
can do in the client is optimize out sending some requests you know will
be no-ops.

But thanks for prompting me to re-read that code, it's less thread-safe
than I remembered.

- ajax


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


Re: [Mesa-dev] [PATCH] glx: block attempt to swapbuffer on pixmap. (v2)

2011-12-19 Thread Michel Dänzer
On Mon, 2011-12-19 at 10:14 -0500, Adam Jackson wrote: 
 On Mon, 2011-12-19 at 09:40 +, Dave Airlie wrote:
  On Wed, Dec 7, 2011 at 6:32 PM, Eric Anholt e...@anholt.net wrote:
   On Wed,  7 Dec 2011 10:24:09 +, Dave Airlie airl...@gmail.com wrote:
   From: Dave Airlie airl...@redhat.com
  
   This keeps track of the creation process and stores a drawable type,
   it then blocks DRI2 from getting called if the drawable is a pixmap.
  
   v2: check if we have a GLX drawable, which means we aren't a pbuffer,
   avoid doing flush at all since its meant to be a no-op.
  
   I still think this is the wrong way to go.  As ajax pointed out, there's
   all sorts of races available from trying to guess client-side, and
   there's no way anybody's relying on the current (print an error message
   in the xorg log) behavior of the DRI2 protocol for single-buffered, so
   we might as well resolve that DRI2 protocol should do what we want for
   GLX.
  
  I've been thinking about the races, and I'm not sure they really
  apply, like we would have all those races now with the current code,
  
  Look at the patch, when the glx_drawable struct is created we record
  the type of the pixmap, we then call GetGLXDrawable, which looks the
  XID up in the hash,
  so if the XID has been reused or raced, then we would have to expect
  the hash to be incorrect, or else avoid using it in a lot of other
  places.
 
 True, but we could fix that by moving the UnlockDisplay() to after the
 DRI2 stanza (and fixing the called code to not try to take the lock
 itself).  There'd still be a race between the GLX and DRI2 requests, in
 that someone else could Destroy that which you just created, but that's
 a race against an actively malicious client; it would have to be
 spamming the server with Destroy requests, since there's no way it can
 know what XIDs you're going to pick.
 
 In contrast, trying to track pixmapness like you're doing here races
 against at least two app programming techniques that GLX allows and apps
 actually use: multiple threads, and XID passing between applications.
 In the latter case you'll not have fixed anything: glx_draw will be NULL
 because we've not tracked this pixmap since its creation, so we'll carry
 on with the DRI request.
 
 The server is the only thing that knows how to handle this scenario, and
 it _can_ get this request, so you have to fix it there anyway.

Actually no, the DRI2 code in the server can't know, as this is a
perfectly legitimate request for a GLXPbuffer.


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


Re: [Mesa-dev] [PATCH] glx: block attempt to swapbuffer on pixmap. (v2)

2011-12-19 Thread Adam Jackson
On Mon, 2011-12-19 at 16:45 +0100, Michel Dänzer wrote:
 On Mon, 2011-12-19 at 10:14 -0500, Adam Jackson wrote: 

  The server is the only thing that knows how to handle this scenario, and
  it _can_ get this request, so you have to fix it there anyway.
 
 Actually no, the DRI2 code in the server can't know, as this is a
 perfectly legitimate request for a GLXPbuffer.

Only as an artifact of how we implement pbuffers (which is,
stylistically, a disaster).  And even then I don't think that's true,
just that the implementation would be unpleasant.  xserver gets
DRI2SwapBuffers on an XID for an X pixmap.  It can either be backing a
GLXPixmap or a GLXPbuffer, but not both*.  Therefore DRI2 needs to wrap
the glx drawable create path in the server, and stash a note on the
PixmapRec private for the GLXPixmap and GLXPbuffer cases.  That way
SwapBuffers has type information without needing to walk all GLXPixmaps
looking for an XID match with the backing pixmap.

This works because Pixmaps have to be created before GLXPixmaps, but the
backing pixmap for a pbuffer is created after the pbuffer.  So
technically that * above is a lie.  We create the backing pixmap for the
pbuffer inside xlib, and we don't leak that XID outside libGL, but the
client could guess.  The failure cases would be:

a) create pbuffer, guess Pixmap XID, bind a GLXPixmap to it
b) create Pixmap, create GLXPixmap, fabricate your own protocol for
CreatePbuffer and DRI2CreateDrawable to bind to the Pixmap

Both of which are detectable, because they involve calling
DRI2CreateDrawable a second time after you've already inferred type.

Or, better yet, if DRI2 insists on keeping the current weird 'alias'
semantics for DRI2CreateDrawable, it could alias based on the GLX
resource ID.  This would mean moving the creation of the backing pixmap
for pbuffers inside the server, but honestly that's a lot cleaner
anyway.  Among other things, there'd be no possibility of leaking an XID
to the client for the backing resource.

- ajax


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


[Mesa-dev] [PATCH] glx: block attempt to swapbuffer on pixmap. (v2)

2011-12-07 Thread Dave Airlie
From: Dave Airlie airl...@redhat.com

This keeps track of the creation process and stores a drawable type,
it then blocks DRI2 from getting called if the drawable is a pixmap.

v2: check if we have a GLX drawable, which means we aren't a pbuffer,
avoid doing flush at all since its meant to be a no-op.

Suggested by Michel Dänzer mic...@daenzer.net
Signed-off-by: Dave Airlie airl...@redhat.com
---
 src/glx/glx_pbuffer.c |3 ++-
 src/glx/glxclient.h   |3 ++-
 src/glx/glxcmds.c |   10 --
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/src/glx/glx_pbuffer.c b/src/glx/glx_pbuffer.c
index 6738252..4bc3292 100644
--- a/src/glx/glx_pbuffer.c
+++ b/src/glx/glx_pbuffer.c
@@ -434,7 +434,8 @@ CreateDrawable(Display *dpy, struct glx_config *config,
UnlockDisplay(dpy);
SyncHandle();
 
-   if (InitGLXDrawable(dpy, glxDraw, drawable, xid)) {
+   if (InitGLXDrawable(dpy, glxDraw, drawable, xid, 
+  (glxCode == X_GLXCreatePixmap) ? GLX_PIXMAP_BIT : 
GLX_WINDOW_BIT)) {
   free(glxDraw);
   return None;
}
diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h
index f915426..a47a2f7 100644
--- a/src/glx/glxclient.h
+++ b/src/glx/glxclient.h
@@ -585,6 +585,7 @@ struct glx_drawable {
XID xDrawable;
XID drawable;
 
+   uint32_t drawableType;
uint32_t lastEventSbc;
int64_t eventSbcWrap;
 };
@@ -797,7 +798,7 @@ applegl_create_display(struct glx_display *display);
 
 extern struct glx_drawable *GetGLXDrawable(Display *dpy, GLXDrawable drawable);
 extern int InitGLXDrawable(Display *dpy, struct glx_drawable *glxDraw,
-  XID xDrawable, GLXDrawable drawable);
+  XID xDrawable, GLXDrawable drawable, uint32_t 
drawableType);
 extern void DestroyGLXDrawable(Display *dpy, GLXDrawable drawable);
 
 extern struct glx_context dummyContext;
diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c
index c8ec9c2..634f0c5 100644
--- a/src/glx/glxcmds.c
+++ b/src/glx/glxcmds.c
@@ -107,7 +107,7 @@ GetGLXDrawable(Display *dpy, GLXDrawable drawable)
 
 _X_HIDDEN int
 InitGLXDrawable(Display *dpy, struct glx_drawable *glxDraw, XID xDrawable,
-   GLXDrawable drawable)
+GLXDrawable drawable, uint32_t drawableType)
 {
struct glx_display *priv = __glXInitialize(dpy);
 
@@ -118,6 +118,7 @@ InitGLXDrawable(Display *dpy, struct glx_drawable *glxDraw, 
XID xDrawable,
glxDraw-drawable = drawable;
glxDraw-lastEventSbc = 0;
glxDraw-eventSbcWrap = 0;
+   glxDraw-drawableType = drawableType;
 
return __glxHashInsert(priv-glXDrawHash, drawable, glxDraw);
 }
@@ -678,7 +679,7 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap 
pixmap)
UnlockDisplay(dpy);
SyncHandle();
 
-   if (InitGLXDrawable(dpy, glxDraw, pixmap, req-glxpixmap)) {
+   if (InitGLXDrawable(dpy, glxDraw, pixmap, req-glxpixmap, GLX_PIXMAP_BIT)) {
   free(glxDraw);
   return None;
}
@@ -796,6 +797,11 @@ glXSwapBuffers(Display * dpy, GLXDrawable drawable)
 #if defined(GLX_DIRECT_RENDERING)  !defined(GLX_USE_APPLEGL)
{
   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
+  struct glx_drawable *glx_draw = GetGLXDrawable(dpy, drawable);
+
+  /* GLX specifies a swapbuffer on a Pixmap to be a no-op. */
+  if (glx_draw  glx_draw-drawableType == GLX_PIXMAP_BIT)
+ return;
 
   if (pdraw != NULL) {
  if (gc  drawable == gc-currentDrawable) {
-- 
1.7.6.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] glx: block attempt to swapbuffer on pixmap. (v2)

2011-12-07 Thread Michel Dänzer
On Mit, 2011-12-07 at 10:24 +, Dave Airlie wrote: 
 From: Dave Airlie airl...@redhat.com
 
 This keeps track of the creation process and stores a drawable type,
 it then blocks DRI2 from getting called if the drawable is a pixmap.
 
 v2: check if we have a GLX drawable, which means we aren't a pbuffer,
 avoid doing flush at all since its meant to be a no-op.
 
 Suggested by Michel Dänzer mic...@daenzer.net
 Signed-off-by: Dave Airlie airl...@redhat.com

[...]

 diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c
 index c8ec9c2..634f0c5 100644
 --- a/src/glx/glxcmds.c
 +++ b/src/glx/glxcmds.c
 @@ -796,6 +797,11 @@ glXSwapBuffers(Display * dpy, GLXDrawable drawable)
  #if defined(GLX_DIRECT_RENDERING)  !defined(GLX_USE_APPLEGL)
 {
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
 +  struct glx_drawable *glx_draw = GetGLXDrawable(dpy, drawable);
 +
 +  /* GLX specifies a swapbuffer on a Pixmap to be a no-op. */
 +  if (glx_draw  glx_draw-drawableType == GLX_PIXMAP_BIT)
 + return;
  
if (pdraw != NULL) {
   if (gc  drawable == gc-currentDrawable) {

I think __glXSwapBuffersMscOML needs similar treatment:

glXSwapBuffersMscOML is a no-op and will always return 0 if the
specified drawable was created with a non-double-buffered
GLXFBConfig or if the specified drawable is a GLXPixmap.

Looks good otherwise, thanks!


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


Re: [Mesa-dev] [PATCH] glx: block attempt to swapbuffer on pixmap. (v2)

2011-12-07 Thread Eric Anholt
On Wed,  7 Dec 2011 10:24:09 +, Dave Airlie airl...@gmail.com wrote:
 From: Dave Airlie airl...@redhat.com
 
 This keeps track of the creation process and stores a drawable type,
 it then blocks DRI2 from getting called if the drawable is a pixmap.
 
 v2: check if we have a GLX drawable, which means we aren't a pbuffer,
 avoid doing flush at all since its meant to be a no-op.

I still think this is the wrong way to go.  As ajax pointed out, there's
all sorts of races available from trying to guess client-side, and
there's no way anybody's relying on the current (print an error message
in the xorg log) behavior of the DRI2 protocol for single-buffered, so
we might as well resolve that DRI2 protocol should do what we want for
GLX.


pgpN0DeVKIF3G.pgp
Description: PGP signature
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev