[Mesa-dev] [PATCH v2 07/18] anv/allocator: Add a BO cache

Chris Wilson chris at chris-wilson.co.uk
Wed Mar 15 09:50:57 UTC 2017


On Tue, Mar 14, 2017 at 10:43:07PM -0700, Jason Ekstrand wrote:
> +void
> +anv_bo_cache_release(struct anv_device *device,
> +                     struct anv_bo_cache *cache,
> +                     struct anv_bo *bo_in,
> +                     VkAllocationCallbacks *alloc)
> +{
> +   assert(anv_bo_cache_lookup(cache, bo_in->gem_handle) == bo_in);
> +   struct anv_cached_bo *bo = (struct anv_cached_bo *)bo_in;
> +
> +   uint32_t count = __sync_fetch_and_add(&bo->refcount, -1);
> +   assert(count > 0);
> +   if (count > 1)
> +      return;
> +   assert(count == 1);
> +   assert(bo->refcount == 0);

There's a window here for a second thread to acquire a reference to the
bo, just before you then go and free it.

The trick is the final unref has to be inside the mutex, earlier can be
outside. See refcount_dec_and_lock() in the kernel.

bool atomic_dec_not_one(int *counter)
{
	int val = *counter;

	for (;;) {
		int old;

		if (val == 1)
			return false;

		old = __sync_bool_compare_and_swap(counter, val, val - 1)
		if (old == val)
			return true;

		val = old;
	}
}

bool refcount_dec_and_lock(int *counter, pthread_mutex_t *mutex)
{
	if (atomic_dec_not_one(counter))
		return false;
	
	pthread_mutex_lock(mutex);
	if (likely(!__sync_sub_and_fetch(counter)))
		return true;

	pthread_mutex_unlock(mutex);
	return false;
}

if (!refcount_dec_and_lock(&bo->refcount, &cache->mutex))
	return;

> +   struct hash_entry *entry =
> +      _mesa_hash_table_search(cache->bo_map,
> +                              (const void *)(uintptr_t)bo->bo.gem_handle);
> +   assert(entry);
> +   _mesa_hash_table_remove(cache->bo_map, entry);
> +
> +   pthread_mutex_unlock(&cache->mutex);
> +
> +   if (bo->bo.map)
> +      anv_gem_munmap(bo->bo.map, bo->bo.size);
> +
> +   anv_gem_close(device, bo->bo.gem_handle);
> +
> +   vk_free(alloc, bo);
> +}

-- 
Chris Wilson, Intel Open Source Technology Centre


More information about the mesa-dev mailing list