[Mesa-dev] [PATCH] egl/wayland: do not leak wl_buffer when it is locked

Juan A. Suarez Romero jasuarez at igalia.com
Wed Aug 8 16:39:40 UTC 2018


On Wed, 2018-08-08 at 17:21 +0100, Daniel Stone wrote:
> Hi Juan,
> 
> On Thu, 2 Aug 2018 at 10:02, Juan A. Suarez Romero <jasuarez at igalia.com> wrote:
> > If color buffer is locked, do not set its wayland buffer to NULL;
> > otherwise it can not be freed later.
> 
> It can: see the 'if (i == ARRAY_SIZE(...))' branch inside wl_buffer_release.

I think I didn't explain wrongly :)

If color buffer is locked, we set color_buffer.wl_buffer to NULL, and thus we
can't free wl_buffer later.

> 
> > This also fixes dEQP-EGL.functional.swap_buffers_with_damage.* tests.
> 
> How does it fix them? Is it just leaks, or is there a functional difference?

Besides this wl_buffer leak, the tests crashes. Found out that fixing the leak
the crash goes away.

> 
> > --- a/src/egl/drivers/dri2/platform_wayland.c
> > +++ b/src/egl/drivers/dri2/platform_wayland.c
> > @@ -412,8 +412,11 @@ dri2_wl_release_buffers(struct dri2_egl_surface *dri2_surf)
> > 
> >     for (int i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
> >        if (dri2_surf->color_buffers[i].wl_buffer &&
> > -          !dri2_surf->color_buffers[i].locked)
> > +          !dri2_surf->color_buffers[i].locked) {
> >           wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);
> > +         dri2_surf->color_buffers[i].wl_buffer = NULL;
> > +      }
> > +
> >        if (dri2_surf->color_buffers[i].dri_image)
> >           dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image);
> >        if (dri2_surf->color_buffers[i].linear_copy)
> > @@ -422,11 +425,9 @@ dri2_wl_release_buffers(struct dri2_egl_surface *dri2_surf)
> >           munmap(dri2_surf->color_buffers[i].data,
> >                  dri2_surf->color_buffers[i].data_size);
> > 
> > -      dri2_surf->color_buffers[i].wl_buffer = NULL;
> >        dri2_surf->color_buffers[i].dri_image = NULL;
> >        dri2_surf->color_buffers[i].linear_copy = NULL;
> >        dri2_surf->color_buffers[i].data = NULL;
> > -      dri2_surf->color_buffers[i].locked = false;
> 
> So in this case, we still occupy a slot with (wl_buffer != NULL &&
> locked == true) when we resize a surface when an old buffer is still
> locked.
> 
> I _think_ the main functional difference is that the buffer is now
> destroyed inside dri2_wl_destroy_surface() when the surface is
> destroyed, even if it is locked. Destroying a surface with a locked
> buffer is bad: calling wl_buffer_destroy() may provoke a fatal
> protocol error, as destroying whilst still in use is illegal. On the
> other hand, destroying the event queue without destroying the object
> may cause a use-after-free later when the event does arrive, if the
> connection is still alive (we should make that an assert really).
> 
> On the balance of things, I think destroying the buffer immediately
> (running the risk of a protocol error), is less bad. It would be even
> better if we could rely on clients to have destroyed their
> surface-wrapper object (causing all buffers to be released) by the
> time they destroy their EGLSurface, but that's of course never going
> to happen. So, assuming there's no unexpected consequences I haven't
> seen, this is:
> Reviewed-by: Daniel Stone <daniels at collabora.com>
> 

I understand this patch does not require any further work, right? Except
clarifying the commit messsage as explaining above.


> Cheers,
> Daniel
> 



More information about the mesa-dev mailing list