gallium/pb_bufmgr_cache: add a way to remove buffers from the cache explicitly
authorMarek Olšák <marek.olsak@amd.com>
Tue, 1 Sep 2015 02:07:54 +0000 (04:07 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Thu, 3 Sep 2015 16:41:40 +0000 (18:41 +0200)
This must be done before exporting a buffer as dmabuf fds, because
we lose track of who is using it and can't trust the reference counter.

Cc: 11.0 <mesa-stable@lists.freedesktop.org>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
src/gallium/auxiliary/pipebuffer/pb_bufmgr.h
src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c

index 147ce39041cf6ceb7a444fa12c4d6c635c58d0b3..1638d96a63bc0572f9c608eb191206bdbdd0c3e4 100644 (file)
@@ -166,6 +166,11 @@ pb_cache_manager_create(struct pb_manager *provider,
                         unsigned bypass_usage,
                         uint64_t maximum_cache_size);
 
+/**
+ * Remove a buffer from the cache, but keep it alive.
+ */
+void
+pb_cache_manager_remove_buffer(struct pb_buffer *buf);
 
 struct pb_fence_ops;
 
index 3b35049f679fd9492180d91dd4802347544dffc5..cc8ae84bb1bcc665609ebbf6e97dee5649f008ef 100644 (file)
@@ -104,18 +104,42 @@ pb_cache_manager(struct pb_manager *mgr)
 }
 
 
+static void
+_pb_cache_manager_remove_buffer_locked(struct pb_cache_buffer *buf)
+{
+   struct pb_cache_manager *mgr = buf->mgr;
+
+   if (buf->head.next) {
+      LIST_DEL(&buf->head);
+      assert(mgr->numDelayed);
+      --mgr->numDelayed;
+      mgr->cache_size -= buf->base.size;
+   }
+   buf->mgr = NULL;
+}
+
+void
+pb_cache_manager_remove_buffer(struct pb_buffer *pb_buf)
+{
+   struct pb_cache_buffer *buf = (struct pb_cache_buffer*)pb_buf;
+   struct pb_cache_manager *mgr = buf->mgr;
+
+   if (!mgr)
+      return;
+
+   pipe_mutex_lock(mgr->mutex);
+   _pb_cache_manager_remove_buffer_locked(buf);
+   pipe_mutex_unlock(mgr->mutex);
+}
+
 /**
  * Actually destroy the buffer.
  */
 static inline void
 _pb_cache_buffer_destroy(struct pb_cache_buffer *buf)
 {
-   struct pb_cache_manager *mgr = buf->mgr;
-
-   LIST_DEL(&buf->head);
-   assert(mgr->numDelayed);
-   --mgr->numDelayed;
-   mgr->cache_size -= buf->base.size;
+   if (buf->mgr)
+      _pb_cache_manager_remove_buffer_locked(buf);
    assert(!pipe_is_referenced(&buf->base.reference));
    pb_reference(&buf->buffer, NULL);
    FREE(buf);
@@ -156,6 +180,12 @@ pb_cache_buffer_destroy(struct pb_buffer *_buf)
    struct pb_cache_buffer *buf = pb_cache_buffer(_buf);   
    struct pb_cache_manager *mgr = buf->mgr;
 
+   if (!mgr) {
+      pb_reference(&buf->buffer, NULL);
+      FREE(buf);
+      return;
+   }
+
    pipe_mutex_lock(mgr->mutex);
    assert(!pipe_is_referenced(&buf->base.reference));