From mboxrd@z Thu Jan 1 00:00:00 1970 From: Keith Packard Subject: [PATCH] intel: Track known prime buffers for re-use Date: Fri, 22 Nov 2013 05:35:54 -0800 Message-ID: <1385127354-28573-1-git-send-email-keithp@keithp.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dri-devel-bounces@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org To: mesa-dev@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org List-Id: dri-devel@lists.freedesktop.org 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 --- 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