All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michel Dänzer" <michel@daenzer.net>
To: amd-gfx@lists.freedesktop.org
Cc: Emil Velikov <emil.l.velikov@gmail.com>, dri-devel@lists.freedesktop.org
Subject: [PATCH libdrm 4/9] amdgpu: Add struct amdgpu_core_device and amdgpu_core_bo
Date: Mon, 24 Jun 2019 18:54:01 +0200	[thread overview]
Message-ID: <20190624165406.13682-5-michel@daenzer.net> (raw)
In-Reply-To: <20190624165406.13682-1-michel@daenzer.net>

From: Michel Dänzer <michel.daenzer@amd.com>

They can be referenced by any number of struct amdgpu_device/bo, which
are used for amdgpu_device/bo_handle in the public API.

This allows keeping track of the DRM file descriptor passed to
amdgpu_device_initialize and the one used for CS submission etc.
separately. The core structs hold the information relevant for the
latter.

Because we now always keep a duplicate of the file descriptor passed to
amdgpu_device_initialize, we can use that for flink, and we no longer
need to check its authentication status (flink could never be expected
to work after passing an unauthenticated file descriptor to
amdgpu_device_initialize).

Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
---
 amdgpu/amdgpu_asic_id.c       |   4 +-
 amdgpu/amdgpu_bo.c            | 251 ++++++++++++++++++++++------------
 amdgpu/amdgpu_cs.c            |  64 +++++----
 amdgpu/amdgpu_device.c        | 219 ++++++++++++-----------------
 amdgpu/amdgpu_gpu_info.c      |  35 ++---
 amdgpu/amdgpu_internal.h      |  27 ++--
 amdgpu/amdgpu_vamgr.c         |   9 +-
 amdgpu/amdgpu_vm.c            |   4 +-
 tests/amdgpu/amdgpu_test.c    |   2 +-
 tests/amdgpu/bo_tests.c       |   2 +-
 tests/amdgpu/cs_tests.c       |   8 +-
 tests/amdgpu/deadlock_tests.c |   8 +-
 tests/amdgpu/uvd_enc_tests.c  |   2 +-
 tests/amdgpu/vce_tests.c      |  12 +-
 tests/amdgpu/vcn_tests.c      |   4 +-
 tests/amdgpu/vm_tests.c       |   2 +-
 16 files changed, 360 insertions(+), 293 deletions(-)

diff --git a/amdgpu/amdgpu_asic_id.c b/amdgpu/amdgpu_asic_id.c
index a5007ffc..356c8a59 100644
--- a/amdgpu/amdgpu_asic_id.c
+++ b/amdgpu/amdgpu_asic_id.c
@@ -34,7 +34,7 @@
 #include "amdgpu_drm.h"
 #include "amdgpu_internal.h"
 
-static int parse_one_line(struct amdgpu_device *dev, const char *line)
+static int parse_one_line(struct amdgpu_core_device *dev, const char *line)
 {
 	char *buf, *saveptr;
 	char *s_did;
@@ -104,7 +104,7 @@ out:
 	return r;
 }
 
-void amdgpu_parse_asic_ids(struct amdgpu_device *dev)
+void amdgpu_parse_asic_ids(struct amdgpu_core_device *dev)
 {
 	FILE *fp;
 	char *line = NULL;
diff --git a/amdgpu/amdgpu_bo.c b/amdgpu/amdgpu_bo.c
index 5bdb8fe8..7fec1f15 100644
--- a/amdgpu/amdgpu_bo.c
+++ b/amdgpu/amdgpu_bo.c
@@ -47,15 +47,15 @@ static int amdgpu_close_kms_handle(int fd, uint32_t handle)
 	return drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &args);
 }
 
-static int amdgpu_bo_create(amdgpu_device_handle dev,
-			    uint64_t size,
-			    uint32_t handle,
-			    amdgpu_bo_handle *buf_handle)
+static int amdgpu_core_bo_create(struct amdgpu_core_device *dev,
+				 uint64_t size,
+				 uint32_t handle,
+				 struct amdgpu_core_bo **out_bo)
 {
-	struct amdgpu_bo *bo;
+	struct amdgpu_core_bo *bo;
 	int r;
 
-	bo = calloc(1, sizeof(struct amdgpu_bo));
+	bo = calloc(1, sizeof(struct amdgpu_core_bo));
 	if (!bo)
 		return -ENOMEM;
 
@@ -66,19 +66,64 @@ static int amdgpu_bo_create(amdgpu_device_handle dev,
 	}
 
 	atomic_set(&bo->refcount, 1);
-	bo->dev = dev;
 	bo->alloc_size = size;
 	bo->handle = handle;
 	pthread_mutex_init(&bo->cpu_access_mutex, NULL);
 
-	*buf_handle = bo;
+	*out_bo = bo;
 	return 0;
 }
 
-drm_public int amdgpu_bo_alloc(amdgpu_device_handle dev,
+static int amdgpu_bo_create(amdgpu_device_handle user_dev,
+			    uint64_t size,
+			    uint32_t handle,
+			    amdgpu_bo_handle *buf_handle)
+{
+	struct amdgpu_core_device *dev = user_dev->core;
+	struct amdgpu_bo *user_bo = NULL;
+	struct amdgpu_core_bo *bo;
+	int r;
+
+	bo = handle_table_lookup(&dev->bo_handles, handle);
+
+	if (bo) {
+		for (user_bo = bo->user_bos; user_bo; user_bo = user_bo->next) {
+			if (user_bo->dev == user_dev) {
+				/* Re-use existing buffer */
+				atomic_inc(&user_bo->refcount);
+				r = 0;
+				goto out;
+			}
+		}
+		atomic_inc(&bo->refcount);
+	} else {
+		r = amdgpu_core_bo_create(dev, size, handle, &bo);
+		if (r)
+			goto out;
+	}
+
+	user_bo = calloc(1, sizeof(struct amdgpu_bo));
+	if (!user_bo) {
+		r = -ENOMEM;
+		goto out;
+	}
+
+	atomic_set(&user_bo->refcount, 1);
+	user_bo->next = bo->user_bos;
+	bo->user_bos = user_bo;
+	user_bo->core = bo;
+	user_bo->dev = user_dev;
+
+out:
+	*buf_handle = user_bo;
+	return r;
+}
+
+drm_public int amdgpu_bo_alloc(amdgpu_device_handle user_dev,
 			       struct amdgpu_bo_alloc_request *alloc_buffer,
 			       amdgpu_bo_handle *buf_handle)
 {
+	struct amdgpu_core_device *dev = user_dev->core;
 	union drm_amdgpu_gem_create args;
 	int r;
 
@@ -97,8 +142,8 @@ drm_public int amdgpu_bo_alloc(amdgpu_device_handle dev,
 		goto out;
 
 	pthread_mutex_lock(&dev->bo_table_mutex);
-	r = amdgpu_bo_create(dev, alloc_buffer->alloc_size, args.out.handle,
-			     buf_handle);
+	r = amdgpu_bo_create(user_dev, alloc_buffer->alloc_size,
+			     args.out.handle, buf_handle);
 	pthread_mutex_unlock(&dev->bo_table_mutex);
 	if (r) {
 		amdgpu_close_kms_handle(dev->fd, args.out.handle);
@@ -108,9 +153,10 @@ out:
 	return r;
 }
 
-drm_public int amdgpu_bo_set_metadata(amdgpu_bo_handle bo,
+drm_public int amdgpu_bo_set_metadata(amdgpu_bo_handle user_bo,
 				      struct amdgpu_bo_metadata *info)
 {
+	struct amdgpu_core_bo *bo = user_bo->core;
 	struct drm_amdgpu_gem_metadata args = {};
 
 	args.handle = bo->handle;
@@ -126,17 +172,19 @@ drm_public int amdgpu_bo_set_metadata(amdgpu_bo_handle bo,
 		memcpy(args.data.data, info->umd_metadata, info->size_metadata);
 	}
 
-	return drmCommandWriteRead(bo->dev->fd,
+	return drmCommandWriteRead(user_bo->dev->core->fd,
 				   DRM_AMDGPU_GEM_METADATA,
 				   &args, sizeof(args));
 }
 
-drm_public int amdgpu_bo_query_info(amdgpu_bo_handle bo,
+drm_public int amdgpu_bo_query_info(amdgpu_bo_handle user_bo,
 				    struct amdgpu_bo_info *info)
 {
+	struct amdgpu_core_bo *bo = user_bo->core;
 	struct drm_amdgpu_gem_metadata metadata = {};
 	struct drm_amdgpu_gem_create_in bo_info = {};
 	struct drm_amdgpu_gem_op gem_op = {};
+	int fd = user_bo->dev->core->fd;
 	int r;
 
 	/* Validate the BO passed in */
@@ -147,8 +195,8 @@ drm_public int amdgpu_bo_query_info(amdgpu_bo_handle bo,
 	metadata.handle = bo->handle;
 	metadata.op = AMDGPU_GEM_METADATA_OP_GET_METADATA;
 
-	r = drmCommandWriteRead(bo->dev->fd, DRM_AMDGPU_GEM_METADATA,
-				&metadata, sizeof(metadata));
+	r = drmCommandWriteRead(fd, DRM_AMDGPU_GEM_METADATA, &metadata,
+				sizeof(metadata));
 	if (r)
 		return r;
 
@@ -161,8 +209,7 @@ drm_public int amdgpu_bo_query_info(amdgpu_bo_handle bo,
 	gem_op.op = AMDGPU_GEM_OP_GET_GEM_CREATE_INFO;
 	gem_op.value = (uintptr_t)&bo_info;
 
-	r = drmCommandWriteRead(bo->dev->fd, DRM_AMDGPU_GEM_OP,
-				&gem_op, sizeof(gem_op));
+	r = drmCommandWriteRead(fd, DRM_AMDGPU_GEM_OP, &gem_op, sizeof(gem_op));
 	if (r)
 		return r;
 
@@ -182,29 +229,30 @@ drm_public int amdgpu_bo_query_info(amdgpu_bo_handle bo,
 	return 0;
 }
 
-static int amdgpu_bo_export_flink(amdgpu_bo_handle bo)
+static int amdgpu_bo_export_flink(amdgpu_bo_handle user_bo)
 {
+	struct amdgpu_core_device *dev = user_bo->dev->core;
+	struct amdgpu_core_bo *bo = user_bo->core;
+	int user_fd = user_bo->dev->user_fd;
 	struct drm_gem_flink flink;
 	int fd, dma_fd;
 	uint32_t handle;
 	int r;
 
-	fd = bo->dev->fd;
+	fd = dev->fd;
 	handle = bo->handle;
 	if (bo->flink_name)
 		return 0;
 
-
-	if (bo->dev->flink_fd != bo->dev->fd) {
-		r = drmPrimeHandleToFD(bo->dev->fd, bo->handle, DRM_CLOEXEC,
-				       &dma_fd);
+	if (user_fd != fd) {
+		r = drmPrimeHandleToFD(fd, bo->handle, DRM_CLOEXEC, &dma_fd);
 		if (!r) {
-			r = drmPrimeFDToHandle(bo->dev->flink_fd, dma_fd, &handle);
+			r = drmPrimeFDToHandle(user_fd, dma_fd, &handle);
 			close(dma_fd);
 		}
 		if (r)
 			return r;
-		fd = bo->dev->flink_fd;
+		fd = user_fd;
 	}
 	memset(&flink, 0, sizeof(flink));
 	flink.handle = handle;
@@ -215,25 +263,26 @@ static int amdgpu_bo_export_flink(amdgpu_bo_handle bo)
 
 	bo->flink_name = flink.name;
 
-	if (bo->dev->flink_fd != bo->dev->fd)
-		amdgpu_close_kms_handle(bo->dev->flink_fd, handle);
+	if (user_fd != dev->fd)
+		amdgpu_close_kms_handle(user_fd, handle);
 
-	pthread_mutex_lock(&bo->dev->bo_table_mutex);
-	r = handle_table_insert(&bo->dev->bo_flink_names, bo->flink_name, bo);
-	pthread_mutex_unlock(&bo->dev->bo_table_mutex);
+	pthread_mutex_lock(&dev->bo_table_mutex);
+	r = handle_table_insert(&dev->bo_flink_names, bo->flink_name, bo);
+	pthread_mutex_unlock(&dev->bo_table_mutex);
 
 	return r;
 }
 
-drm_public int amdgpu_bo_export(amdgpu_bo_handle bo,
+drm_public int amdgpu_bo_export(amdgpu_bo_handle user_bo,
 				enum amdgpu_bo_handle_type type,
 				uint32_t *shared_handle)
 {
+	struct amdgpu_core_bo *bo = user_bo->core;
 	int r;
 
 	switch (type) {
 	case amdgpu_bo_handle_type_gem_flink_name:
-		r = amdgpu_bo_export_flink(bo);
+		r = amdgpu_bo_export_flink(user_bo);
 		if (r)
 			return r;
 
@@ -246,21 +295,24 @@ drm_public int amdgpu_bo_export(amdgpu_bo_handle bo,
 		return 0;
 
 	case amdgpu_bo_handle_type_dma_buf_fd:
-		return drmPrimeHandleToFD(bo->dev->fd, bo->handle,
+		return drmPrimeHandleToFD(user_bo->dev->core->fd, bo->handle,
 					  DRM_CLOEXEC | DRM_RDWR,
 					  (int*)shared_handle);
 	}
 	return -EINVAL;
 }
 
-drm_public int amdgpu_bo_import(amdgpu_device_handle dev,
+drm_public int amdgpu_bo_import(amdgpu_device_handle user_dev,
 				enum amdgpu_bo_handle_type type,
 				uint32_t shared_handle,
-		     struct amdgpu_bo_import_result *output)
+				struct amdgpu_bo_import_result *output)
 {
+	struct amdgpu_core_device *dev = user_dev->core;
 	struct drm_gem_open open_arg = {};
-	struct amdgpu_bo *bo = NULL;
+	struct amdgpu_bo *user_bo = NULL;
 	uint32_t handle = 0, flink_name = 0;
+	int user_fd = user_dev->user_fd;
+	struct amdgpu_core_bo *bo;
 	uint64_t alloc_size = 0;
 	int r = 0;
 	int dma_fd;
@@ -313,37 +365,32 @@ drm_public int amdgpu_bo_import(amdgpu_device_handle dev,
 	}
 
 	if (bo) {
-		/* The buffer already exists, just bump the refcount. */
-		atomic_inc(&bo->refcount);
-		pthread_mutex_unlock(&dev->bo_table_mutex);
-
-		output->buf_handle = bo;
-		output->alloc_size = bo->alloc_size;
-		return 0;
+		handle = bo->handle;
+		alloc_size = bo->alloc_size;
+		goto bo_create;
 	}
 
 	/* Open the handle. */
 	switch (type) {
 	case amdgpu_bo_handle_type_gem_flink_name:
 		open_arg.name = shared_handle;
-		r = drmIoctl(dev->flink_fd, DRM_IOCTL_GEM_OPEN, &open_arg);
+		r = drmIoctl(user_fd, DRM_IOCTL_GEM_OPEN, &open_arg);
 		if (r)
 			goto unlock;
 
 		flink_name = shared_handle;
 		handle = open_arg.handle;
 		alloc_size = open_arg.size;
-		if (dev->flink_fd != dev->fd) {
-			r = drmPrimeHandleToFD(dev->flink_fd, handle,
-					       DRM_CLOEXEC, &dma_fd);
+		if (user_fd != dev->fd) {
+			r = drmPrimeHandleToFD(user_fd, handle, DRM_CLOEXEC,
+					       &dma_fd);
 			if (r)
 				goto free_bo_handle;
 			r = drmPrimeFDToHandle(dev->fd, dma_fd, &handle);
 			close(dma_fd);
 			if (r)
 				goto free_bo_handle;
-			r = amdgpu_close_kms_handle(dev->flink_fd,
-						    open_arg.handle);
+			r = amdgpu_close_kms_handle(user_fd, open_arg.handle);
 			if (r)
 				goto free_bo_handle;
 		}
@@ -360,11 +407,13 @@ drm_public int amdgpu_bo_import(amdgpu_device_handle dev,
 		assert(0); /* unreachable */
 	}
 
+bo_create:
 	/* Initialize it. */
-	r = amdgpu_bo_create(dev, alloc_size, handle, &bo);
+	r = amdgpu_bo_create(user_dev, alloc_size, handle, &user_bo);
 	if (r)
 		goto free_bo_handle;
 
+	bo = user_bo->core;
 	if (flink_name) {
 		bo->flink_name = flink_name;
 		r = handle_table_insert(&dev->bo_flink_names, flink_name,
@@ -374,17 +423,17 @@ drm_public int amdgpu_bo_import(amdgpu_device_handle dev,
 
 	}
 
-	output->buf_handle = bo;
+	output->buf_handle = user_bo;
 	output->alloc_size = bo->alloc_size;
 	pthread_mutex_unlock(&dev->bo_table_mutex);
 	return 0;
 
 free_bo_handle:
 	if (flink_name && open_arg.handle)
-		amdgpu_close_kms_handle(dev->flink_fd, open_arg.handle);
+		amdgpu_close_kms_handle(user_fd, open_arg.handle);
 
-	if (bo)
-		amdgpu_bo_free(bo);
+	if (user_bo)
+		amdgpu_bo_free(user_bo);
 	else
 		amdgpu_close_kms_handle(dev->fd, handle);
 unlock:
@@ -392,14 +441,10 @@ unlock:
 	return r;
 }
 
-drm_public int amdgpu_bo_free(amdgpu_bo_handle buf_handle)
+static void amdgpu_core_bo_free(struct amdgpu_bo *user_bo)
 {
-	struct amdgpu_device *dev;
-	struct amdgpu_bo *bo = buf_handle;
-
-	assert(bo != NULL);
-	dev = bo->dev;
-	pthread_mutex_lock(&dev->bo_table_mutex);
+	struct amdgpu_core_device *dev = user_bo->dev->core;
+	struct amdgpu_core_bo *bo = user_bo->core;
 
 	if (update_references(&bo->refcount, NULL)) {
 		/* Remove the buffer from the hash tables. */
@@ -412,12 +457,39 @@ drm_public int amdgpu_bo_free(amdgpu_bo_handle buf_handle)
 		/* Release CPU access. */
 		if (bo->cpu_map_count > 0) {
 			bo->cpu_map_count = 1;
-			amdgpu_bo_cpu_unmap(bo);
+			amdgpu_bo_cpu_unmap(user_bo);
 		}
 
 		amdgpu_close_kms_handle(dev->fd, bo->handle);
 		pthread_mutex_destroy(&bo->cpu_access_mutex);
 		free(bo);
+	} else if (bo->user_bos == user_bo) {
+		bo->user_bos = user_bo->next;
+	} else {
+		struct amdgpu_bo *iter;
+
+		for (iter = bo->user_bos; iter->next; iter = iter->next) {
+			if (iter->next == user_bo) {
+				iter->next = user_bo->next;
+				break;
+			}
+		}
+	}
+}
+
+drm_public int amdgpu_bo_free(amdgpu_bo_handle buf_handle)
+{
+	struct amdgpu_bo *user_bo = buf_handle;
+	struct amdgpu_core_device *dev;
+
+	assert(user_bo != NULL);
+	dev = user_bo->dev->core;
+
+	pthread_mutex_lock(&dev->bo_table_mutex);
+
+	if (update_references(&user_bo->refcount, NULL)) {
+		amdgpu_core_bo_free(user_bo);
+		free(user_bo);
 	}
 
 	pthread_mutex_unlock(&dev->bo_table_mutex);
@@ -430,8 +502,10 @@ drm_public void amdgpu_bo_inc_ref(amdgpu_bo_handle bo)
 	atomic_inc(&bo->refcount);
 }
 
-drm_public int amdgpu_bo_cpu_map(amdgpu_bo_handle bo, void **cpu)
+drm_public int amdgpu_bo_cpu_map(amdgpu_bo_handle user_bo, void **cpu)
 {
+	struct amdgpu_core_bo *bo = user_bo->core;
+	int fd = user_bo->dev->core->fd;
 	union drm_amdgpu_gem_mmap args;
 	void *ptr;
 	int r;
@@ -455,8 +529,7 @@ drm_public int amdgpu_bo_cpu_map(amdgpu_bo_handle bo, void **cpu)
 	 * The kernel driver ignores the offset and size parameters. */
 	args.in.handle = bo->handle;
 
-	r = drmCommandWriteRead(bo->dev->fd, DRM_AMDGPU_GEM_MMAP, &args,
-				sizeof(args));
+	r = drmCommandWriteRead(fd, DRM_AMDGPU_GEM_MMAP, &args, sizeof(args));
 	if (r) {
 		pthread_mutex_unlock(&bo->cpu_access_mutex);
 		return r;
@@ -464,7 +537,7 @@ drm_public int amdgpu_bo_cpu_map(amdgpu_bo_handle bo, void **cpu)
 
 	/* Map the buffer. */
 	ptr = drm_mmap(NULL, bo->alloc_size, PROT_READ | PROT_WRITE, MAP_SHARED,
-		       bo->dev->fd, args.out.addr_ptr);
+		       fd, args.out.addr_ptr);
 	if (ptr == MAP_FAILED) {
 		pthread_mutex_unlock(&bo->cpu_access_mutex);
 		return -errno;
@@ -478,8 +551,9 @@ drm_public int amdgpu_bo_cpu_map(amdgpu_bo_handle bo, void **cpu)
 	return 0;
 }
 
-drm_public int amdgpu_bo_cpu_unmap(amdgpu_bo_handle bo)
+drm_public int amdgpu_bo_cpu_unmap(amdgpu_bo_handle user_bo)
 {
+	struct amdgpu_core_bo *bo = user_bo->core;
 	int r;
 
 	pthread_mutex_lock(&bo->cpu_access_mutex);
@@ -504,18 +578,21 @@ drm_public int amdgpu_bo_cpu_unmap(amdgpu_bo_handle bo)
 	return r;
 }
 
-drm_public int amdgpu_query_buffer_size_alignment(amdgpu_device_handle dev,
+drm_public int amdgpu_query_buffer_size_alignment(amdgpu_device_handle user_dev,
 				struct amdgpu_buffer_size_alignments *info)
 {
+	struct amdgpu_core_device *dev = user_dev->core;
+
 	info->size_local = dev->dev_info.pte_fragment_size;
 	info->size_remote = dev->dev_info.gart_page_size;
 	return 0;
 }
 
-drm_public int amdgpu_bo_wait_for_idle(amdgpu_bo_handle bo,
+drm_public int amdgpu_bo_wait_for_idle(amdgpu_bo_handle user_bo,
 				       uint64_t timeout_ns,
 			    bool *busy)
 {
+	struct amdgpu_core_bo *bo = user_bo->core;
 	union drm_amdgpu_gem_wait_idle args;
 	int r;
 
@@ -523,7 +600,7 @@ drm_public int amdgpu_bo_wait_for_idle(amdgpu_bo_handle bo,
 	args.in.handle = bo->handle;
 	args.in.timeout = amdgpu_cs_calculate_timeout(timeout_ns);
 
-	r = drmCommandWriteRead(bo->dev->fd, DRM_AMDGPU_GEM_WAIT_IDLE,
+	r = drmCommandWriteRead(user_bo->dev->core->fd, DRM_AMDGPU_GEM_WAIT_IDLE,
 				&args, sizeof(args));
 
 	if (r == 0) {
@@ -535,13 +612,14 @@ drm_public int amdgpu_bo_wait_for_idle(amdgpu_bo_handle bo,
 	}
 }
 
-drm_public int amdgpu_find_bo_by_cpu_mapping(amdgpu_device_handle dev,
+drm_public int amdgpu_find_bo_by_cpu_mapping(amdgpu_device_handle user_dev,
 					     void *cpu,
 					     uint64_t size,
 					     amdgpu_bo_handle *buf_handle,
 					     uint64_t *offset_in_bo)
 {
-	struct amdgpu_bo *bo;
+	struct amdgpu_core_device *dev = user_dev->core;
+	struct amdgpu_core_bo *bo;
 	uint32_t i;
 	int r = 0;
 
@@ -564,8 +642,8 @@ drm_public int amdgpu_find_bo_by_cpu_mapping(amdgpu_device_handle dev,
 	}
 
 	if (i < dev->bo_handles.max_key) {
-		atomic_inc(&bo->refcount);
-		*buf_handle = bo;
+		r = amdgpu_bo_create(user_dev, bo->alloc_size, bo->handle,
+				     buf_handle);
 		*offset_in_bo = (uintptr_t)cpu - (uintptr_t)bo->cpu_ptr;
 	} else {
 		*buf_handle = NULL;
@@ -577,11 +655,12 @@ drm_public int amdgpu_find_bo_by_cpu_mapping(amdgpu_device_handle dev,
 	return r;
 }
 
-drm_public int amdgpu_create_bo_from_user_mem(amdgpu_device_handle dev,
+drm_public int amdgpu_create_bo_from_user_mem(amdgpu_device_handle user_dev,
 					      void *cpu,
 					      uint64_t size,
 					      amdgpu_bo_handle *buf_handle)
 {
+	struct amdgpu_core_device *dev = user_dev->core;
 	int r;
 	struct drm_amdgpu_gem_userptr args;
 
@@ -595,7 +674,7 @@ drm_public int amdgpu_create_bo_from_user_mem(amdgpu_device_handle dev,
 		goto out;
 
 	pthread_mutex_lock(&dev->bo_table_mutex);
-	r = amdgpu_bo_create(dev, size, args.handle, buf_handle);
+	r = amdgpu_bo_create(user_dev, size, args.handle, buf_handle);
 	pthread_mutex_unlock(&dev->bo_table_mutex);
 	if (r) {
 		amdgpu_close_kms_handle(dev->fd, args.handle);
@@ -605,11 +684,12 @@ out:
 	return r;
 }
 
-drm_public int amdgpu_bo_list_create_raw(amdgpu_device_handle dev,
+drm_public int amdgpu_bo_list_create_raw(amdgpu_device_handle user_dev,
 					 uint32_t number_of_buffers,
 					 struct drm_amdgpu_bo_list_entry *buffers,
 					 uint32_t *result)
 {
+	struct amdgpu_core_device *dev = user_dev->core;
 	union drm_amdgpu_bo_list args;
 	int r;
 
@@ -626,9 +706,10 @@ drm_public int amdgpu_bo_list_create_raw(amdgpu_device_handle dev,
 	return r;
 }
 
-drm_public int amdgpu_bo_list_destroy_raw(amdgpu_device_handle dev,
+drm_public int amdgpu_bo_list_destroy_raw(amdgpu_device_handle user_dev,
 					  uint32_t bo_list)
 {
+	struct amdgpu_core_device *dev = user_dev->core;
 	union drm_amdgpu_bo_list args;
 
 	memset(&args, 0, sizeof(args));
@@ -639,12 +720,13 @@ drm_public int amdgpu_bo_list_destroy_raw(amdgpu_device_handle dev,
 				   &args, sizeof(args));
 }
 
-drm_public int amdgpu_bo_list_create(amdgpu_device_handle dev,
+drm_public int amdgpu_bo_list_create(amdgpu_device_handle user_dev,
 				     uint32_t number_of_resources,
 				     amdgpu_bo_handle *resources,
 				     uint8_t *resource_prios,
 				     amdgpu_bo_list_handle *result)
 {
+	struct amdgpu_core_device *dev = user_dev->core;
 	struct drm_amdgpu_bo_list_entry *list;
 	union drm_amdgpu_bo_list args;
 	unsigned i;
@@ -674,7 +756,7 @@ drm_public int amdgpu_bo_list_create(amdgpu_device_handle dev,
 	args.in.bo_info_ptr = (uint64_t)(uintptr_t)list;
 
 	for (i = 0; i < number_of_resources; i++) {
-		list[i].bo_handle = resources[i]->handle;
+		list[i].bo_handle = resources[i]->core->handle;
 		if (resource_prios)
 			list[i].bo_priority = resource_prios[i];
 		else
@@ -740,7 +822,7 @@ drm_public int amdgpu_bo_list_update(amdgpu_bo_list_handle handle,
 	args.in.bo_info_ptr = (uintptr_t)list;
 
 	for (i = 0; i < number_of_resources; i++) {
-		list[i].bo_handle = resources[i]->handle;
+		list[i].bo_handle = resources[i]->core->handle;
 		if (resource_prios)
 			list[i].bo_priority = resource_prios[i];
 		else
@@ -770,7 +852,7 @@ drm_public int amdgpu_bo_va_op(amdgpu_bo_handle bo,
 				   AMDGPU_VM_PAGE_EXECUTABLE, ops);
 }
 
-drm_public int amdgpu_bo_va_op_raw(amdgpu_device_handle dev,
+drm_public int amdgpu_bo_va_op_raw(amdgpu_device_handle user_dev,
 				   amdgpu_bo_handle bo,
 				   uint64_t offset,
 				   uint64_t size,
@@ -778,6 +860,7 @@ drm_public int amdgpu_bo_va_op_raw(amdgpu_device_handle dev,
 				   uint64_t flags,
 				   uint32_t ops)
 {
+	struct amdgpu_core_device *dev = user_dev->core;
 	struct drm_amdgpu_gem_va va;
 	int r;
 
@@ -786,7 +869,7 @@ drm_public int amdgpu_bo_va_op_raw(amdgpu_device_handle dev,
 		return -EINVAL;
 
 	memset(&va, 0, sizeof(va));
-	va.handle = bo ? bo->handle : 0;
+	va.handle = bo ? bo->core->handle : 0;
 	va.operation = ops;
 	va.flags = flags;
 	va.va_address = addr;
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index 20d5aef2..98130105 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -48,22 +48,24 @@ static int amdgpu_cs_reset_sem(amdgpu_semaphore_handle sem);
  *
  * \return  0 on success otherwise POSIX Error code
 */
-drm_public int amdgpu_cs_ctx_create2(amdgpu_device_handle dev,
+drm_public int amdgpu_cs_ctx_create2(amdgpu_device_handle user_dev,
 				     uint32_t priority,
 				     amdgpu_context_handle *context)
 {
 	struct amdgpu_context *gpu_context;
+	struct amdgpu_core_device *dev;
 	union drm_amdgpu_ctx args;
 	int i, j, k;
 	int r;
 
-	if (!dev || !context)
+	if (!user_dev || !context)
 		return -EINVAL;
 
 	gpu_context = calloc(1, sizeof(struct amdgpu_context));
 	if (!gpu_context)
 		return -ENOMEM;
 
+	dev = user_dev->core;
 	gpu_context->dev = dev;
 
 	r = pthread_mutex_init(&gpu_context->sequence_mutex, NULL);
@@ -156,7 +158,7 @@ drm_public int amdgpu_cs_ctx_override_priority(amdgpu_device_handle dev,
 	memset(&args, 0, sizeof(args));
 
 	args.in.op = AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE;
-	args.in.fd = dev->fd;
+	args.in.fd = dev->core->fd;
 	args.in.priority = priority;
 	args.in.ctx_id = context->id;
 
@@ -269,7 +271,7 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
 		chunks[i].chunk_data = (uint64_t)(uintptr_t)&chunk_data[i];
 
 		/* fence bo handle */
-		chunk_data[i].fence_data.handle = ibs_request->fence_info.handle->handle;
+		chunk_data[i].fence_data.handle = ibs_request->fence_info.handle->core->handle;
 		/* offset */
 		chunk_data[i].fence_data.offset = 
 			ibs_request->fence_info.offset * sizeof(uint64_t);
@@ -409,7 +411,7 @@ static int amdgpu_ioctl_wait_cs(amdgpu_context_handle context,
 				uint64_t flags,
 				bool *busy)
 {
-	amdgpu_device_handle dev = context->dev;
+	struct amdgpu_core_device *dev = context->dev;
 	union drm_amdgpu_wait_cs args;
 	int r;
 
@@ -471,8 +473,8 @@ static int amdgpu_ioctl_wait_fences(struct amdgpu_cs_fence *fences,
 				    uint32_t *status,
 				    uint32_t *first)
 {
+	struct amdgpu_core_device *dev = fences[0].context->dev;
 	struct drm_amdgpu_fence *drm_fences;
-	amdgpu_device_handle dev = fences[0].context->dev;
 	union drm_amdgpu_wait_fences args;
 	int r;
 	uint32_t i;
@@ -633,7 +635,7 @@ drm_public int amdgpu_cs_create_syncobj2(amdgpu_device_handle dev,
 	if (NULL == dev)
 		return -EINVAL;
 
-	return drmSyncobjCreate(dev->fd, flags, handle);
+	return drmSyncobjCreate(dev->core->fd, flags, handle);
 }
 
 drm_public int amdgpu_cs_create_syncobj(amdgpu_device_handle dev,
@@ -642,7 +644,7 @@ drm_public int amdgpu_cs_create_syncobj(amdgpu_device_handle dev,
 	if (NULL == dev)
 		return -EINVAL;
 
-	return drmSyncobjCreate(dev->fd, 0, handle);
+	return drmSyncobjCreate(dev->core->fd, 0, handle);
 }
 
 drm_public int amdgpu_cs_destroy_syncobj(amdgpu_device_handle dev,
@@ -651,7 +653,7 @@ drm_public int amdgpu_cs_destroy_syncobj(amdgpu_device_handle dev,
 	if (NULL == dev)
 		return -EINVAL;
 
-	return drmSyncobjDestroy(dev->fd, handle);
+	return drmSyncobjDestroy(dev->core->fd, handle);
 }
 
 drm_public int amdgpu_cs_syncobj_reset(amdgpu_device_handle dev,
@@ -661,7 +663,7 @@ drm_public int amdgpu_cs_syncobj_reset(amdgpu_device_handle dev,
 	if (NULL == dev)
 		return -EINVAL;
 
-	return drmSyncobjReset(dev->fd, syncobjs, syncobj_count);
+	return drmSyncobjReset(dev->core->fd, syncobjs, syncobj_count);
 }
 
 drm_public int amdgpu_cs_syncobj_signal(amdgpu_device_handle dev,
@@ -671,7 +673,7 @@ drm_public int amdgpu_cs_syncobj_signal(amdgpu_device_handle dev,
 	if (NULL == dev)
 		return -EINVAL;
 
-	return drmSyncobjSignal(dev->fd, syncobjs, syncobj_count);
+	return drmSyncobjSignal(dev->core->fd, syncobjs, syncobj_count);
 }
 
 drm_public int amdgpu_cs_syncobj_timeline_signal(amdgpu_device_handle dev,
@@ -682,7 +684,7 @@ drm_public int amdgpu_cs_syncobj_timeline_signal(amdgpu_device_handle dev,
 	if (NULL == dev)
 		return -EINVAL;
 
-	return drmSyncobjTimelineSignal(dev->fd, syncobjs,
+	return drmSyncobjTimelineSignal(dev->core->fd, syncobjs,
 					points, syncobj_count);
 }
 
@@ -694,7 +696,7 @@ drm_public int amdgpu_cs_syncobj_wait(amdgpu_device_handle dev,
 	if (NULL == dev)
 		return -EINVAL;
 
-	return drmSyncobjWait(dev->fd, handles, num_handles, timeout_nsec,
+	return drmSyncobjWait(dev->core->fd, handles, num_handles, timeout_nsec,
 			      flags, first_signaled);
 }
 
@@ -707,7 +709,7 @@ drm_public int amdgpu_cs_syncobj_timeline_wait(amdgpu_device_handle dev,
 	if (NULL == dev)
 		return -EINVAL;
 
-	return drmSyncobjTimelineWait(dev->fd, handles, points, num_handles,
+	return drmSyncobjTimelineWait(dev->core->fd, handles, points, num_handles,
 				      timeout_nsec, flags, first_signaled);
 }
 
@@ -718,7 +720,7 @@ drm_public int amdgpu_cs_syncobj_query(amdgpu_device_handle dev,
 	if (NULL == dev)
 		return -EINVAL;
 
-	return drmSyncobjQuery(dev->fd, handles, points, num_handles);
+	return drmSyncobjQuery(dev->core->fd, handles, points, num_handles);
 }
 
 drm_public int amdgpu_cs_export_syncobj(amdgpu_device_handle dev,
@@ -728,7 +730,7 @@ drm_public int amdgpu_cs_export_syncobj(amdgpu_device_handle dev,
 	if (NULL == dev)
 		return -EINVAL;
 
-	return drmSyncobjHandleToFD(dev->fd, handle, shared_fd);
+	return drmSyncobjHandleToFD(dev->core->fd, handle, shared_fd);
 }
 
 drm_public int amdgpu_cs_import_syncobj(amdgpu_device_handle dev,
@@ -738,7 +740,7 @@ drm_public int amdgpu_cs_import_syncobj(amdgpu_device_handle dev,
 	if (NULL == dev)
 		return -EINVAL;
 
-	return drmSyncobjFDToHandle(dev->fd, shared_fd, handle);
+	return drmSyncobjFDToHandle(dev->core->fd, shared_fd, handle);
 }
 
 drm_public int amdgpu_cs_syncobj_export_sync_file(amdgpu_device_handle dev,
@@ -748,7 +750,7 @@ drm_public int amdgpu_cs_syncobj_export_sync_file(amdgpu_device_handle dev,
 	if (NULL == dev)
 		return -EINVAL;
 
-	return drmSyncobjExportSyncFile(dev->fd, syncobj, sync_file_fd);
+	return drmSyncobjExportSyncFile(dev->core->fd, syncobj, sync_file_fd);
 }
 
 drm_public int amdgpu_cs_syncobj_import_sync_file(amdgpu_device_handle dev,
@@ -758,21 +760,24 @@ drm_public int amdgpu_cs_syncobj_import_sync_file(amdgpu_device_handle dev,
 	if (NULL == dev)
 		return -EINVAL;
 
-	return drmSyncobjImportSyncFile(dev->fd, syncobj, sync_file_fd);
+	return drmSyncobjImportSyncFile(dev->core->fd, syncobj, sync_file_fd);
 }
 
-drm_public int amdgpu_cs_syncobj_export_sync_file2(amdgpu_device_handle dev,
+drm_public int amdgpu_cs_syncobj_export_sync_file2(amdgpu_device_handle user_dev,
 						   uint32_t syncobj,
 						   uint64_t point,
 						   uint32_t flags,
 						   int *sync_file_fd)
 {
+	struct amdgpu_core_device *dev;
 	uint32_t binary_handle;
 	int ret;
 
-	if (NULL == dev)
+	if (!user_dev)
 		return -EINVAL;
 
+	dev = user_dev->core;
+
 	if (!point)
 		return drmSyncobjExportSyncFile(dev->fd, syncobj, sync_file_fd);
 
@@ -790,17 +795,20 @@ out:
 	return ret;
 }
 
-drm_public int amdgpu_cs_syncobj_import_sync_file2(amdgpu_device_handle dev,
+drm_public int amdgpu_cs_syncobj_import_sync_file2(amdgpu_device_handle user_dev,
 						   uint32_t syncobj,
 						   uint64_t point,
 						   int sync_file_fd)
 {
+	struct amdgpu_core_device *dev;
 	uint32_t binary_handle;
 	int ret;
 
-	if (NULL == dev)
+	if (!user_dev)
 		return -EINVAL;
 
+	dev = user_dev->core;
+
 	if (!point)
 		return drmSyncobjImportSyncFile(dev->fd, syncobj, sync_file_fd);
 
@@ -827,7 +835,7 @@ drm_public int amdgpu_cs_syncobj_transfer(amdgpu_device_handle dev,
 	if (NULL == dev)
 		return -EINVAL;
 
-	return drmSyncobjTransfer(dev->fd,
+	return drmSyncobjTransfer(dev->core->fd,
 				  dst_handle, dst_point,
 				  src_handle, src_point,
 				  flags);
@@ -854,7 +862,7 @@ drm_public int amdgpu_cs_submit_raw(amdgpu_device_handle dev,
 	cs.in.ctx_id = context->id;
 	cs.in.bo_list_handle = bo_list_handle ? bo_list_handle->handle : 0;
 	cs.in.num_chunks = num_chunks;
-	r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_CS,
+	r = drmCommandWriteRead(dev->core->fd, DRM_AMDGPU_CS,
 				&cs, sizeof(cs));
 	if (r)
 		return r;
@@ -883,7 +891,7 @@ drm_public int amdgpu_cs_submit_raw2(amdgpu_device_handle dev,
 	cs.in.ctx_id = context->id;
 	cs.in.bo_list_handle = bo_list_handle;
 	cs.in.num_chunks = num_chunks;
-	r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_CS,
+	r = drmCommandWriteRead(dev->core->fd, DRM_AMDGPU_CS,
 				&cs, sizeof(cs));
 	if (!r && seq_no)
 		*seq_no = cs.out.handle;
@@ -893,7 +901,7 @@ drm_public int amdgpu_cs_submit_raw2(amdgpu_device_handle dev,
 drm_public void amdgpu_cs_chunk_fence_info_to_data(struct amdgpu_cs_fence_info *fence_info,
 					struct drm_amdgpu_cs_chunk_data *data)
 {
-	data->fence_data.handle = fence_info->handle->handle;
+	data->fence_data.handle = fence_info->handle->core->handle;
 	data->fence_data.offset = fence_info->offset * sizeof(uint64_t);
 }
 
@@ -923,7 +931,7 @@ drm_public int amdgpu_cs_fence_to_handle(amdgpu_device_handle dev,
 	fth.in.fence.seq_no = fence->fence;
 	fth.in.what = what;
 
-	r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_FENCE_TO_HANDLE,
+	r = drmCommandWriteRead(dev->core->fd, DRM_AMDGPU_FENCE_TO_HANDLE,
 				&fth, sizeof(fth));
 	if (r == 0)
 		*out_handle = fth.out.handle;
diff --git a/amdgpu/amdgpu_device.c b/amdgpu/amdgpu_device.c
index 76b4e5eb..abf5f942 100644
--- a/amdgpu/amdgpu_device.c
+++ b/amdgpu/amdgpu_device.c
@@ -44,7 +44,7 @@
 #define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x)))
 
 static pthread_mutex_t dev_mutex = PTHREAD_MUTEX_INITIALIZER;
-static amdgpu_device_handle dev_list;
+static struct amdgpu_core_device *dev_list;
 
 static int fd_compare(int fd1, int fd2)
 {
@@ -65,47 +65,15 @@ static int fd_compare(int fd1, int fd2)
 	return result;
 }
 
-/**
-* Get the authenticated form fd,
-*
-* \param   fd   - \c [in]  File descriptor for AMD GPU device
-* \param   auth - \c [out] Pointer to output the fd is authenticated or not
-*                          A render node fd, output auth = 0
-*                          A legacy fd, get the authenticated for compatibility root
-*
-* \return   0 on success\n
-*          >0 - AMD specific error code\n
-*          <0 - Negative POSIX Error code
-*/
-static int amdgpu_get_auth(int fd, int *auth)
+static void amdgpu_device_free(struct amdgpu_core_device *dev)
 {
-	int r = 0;
-	drm_client_t client = {};
-
-	if (drmGetNodeTypeFromFd(fd) == DRM_NODE_RENDER)
-		*auth = 0;
-	else {
-		client.idx = 0;
-		r = drmIoctl(fd, DRM_IOCTL_GET_CLIENT, &client);
-		if (!r)
-			*auth = client.auth;
-	}
-	return r;
-}
+	struct amdgpu_core_device **node = &dev_list;
 
-static void amdgpu_device_free_internal(amdgpu_device_handle dev)
-{
-	amdgpu_device_handle *node = &dev_list;
-
-	pthread_mutex_lock(&dev_mutex);
 	while (*node != dev && (*node)->next)
 		node = &(*node)->next;
 	*node = (*node)->next;
-	pthread_mutex_unlock(&dev_mutex);
 
 	close(dev->fd);
-	if ((dev->flink_fd >= 0) && (dev->fd != dev->flink_fd))
-		close(dev->flink_fd);
 
 	amdgpu_vamgr_deinit(&dev->vamgr_32);
 	amdgpu_vamgr_deinit(&dev->vamgr);
@@ -118,87 +86,39 @@ static void amdgpu_device_free_internal(amdgpu_device_handle dev)
 	free(dev);
 }
 
-/**
- * Assignment between two amdgpu_device pointers with reference counting.
- *
- * Usage:
- *    struct amdgpu_device *dst = ... , *src = ...;
- *
- *    dst = src;
- *    // No reference counting. Only use this when you need to move
- *    // a reference from one pointer to another.
- *
- *    amdgpu_device_reference(&dst, src);
- *    // Reference counters are updated. dst is decremented and src is
- *    // incremented. dst is freed if its reference counter is 0.
- */
-static void amdgpu_device_reference(struct amdgpu_device **dst,
-				    struct amdgpu_device *src)
+static int amdgpu_device_init(amdgpu_device_handle user_dev)
 {
-	if (update_references(&(*dst)->refcount, &src->refcount))
-		amdgpu_device_free_internal(*dst);
-	*dst = src;
-}
-
-drm_public int amdgpu_device_initialize(int fd,
-					uint32_t *major_version,
-					uint32_t *minor_version,
-					amdgpu_device_handle *device_handle)
-{
-	struct amdgpu_device *dev;
+	struct amdgpu_core_device *dev;
 	drmVersionPtr version;
-	int r;
-	int flag_auth = 0;
-	int flag_authexist=0;
-	uint32_t accel_working = 0;
 	uint64_t start, max;
-
-	*device_handle = NULL;
-
-	pthread_mutex_lock(&dev_mutex);
-	r = amdgpu_get_auth(fd, &flag_auth);
-	if (r) {
-		fprintf(stderr, "%s: amdgpu_get_auth (1) failed (%i)\n",
-			__func__, r);
-		pthread_mutex_unlock(&dev_mutex);
-		return r;
-	}
+	int r;
 
 	for (dev = dev_list; dev; dev = dev->next)
-		if (fd_compare(dev->fd, fd) == 0)
+		if (fd_compare(dev->fd, user_dev->user_fd) == 0)
 			break;
 
 	if (dev) {
-		r = amdgpu_get_auth(dev->fd, &flag_authexist);
-		if (r) {
-			fprintf(stderr, "%s: amdgpu_get_auth (2) failed (%i)\n",
-				__func__, r);
-			pthread_mutex_unlock(&dev_mutex);
-			return r;
-		}
-		if ((flag_auth) && (!flag_authexist)) {
-			dev->flink_fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
-		}
-		*major_version = dev->major_version;
-		*minor_version = dev->minor_version;
-		amdgpu_device_reference(device_handle, dev);
-		pthread_mutex_unlock(&dev_mutex);
+		atomic_inc(&dev->refcount);
+		user_dev->core = dev;
 		return 0;
 	}
 
-	dev = calloc(1, sizeof(struct amdgpu_device));
+	dev = calloc(1, sizeof(struct amdgpu_core_device));
 	if (!dev) {
 		fprintf(stderr, "%s: calloc failed\n", __func__);
-		pthread_mutex_unlock(&dev_mutex);
 		return -ENOMEM;
 	}
 
-	dev->fd = -1;
-	dev->flink_fd = -1;
-
 	atomic_set(&dev->refcount, 1);
+	pthread_mutex_init(&dev->bo_table_mutex, NULL);
+
+	dev->fd = user_dev->user_fd;
+	user_dev->core = dev;
+
+	dev->next = dev_list;
+	dev_list = dev;
 
-	version = drmGetVersion(fd);
+	version = drmGetVersion(dev->fd);
 	if (version->version_major != 3) {
 		fprintf(stderr, "%s: DRM version is %d.%d.%d but this driver is "
 			"only compatible with 3.x.x.\n",
@@ -211,28 +131,11 @@ drm_public int amdgpu_device_initialize(int fd,
 		goto cleanup;
 	}
 
-	dev->fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
-	dev->flink_fd = dev->fd;
 	dev->major_version = version->version_major;
 	dev->minor_version = version->version_minor;
 	drmFreeVersion(version);
 
-	pthread_mutex_init(&dev->bo_table_mutex, NULL);
-
-	/* Check if acceleration is working. */
-	r = amdgpu_query_info(dev, AMDGPU_INFO_ACCEL_WORKING, 4, &accel_working);
-	if (r) {
-		fprintf(stderr, "%s: amdgpu_query_info(ACCEL_WORKING) failed (%i)\n",
-			__func__, r);
-		goto cleanup;
-	}
-	if (!accel_working) {
-		fprintf(stderr, "%s: AMDGPU_INFO_ACCEL_WORKING = 0\n", __func__);
-		r = -EBADF;
-		goto cleanup;
-	}
-
-	r = amdgpu_query_gpu_info_init(dev);
+	r = amdgpu_query_gpu_info_init(user_dev);
 	if (r) {
 		fprintf(stderr, "%s: amdgpu_query_gpu_info_init failed\n", __func__);
 		goto cleanup;
@@ -261,39 +164,97 @@ drm_public int amdgpu_device_initialize(int fd,
 			  dev->dev_info.virtual_address_alignment);
 
 	amdgpu_parse_asic_ids(dev);
+	return 0;
 
-	*major_version = dev->major_version;
-	*minor_version = dev->minor_version;
-	*device_handle = dev;
-	dev->next = dev_list;
-	dev_list = dev;
+cleanup:
+	user_dev->core = NULL;
+	close(dev->fd);
+	free(dev);
+	return r;
+}
+
+drm_public int amdgpu_device_initialize(int fd,
+					uint32_t *major_version,
+					uint32_t *minor_version,
+					amdgpu_device_handle *device_handle)
+{
+	struct amdgpu_device *user_dev;
+	uint32_t accel_working = 0;
+	int r;
+
+	*device_handle = NULL;
+
+	user_dev = calloc(1, sizeof(struct amdgpu_device));
+	if (!user_dev) {
+		fprintf(stderr, "%s: calloc failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	user_dev->user_fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
+
+	pthread_mutex_lock(&dev_mutex);
+
+	r = amdgpu_device_init(user_dev);
+	if (r != 0)
+		goto cleanup;
+
+	/* Check if acceleration is working. */
+	r = amdgpu_query_info(user_dev, AMDGPU_INFO_ACCEL_WORKING, 4, &accel_working);
+	if (r) {
+		fprintf(stderr, "%s: amdgpu_query_info(ACCEL_WORKING) failed (%i)\n",
+			__func__, r);
+		goto cleanup;
+	}
+	if (!accel_working) {
+		fprintf(stderr, "%s: AMDGPU_INFO_ACCEL_WORKING = 0\n", __func__);
+		r = -EBADF;
+		goto cleanup;
+	}
+
+	*major_version = user_dev->core->major_version;
+	*minor_version = user_dev->core->minor_version;
+	*device_handle = user_dev;
 	pthread_mutex_unlock(&dev_mutex);
 
 	return 0;
 
 cleanup:
-	if (dev->fd >= 0)
-		close(dev->fd);
-	free(dev);
+	if (!user_dev->core || user_dev->user_fd != user_dev->core->fd)
+		close(user_dev->user_fd);
+	if (user_dev->core && update_references(&user_dev->core->refcount, NULL))
+		amdgpu_device_free(user_dev->core);
+	free(user_dev);
 	pthread_mutex_unlock(&dev_mutex);
 	return r;
 }
 
-drm_public int amdgpu_device_deinitialize(amdgpu_device_handle dev)
+drm_public int amdgpu_device_deinitialize(amdgpu_device_handle user_dev)
 {
-	amdgpu_device_reference(&dev, NULL);
+	struct amdgpu_core_device *dev = user_dev->core;
+
+	pthread_mutex_lock(&dev_mutex);
+
+	if (user_dev->user_fd != dev->fd)
+		close(user_dev->user_fd);
+
+	if (update_references(&dev->refcount, NULL))
+		amdgpu_device_free(dev);
+
+	pthread_mutex_unlock(&dev_mutex);
+	free(user_dev);
 	return 0;
 }
 
-drm_public const char *amdgpu_get_marketing_name(amdgpu_device_handle dev)
+drm_public const char *amdgpu_get_marketing_name(amdgpu_device_handle user_dev)
 {
-	return dev->marketing_name;
+	return user_dev->core->marketing_name;
 }
 
-drm_public int amdgpu_query_sw_info(amdgpu_device_handle dev,
+drm_public int amdgpu_query_sw_info(amdgpu_device_handle user_dev,
 				    enum amdgpu_sw_info info,
 				    void *value)
 {
+	struct amdgpu_core_device *dev = user_dev->core;
 	uint32_t *val32 = (uint32_t*)value;
 
 	switch (info) {
diff --git a/amdgpu/amdgpu_gpu_info.c b/amdgpu/amdgpu_gpu_info.c
index 777087f2..7253fbea 100644
--- a/amdgpu/amdgpu_gpu_info.c
+++ b/amdgpu/amdgpu_gpu_info.c
@@ -40,7 +40,7 @@ drm_public int amdgpu_query_info(amdgpu_device_handle dev, unsigned info_id,
 	request.return_size = size;
 	request.query = info_id;
 
-	return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
+	return drmCommandWrite(dev->core->fd, DRM_AMDGPU_INFO, &request,
 			       sizeof(struct drm_amdgpu_info));
 }
 
@@ -55,7 +55,7 @@ drm_public int amdgpu_query_crtc_from_id(amdgpu_device_handle dev, unsigned id,
 	request.query = AMDGPU_INFO_CRTC_FROM_ID;
 	request.mode_crtc.id = id;
 
-	return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
+	return drmCommandWrite(dev->core->fd, DRM_AMDGPU_INFO, &request,
 			       sizeof(struct drm_amdgpu_info));
 }
 
@@ -74,7 +74,7 @@ drm_public int amdgpu_read_mm_registers(amdgpu_device_handle dev,
 	request.read_mmr_reg.instance = instance;
 	request.read_mmr_reg.flags = flags;
 
-	return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
+	return drmCommandWrite(dev->core->fd, DRM_AMDGPU_INFO, &request,
 			       sizeof(struct drm_amdgpu_info));
 }
 
@@ -90,7 +90,7 @@ drm_public int amdgpu_query_hw_ip_count(amdgpu_device_handle dev,
 	request.query = AMDGPU_INFO_HW_IP_COUNT;
 	request.query_hw_ip.type = type;
 
-	return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
+	return drmCommandWrite(dev->core->fd, DRM_AMDGPU_INFO, &request,
 			       sizeof(struct drm_amdgpu_info));
 }
 
@@ -107,7 +107,7 @@ drm_public int amdgpu_query_hw_ip_info(amdgpu_device_handle dev, unsigned type,
 	request.query_hw_ip.type = type;
 	request.query_hw_ip.ip_instance = ip_instance;
 
-	return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
+	return drmCommandWrite(dev->core->fd, DRM_AMDGPU_INFO, &request,
 			       sizeof(struct drm_amdgpu_info));
 }
 
@@ -127,7 +127,7 @@ drm_public int amdgpu_query_firmware_version(amdgpu_device_handle dev,
 	request.query_fw.ip_instance = ip_instance;
 	request.query_fw.index = index;
 
-	r = drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
+	r = drmCommandWrite(dev->core->fd, DRM_AMDGPU_INFO, &request,
 			    sizeof(struct drm_amdgpu_info));
 	if (r)
 		return r;
@@ -137,11 +137,12 @@ drm_public int amdgpu_query_firmware_version(amdgpu_device_handle dev,
 	return 0;
 }
 
-drm_private int amdgpu_query_gpu_info_init(amdgpu_device_handle dev)
+drm_private int amdgpu_query_gpu_info_init(amdgpu_device_handle user_dev)
 {
+	struct amdgpu_core_device *dev = user_dev->core;
 	int r, i;
 
-	r = amdgpu_query_info(dev, AMDGPU_INFO_DEV_INFO, sizeof(dev->dev_info),
+	r = amdgpu_query_info(user_dev, AMDGPU_INFO_DEV_INFO, sizeof(dev->dev_info),
 			      &dev->dev_info);
 	if (r)
 		return r;
@@ -172,7 +173,7 @@ drm_private int amdgpu_query_gpu_info_init(amdgpu_device_handle dev)
 					    (AMDGPU_INFO_MMR_SH_INDEX_MASK <<
 					     AMDGPU_INFO_MMR_SH_INDEX_SHIFT);
 
-			r = amdgpu_read_mm_registers(dev, 0x263d, 1, instance, 0,
+			r = amdgpu_read_mm_registers(user_dev, 0x263d, 1, instance, 0,
 						     &dev->info.backend_disable[i]);
 			if (r)
 				return r;
@@ -180,13 +181,13 @@ drm_private int amdgpu_query_gpu_info_init(amdgpu_device_handle dev)
 			dev->info.backend_disable[i] =
 				(dev->info.backend_disable[i] >> 16) & 0xff;
 
-			r = amdgpu_read_mm_registers(dev, 0xa0d4, 1, instance, 0,
+			r = amdgpu_read_mm_registers(user_dev, 0xa0d4, 1, instance, 0,
 						     &dev->info.pa_sc_raster_cfg[i]);
 			if (r)
 				return r;
 
 			if (dev->info.family_id >= AMDGPU_FAMILY_CI) {
-				r = amdgpu_read_mm_registers(dev, 0xa0d5, 1, instance, 0,
+				r = amdgpu_read_mm_registers(user_dev, 0xa0d5, 1, instance, 0,
 						     &dev->info.pa_sc_raster_cfg1[i]);
 				if (r)
 					return r;
@@ -194,25 +195,25 @@ drm_private int amdgpu_query_gpu_info_init(amdgpu_device_handle dev)
 		}
 	}
 
-	r = amdgpu_read_mm_registers(dev, 0x263e, 1, 0xffffffff, 0,
+	r = amdgpu_read_mm_registers(user_dev, 0x263e, 1, 0xffffffff, 0,
 					     &dev->info.gb_addr_cfg);
 	if (r)
 		return r;
 
 	if (dev->info.family_id < AMDGPU_FAMILY_AI) {
-		r = amdgpu_read_mm_registers(dev, 0x2644, 32, 0xffffffff, 0,
+		r = amdgpu_read_mm_registers(user_dev, 0x2644, 32, 0xffffffff, 0,
 					     dev->info.gb_tile_mode);
 		if (r)
 			return r;
 
 		if (dev->info.family_id >= AMDGPU_FAMILY_CI) {
-			r = amdgpu_read_mm_registers(dev, 0x2664, 16, 0xffffffff, 0,
+			r = amdgpu_read_mm_registers(user_dev, 0x2664, 16, 0xffffffff, 0,
 						     dev->info.gb_macro_tile_mode);
 			if (r)
 				return r;
 		}
 
-		r = amdgpu_read_mm_registers(dev, 0x9d8, 1, 0xffffffff, 0,
+		r = amdgpu_read_mm_registers(user_dev, 0x9d8, 1, 0xffffffff, 0,
 					     &dev->info.mc_arb_ramcfg);
 		if (r)
 			return r;
@@ -235,7 +236,7 @@ drm_public int amdgpu_query_gpu_info(amdgpu_device_handle dev,
 		return -EINVAL;
 
 	/* Get ASIC info*/
-	*info = dev->info;
+	*info = dev->core->info;
 
 	return 0;
 }
@@ -328,6 +329,6 @@ drm_public int amdgpu_query_sensor_info(amdgpu_device_handle dev, unsigned senso
 	request.query = AMDGPU_INFO_SENSOR;
 	request.sensor_info.type = sensor_type;
 
-	return drmCommandWrite(dev->fd, DRM_AMDGPU_INFO, &request,
+	return drmCommandWrite(dev->core->fd, DRM_AMDGPU_INFO, &request,
 			       sizeof(struct drm_amdgpu_info));
 }
diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h
index a340abbd..3a2ab74c 100644
--- a/amdgpu/amdgpu_internal.h
+++ b/amdgpu/amdgpu_internal.h
@@ -64,14 +64,13 @@ struct amdgpu_va {
 	struct amdgpu_bo_va_mgr *vamgr;
 };
 
-struct amdgpu_device {
+struct amdgpu_core_device {
 	atomic_t refcount;
-	struct amdgpu_device *next;
 	int fd;
-	int flink_fd;
 	unsigned major_version;
 	unsigned minor_version;
 
+	struct amdgpu_core_device *next;
 	char *marketing_name;
 	/** List of buffer handles. Protected by bo_table_mutex. */
 	struct handle_table bo_handles;
@@ -91,9 +90,14 @@ struct amdgpu_device {
 	struct amdgpu_bo_va_mgr vamgr_high_32;
 };
 
-struct amdgpu_bo {
+struct amdgpu_device {
+	int user_fd;
+	struct amdgpu_core_device *core;
+};
+
+struct amdgpu_core_bo {
 	atomic_t refcount;
-	struct amdgpu_device *dev;
+	amdgpu_bo_handle user_bos;
 
 	uint64_t alloc_size;
 
@@ -105,14 +109,21 @@ struct amdgpu_bo {
 	int cpu_map_count;
 };
 
-struct amdgpu_bo_list {
+struct amdgpu_bo {
+	atomic_t refcount;
+	struct amdgpu_bo *next;
+	struct amdgpu_core_bo *core;
 	struct amdgpu_device *dev;
+};
+
+struct amdgpu_bo_list {
+	struct amdgpu_core_device *dev;
 
 	uint32_t handle;
 };
 
 struct amdgpu_context {
-	struct amdgpu_device *dev;
+	struct amdgpu_core_device *dev;
 	/** Mutex for accessing fences and to maintain command submissions
 	    in good sequence. */
 	pthread_mutex_t sequence_mutex;
@@ -141,7 +152,7 @@ drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
 
 drm_private void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr);
 
-drm_private void amdgpu_parse_asic_ids(struct amdgpu_device *dev);
+drm_private void amdgpu_parse_asic_ids(struct amdgpu_core_device *dev);
 
 drm_private int amdgpu_query_gpu_info_init(amdgpu_device_handle dev);
 
diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
index d25d4216..560b84e7 100644
--- a/amdgpu/amdgpu_vamgr.c
+++ b/amdgpu/amdgpu_vamgr.c
@@ -29,10 +29,12 @@
 #include "amdgpu_internal.h"
 #include "util_math.h"
 
-drm_public int amdgpu_va_range_query(amdgpu_device_handle dev,
+drm_public int amdgpu_va_range_query(amdgpu_device_handle user_dev,
 				     enum amdgpu_gpu_va_range type,
 				     uint64_t *start, uint64_t *end)
 {
+	struct amdgpu_core_device *dev = user_dev->core;
+
 	if (type != amdgpu_gpu_va_range_general)
 		return -EINVAL;
 
@@ -186,7 +188,7 @@ out:
 	pthread_mutex_unlock(&mgr->bo_va_mutex);
 }
 
-drm_public int amdgpu_va_range_alloc(amdgpu_device_handle dev,
+drm_public int amdgpu_va_range_alloc(amdgpu_device_handle user_dev,
 				     enum amdgpu_gpu_va_range va_range_type,
 				     uint64_t size,
 				     uint64_t va_base_alignment,
@@ -195,6 +197,7 @@ drm_public int amdgpu_va_range_alloc(amdgpu_device_handle dev,
 				     amdgpu_va_handle *va_range_handle,
 				     uint64_t flags)
 {
+	struct amdgpu_core_device *dev = user_dev->core;
 	struct amdgpu_bo_va_mgr *vamgr;
 
 	/* Clear the flag when the high VA manager is not initialized */
@@ -237,7 +240,7 @@ drm_public int amdgpu_va_range_alloc(amdgpu_device_handle dev,
 			amdgpu_vamgr_free_va(vamgr, *va_base_allocated, size);
 			return -ENOMEM;
 		}
-		va->dev = dev;
+		va->dev = user_dev;
 		va->address = *va_base_allocated;
 		va->size = size;
 		va->range = va_range_type;
diff --git a/amdgpu/amdgpu_vm.c b/amdgpu/amdgpu_vm.c
index 7e6e28f0..de44e6c2 100644
--- a/amdgpu/amdgpu_vm.c
+++ b/amdgpu/amdgpu_vm.c
@@ -33,7 +33,7 @@ drm_public int amdgpu_vm_reserve_vmid(amdgpu_device_handle dev, uint32_t flags)
 	vm.in.op = AMDGPU_VM_OP_RESERVE_VMID;
 	vm.in.flags = flags;
 
-	return drmCommandWriteRead(dev->fd, DRM_AMDGPU_VM,
+	return drmCommandWriteRead(dev->core->fd, DRM_AMDGPU_VM,
 				   &vm, sizeof(vm));
 }
 
@@ -45,6 +45,6 @@ drm_public int amdgpu_vm_unreserve_vmid(amdgpu_device_handle dev,
 	vm.in.op = AMDGPU_VM_OP_UNRESERVE_VMID;
 	vm.in.flags = flags;
 
-	return drmCommandWriteRead(dev->fd, DRM_AMDGPU_VM,
+	return drmCommandWriteRead(dev->core->fd, DRM_AMDGPU_VM,
 				   &vm, sizeof(vm));
 }
diff --git a/tests/amdgpu/amdgpu_test.c b/tests/amdgpu/amdgpu_test.c
index 73403fb4..7095c4e4 100644
--- a/tests/amdgpu/amdgpu_test.c
+++ b/tests/amdgpu/amdgpu_test.c
@@ -428,7 +428,7 @@ static void amdgpu_disable_suites()
 				   &minor_version, &device_handle))
 		return;
 
-	family_id = device_handle->info.family_id;
+	family_id = device_handle->core->info.family_id;
 
 	if (amdgpu_device_deinitialize(device_handle))
 		return;
diff --git a/tests/amdgpu/bo_tests.c b/tests/amdgpu/bo_tests.c
index 7cff4cf7..d89c944d 100644
--- a/tests/amdgpu/bo_tests.c
+++ b/tests/amdgpu/bo_tests.c
@@ -309,7 +309,7 @@ static void amdgpu_bo_find_by_cpu_mapping(void)
 					  &offset);
 	CU_ASSERT_EQUAL(r, 0);
 	CU_ASSERT_EQUAL(offset, 0);
-	CU_ASSERT_EQUAL(bo_handle->handle, find_bo_handle->handle);
+	CU_ASSERT_EQUAL(bo_handle->core->handle, find_bo_handle->core->handle);
 
 	atomic_dec(&find_bo_handle->refcount, 1);
 	r = amdgpu_bo_unmap_and_free(bo_handle, va_handle,
diff --git a/tests/amdgpu/cs_tests.c b/tests/amdgpu/cs_tests.c
index 7ad0f0dc..8a5f6ed3 100644
--- a/tests/amdgpu/cs_tests.c
+++ b/tests/amdgpu/cs_tests.c
@@ -68,7 +68,7 @@ CU_BOOL suite_cs_tests_enable(void)
 					     &minor_version, &device_handle))
 		return CU_FALSE;
 
-	family_id = device_handle->info.family_id;
+	family_id = device_handle->core->info.family_id;
 
 	if (amdgpu_device_deinitialize(device_handle))
 		return CU_FALSE;
@@ -101,10 +101,10 @@ int suite_cs_tests_init(void)
 		return CUE_SINIT_FAILED;
 	}
 
-	family_id = device_handle->info.family_id;
+	family_id = device_handle->core->info.family_id;
 	/* VI asic POLARIS10/11 have specific external_rev_id */
-	chip_rev = device_handle->info.chip_rev;
-	chip_id = device_handle->info.chip_external_rev;
+	chip_rev = device_handle->core->info.chip_rev;
+	chip_id = device_handle->core->info.chip_external_rev;
 
 	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
 	if (r)
diff --git a/tests/amdgpu/deadlock_tests.c b/tests/amdgpu/deadlock_tests.c
index 91368c15..8526bae7 100644
--- a/tests/amdgpu/deadlock_tests.c
+++ b/tests/amdgpu/deadlock_tests.c
@@ -127,14 +127,14 @@ CU_BOOL suite_deadlock_tests_enable(void)
 	 * Only enable for ASICs supporting GPU reset and for which it's enabled
 	 * by default (currently GFX8/9 dGPUS)
 	 */
-	if (device_handle->info.family_id != AMDGPU_FAMILY_VI &&
-	    device_handle->info.family_id != AMDGPU_FAMILY_AI &&
-	    device_handle->info.family_id != AMDGPU_FAMILY_CI) {
+	if (device_handle->core->info.family_id != AMDGPU_FAMILY_VI &&
+	    device_handle->core->info.family_id != AMDGPU_FAMILY_AI &&
+	    device_handle->core->info.family_id != AMDGPU_FAMILY_CI) {
 		printf("\n\nGPU reset is not enabled for the ASIC, deadlock suite disabled\n");
 		enable = CU_FALSE;
 	}
 
-	if (device_handle->info.family_id >= AMDGPU_FAMILY_AI)
+	if (device_handle->core->info.family_id >= AMDGPU_FAMILY_AI)
 		use_uc_mtype = 1;
 
 	if (amdgpu_device_deinitialize(device_handle))
diff --git a/tests/amdgpu/uvd_enc_tests.c b/tests/amdgpu/uvd_enc_tests.c
index b4251bcf..856e7ae1 100644
--- a/tests/amdgpu/uvd_enc_tests.c
+++ b/tests/amdgpu/uvd_enc_tests.c
@@ -114,7 +114,7 @@ int suite_uvd_enc_tests_init(void)
 	if (r)
 		return CUE_SINIT_FAILED;
 
-	family_id = device_handle->info.family_id;
+	family_id = device_handle->core->info.family_id;
 
 	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
 	if (r)
diff --git a/tests/amdgpu/vce_tests.c b/tests/amdgpu/vce_tests.c
index 0026826e..05d9ef57 100644
--- a/tests/amdgpu/vce_tests.c
+++ b/tests/amdgpu/vce_tests.c
@@ -103,10 +103,10 @@ CU_BOOL suite_vce_tests_enable(void)
 					     &minor_version, &device_handle))
 		return CU_FALSE;
 
-	family_id = device_handle->info.family_id;
-	chip_rev = device_handle->info.chip_rev;
-	chip_id = device_handle->info.chip_external_rev;
-	ids_flags = device_handle->info.ids_flags;
+	family_id = device_handle->core->info.family_id;
+	chip_rev = device_handle->core->info.chip_rev;
+	chip_id = device_handle->core->info.chip_external_rev;
+	ids_flags = device_handle->core->info.ids_flags;
 
 	amdgpu_query_firmware_version(device_handle, AMDGPU_INFO_FW_VCE, 0,
 					  0, &version, &feature);
@@ -153,8 +153,8 @@ int suite_vce_tests_init(void)
 		return CUE_SINIT_FAILED;
 	}
 
-	family_id = device_handle->info.family_id;
-	vce_harvest_config = device_handle->info.vce_harvest_config;
+	family_id = device_handle->core->info.family_id;
+	vce_harvest_config = device_handle->core->info.vce_harvest_config;
 
 	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
 	if (r)
diff --git a/tests/amdgpu/vcn_tests.c b/tests/amdgpu/vcn_tests.c
index ad438f35..17248444 100644
--- a/tests/amdgpu/vcn_tests.c
+++ b/tests/amdgpu/vcn_tests.c
@@ -94,7 +94,7 @@ CU_BOOL suite_vcn_tests_enable(void)
 				   &minor_version, &device_handle))
 		return CU_FALSE;
 
-	family_id = device_handle->info.family_id;
+	family_id = device_handle->core->info.family_id;
 
 	if (amdgpu_device_deinitialize(device_handle))
 			return CU_FALSE;
@@ -132,7 +132,7 @@ int suite_vcn_tests_init(void)
 	if (r)
 		return CUE_SINIT_FAILED;
 
-	family_id = device_handle->info.family_id;
+	family_id = device_handle->core->info.family_id;
 
 	r = amdgpu_cs_ctx_create(device_handle, &context_handle);
 	if (r)
diff --git a/tests/amdgpu/vm_tests.c b/tests/amdgpu/vm_tests.c
index 69bc4683..e52aef25 100644
--- a/tests/amdgpu/vm_tests.c
+++ b/tests/amdgpu/vm_tests.c
@@ -43,7 +43,7 @@ CU_BOOL suite_vm_tests_enable(void)
 				     &minor_version, &device_handle))
 		return CU_FALSE;
 
-	if (device_handle->info.family_id == AMDGPU_FAMILY_SI) {
+	if (device_handle->core->info.family_id == AMDGPU_FAMILY_SI) {
 		printf("\n\nCurrently hangs the CP on this ASIC, VM suite disabled\n");
 		enable = CU_FALSE;
 	}
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2019-06-24 16:54 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-24 16:53 [PATCH libdrm 0/9] amdgpu: Michel Dänzer
2019-06-24 16:54 ` Michel Dänzer [this message]
2019-06-24 16:54 ` [PATCH libdrm 5/9] amdgpu: Add amdgpu_bo_handle_type_kms_user Michel Dänzer
2019-06-24 16:54 ` [PATCH libdrm 6/9] amdgpu: Re-use an existing amdgpu_device when possible Michel Dänzer
2019-06-24 16:54 ` [PATCH libdrm 7/9] amdgpu: Use normal integers for device / core BO reference counting Michel Dänzer
     [not found] ` <20190624165406.13682-1-michel-otUistvHUpPR7s880joybQ@public.gmane.org>
2019-06-24 16:53   ` [PATCH libdrm 1/9] amdgpu: Pass file descriptor directly to amdgpu_close_kms_handle Michel Dänzer
2019-06-28 17:11     ` Emil Velikov
2019-06-24 16:53   ` [PATCH libdrm 2/9] amdgpu: Add BO handle to table in amdgpu_bo_create Michel Dänzer
2019-06-24 16:54   ` [PATCH libdrm 3/9] amdgpu: Rename fd_mutex/list to dev_mutex/list Michel Dänzer
2019-06-24 16:54   ` [PATCH libdrm 8/9] amdgpu: Drop refcount member from struct amdgpu_core_bo/device Michel Dänzer
2019-06-24 16:54   ` [PATCH mesa 9/9] winsys/amdgpu: Use amdgpu_bo_handle_type_kms_user for API KMS handles Michel Dänzer
2019-06-24 17:31 ` [PATCH libdrm 0/9] amdgpu: Christian König
     [not found]   ` <b48aae10-c1db-b76b-ddde-9c0a47028633-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2019-06-25  8:02     ` Michel Dänzer
2019-06-25  9:44       ` Koenig, Christian
     [not found]         ` <78d5a7c1-8534-7917-58bc-1827dff106c8-5C7GfCeVMHo@public.gmane.org>
2019-06-25 10:07           ` Michel Dänzer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190624165406.13682-5-michel@daenzer.net \
    --to=michel@daenzer.net \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=emil.l.velikov@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.