[Mesa-dev] [PATCH] dri3: Prevent multiple freeing of buffers.

Sergii Romantsov sergii.romantsov at gmail.com
Fri Apr 6 08:12:24 UTC 2018


Commit 3160cb86aa92 adds optimization with flag 'reallocate'.
Processing of flag causes buffers freeing while pointer
is still hold in caller stack and than again used to be freed.

Fixes: 3160cb86aa92 "egl/x11: Re-allocate buffers if format is suboptimal"

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105906
Signed-off-by: Sergii Romantsov <sergii.romantsov at globallogic.com>
Tested-by: Andriy Khulap <andriy.khulap at globallogic.com>
---
 src/loader/loader_dri3_helper.c | 7 +++++--
 src/loader/loader_dri3_helper.h | 1 +
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index fe17df1..5f9cc42 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -422,7 +422,7 @@ dri3_handle_present_event(struct loader_dri3_drawable *draw,
             buf->busy = 0;
 
          if (buf && draw->cur_blit_source != b && !buf->busy &&
-             (buf->reallocate ||
+             ((buf->reallocate && !buf->in_use_to_destroy) ||
              (draw->num_back <= b && b < LOADER_DRI3_MAX_BACK))) {
             dri3_free_render_buffer(draw, buf);
             draw->buffers[b] = NULL;
@@ -1688,6 +1688,7 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
            (buffer_type == loader_dri3_buffer_front && draw->have_fake_front))
           && buffer) {
 
+         buffer->in_use_to_destroy = true;
          /* Fill the new buffer with data from an old buffer */
          dri3_fence_await(draw->conn, draw, buffer);
          if (!loader_dri3_blit_image(draw,
@@ -1731,6 +1732,7 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
       draw->buffers[buf_id] = buffer;
    }
    dri3_fence_await(draw->conn, draw, buffer);
+   buffer = draw->buffers[buf_id];
 
    /*
     * Do we need to preserve the content of a previous buffer?
@@ -1744,7 +1746,8 @@ dri3_get_buffer(__DRIdrawable *driDrawable,
    if (buffer_type == loader_dri3_buffer_back &&
        draw->cur_blit_source != -1 &&
        draw->buffers[draw->cur_blit_source] &&
-       buffer != draw->buffers[draw->cur_blit_source]) {
+       buffer != draw->buffers[draw->cur_blit_source] &&
+       buffer != NULL) {
 
       struct loader_dri3_buffer *source = draw->buffers[draw->cur_blit_source];
 
diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h
index 7e3d829..9232d61 100644
--- a/src/loader/loader_dri3_helper.h
+++ b/src/loader/loader_dri3_helper.h
@@ -62,6 +62,7 @@ struct loader_dri3_buffer {
    bool         busy;           /* Set on swap, cleared on IdleNotify */
    bool         own_pixmap;     /* We allocated the pixmap ID, free on destroy */
    bool         reallocate;     /* Buffer should be reallocated and not reused */
+   bool         in_use_to_destroy;     /* Buffer is in use and will be destroyed soon */
 
    uint32_t     num_planes;
    uint32_t     size;
-- 
2.7.4



More information about the mesa-dev mailing list