[PATCH] intel: Track known prime buffers for re-use
Keith Packard
keithp at keithp.com
Fri Nov 22 05:35:54 PST 2013
If the application sends us a file descriptor pointing at a prime
buffer that we've already got, we have to re-use the same bo_gem
structure or chaos will result.
Track the set of all known prime objects and look to see if the kernel
has returned one of those for a new file descriptor.
Signed-off-by: Keith Packard <keithp at keithp.com>
---
This one took a while to find -- multiple bo_gem structs pointing at
the same gem handle would either cause the object to be destroyed
before we were done using it, or we'd end up sending the same
gem_handle for multiple buffers.
This looks a lot like the named object handling stuff, as one would
expect.
intel/intel_bufmgr_gem.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
index df6fcec..2897bb2 100644
--- a/intel/intel_bufmgr_gem.c
+++ b/intel/intel_bufmgr_gem.c
@@ -112,6 +112,7 @@ typedef struct _drm_intel_bufmgr_gem {
drmMMListHead named;
drmMMListHead vma_cache;
+ drmMMListHead prime;
int vma_count, vma_open, vma_max;
uint64_t gtt_size;
@@ -2451,8 +2452,25 @@ drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr *bufmgr, int prime_fd, int s
uint32_t handle;
drm_intel_bo_gem *bo_gem;
struct drm_i915_gem_get_tiling get_tiling;
+ drmMMListHead *list;
ret = drmPrimeFDToHandle(bufmgr_gem->fd, prime_fd, &handle);
+
+ /*
+ * See if the kernel has already returned this buffer to us. Just as
+ * for named buffers, we must not create two bo's pointing at the same
+ * kernel object
+ */
+ for (list = bufmgr_gem->prime.next;
+ list != &bufmgr_gem->prime;
+ list = list->next) {
+ bo_gem = DRMLISTENTRY(drm_intel_bo_gem, list, name_list);
+ if (bo_gem->gem_handle == handle) {
+ drm_intel_gem_bo_reference(&bo_gem->bo);
+ return &bo_gem->bo;
+ }
+ }
+
if (ret) {
fprintf(stderr,"ret is %d %d\n", ret, errno);
return NULL;
@@ -2487,8 +2505,8 @@ drm_intel_bo_gem_create_from_prime(drm_intel_bufmgr *bufmgr, int prime_fd, int s
bo_gem->has_error = false;
bo_gem->reusable = false;
- DRMINITLISTHEAD(&bo_gem->name_list);
DRMINITLISTHEAD(&bo_gem->vma_list);
+ DRMLISTADDTAIL(&bo_gem->name_list, &bufmgr_gem->prime);
VG_CLEAR(get_tiling);
get_tiling.handle = bo_gem->gem_handle;
@@ -3301,5 +3319,7 @@ drm_intel_bufmgr_gem_init(int fd, int batch_size)
DRMINITLISTHEAD(&bufmgr_gem->vma_cache);
bufmgr_gem->vma_max = -1; /* unlimited by default */
+ DRMINITLISTHEAD(&bufmgr_gem->prime);
+
return &bufmgr_gem->bufmgr;
}
--
1.8.4.3
More information about the dri-devel
mailing list