winsys/amdgpu: Only re-export KMS handles for different DRM FDs
authorMichel Dänzer <mdaenzer@redhat.com>
Mon, 23 Dec 2019 17:51:57 +0000 (18:51 +0100)
committerMichel Dänzer <michel@daenzer.net>
Thu, 23 Jan 2020 16:39:34 +0000 (17:39 +0100)
When the amdgpu_screen_winsys uses the same FD as the amdgpu_winsys
(which is always the case for the first amdgpu_screen_winsys), we can
just use bo->u.real.kms_handle.

v2:
* Also only create the kms_handles hash table if the
  amdgpu_screen_winsys fd is different from the amdgpu_winsys one.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3202>

src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c
src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h

index 5f44b02d3513a0068f2fa3c916aa05b2b7cb368b..e6a5a7773e0798139124981a8463a49715c8caa6 100644 (file)
@@ -184,8 +184,10 @@ void amdgpu_bo_destroy(struct pb_buffer *_buf)
    }
 
    simple_mtx_lock(&ws->sws_list_lock);
-   for (sws_iter = ws->sws_list; sws_iter; sws_iter = sws_iter->next)
-      _mesa_hash_table_remove_key(sws_iter->kms_handles, bo);
+   for (sws_iter = ws->sws_list; sws_iter; sws_iter = sws_iter->next) {
+      if (sws_iter->kms_handles)
+         _mesa_hash_table_remove_key(sws_iter->kms_handles, bo);
+   }
    simple_mtx_unlock(&ws->sws_list_lock);
 
    simple_mtx_lock(&ws->bo_export_table_lock);
@@ -1551,6 +1553,15 @@ static bool amdgpu_bo_get_handle(struct radeon_winsys *rws,
       type = amdgpu_bo_handle_type_gem_flink_name;
       break;
    case WINSYS_HANDLE_TYPE_KMS:
+      if (sws->fd == ws->fd) {
+         whandle->handle = bo->u.real.kms_handle;
+
+         if (bo->is_shared)
+            return true;
+
+         goto hash_table_set;
+      }
+
       simple_mtx_lock(&ws->sws_list_lock);
       entry = _mesa_hash_table_search(sws->kms_handles, bo);
       simple_mtx_unlock(&ws->sws_list_lock);
@@ -1586,6 +1597,7 @@ static bool amdgpu_bo_get_handle(struct radeon_winsys *rws,
       simple_mtx_unlock(&ws->sws_list_lock);
    }
 
+ hash_table_set:
    simple_mtx_lock(&ws->bo_export_table_lock);
    util_hash_table_set(ws->bo_export_table, bo->bo, bo);
    simple_mtx_unlock(&ws->bo_export_table_lock);
index 7bc5fed02f671885e914167e3d8dfdcd6b687468..000abd00a145256a4c88f628beb3696436785240 100644 (file)
@@ -188,7 +188,11 @@ static void amdgpu_winsys_destroy(struct radeon_winsys *rws)
       simple_mtx_unlock(&ws->sws_list_lock);
    }
 
-   _mesa_hash_table_destroy(sws->kms_handles, NULL);
+   if (sws->kms_handles) {
+      assert(!destroy);
+      _mesa_hash_table_destroy(sws->kms_handles, NULL);
+   }
+
    close(sws->fd);
    FREE(rws);
 }
@@ -336,11 +340,6 @@ amdgpu_winsys_create(int fd, const struct pipe_screen_config *config,
 
    ws->fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
 
-   ws->kms_handles = _mesa_hash_table_create(NULL, kms_handle_hash,
-                                             kms_handle_equals);
-   if (!ws->kms_handles)
-      goto fail;
-
    /* Look up the winsys from the dev table. */
    simple_mtx_lock(&dev_tab_mutex);
    if (!dev_tab)
@@ -348,7 +347,7 @@ amdgpu_winsys_create(int fd, const struct pipe_screen_config *config,
 
    /* Initialize the amdgpu device. This should always return the same pointer
     * for the same fd. */
-   r = amdgpu_device_initialize(fd, &drm_major, &drm_minor, &dev);
+   r = amdgpu_device_initialize(ws->fd, &drm_major, &drm_minor, &dev);
    if (r) {
       fprintf(stderr, "amdgpu: amdgpu_device_initialize failed.\n");
       goto fail;
@@ -357,13 +356,18 @@ amdgpu_winsys_create(int fd, const struct pipe_screen_config *config,
    /* Lookup a winsys if we have already created one for this device. */
    aws = util_hash_table_get(dev_tab, dev);
    if (aws) {
-      pipe_reference(NULL, &aws->reference);
-
       /* Release the device handle, because we don't need it anymore.
        * This function is returning an existing winsys instance, which
        * has its own device handle.
        */
       amdgpu_device_deinitialize(dev);
+
+      ws->kms_handles = _mesa_hash_table_create(NULL, kms_handle_hash,
+                                                kms_handle_equals);
+      if (!ws->kms_handles)
+         goto fail;
+
+      pipe_reference(NULL, &aws->reference);
    } else {
       /* Create a new winsys. */
       aws = CALLOC_STRUCT(amdgpu_winsys);
@@ -371,6 +375,7 @@ amdgpu_winsys_create(int fd, const struct pipe_screen_config *config,
          goto fail;
 
       aws->dev = dev;
+      aws->fd = ws->fd;
       aws->info.drm_major = drm_major;
       aws->info.drm_minor = drm_minor;
 
index 147e4b23b9b3f538d44ba3133a5125ce535a7877..c2edf4f46dc2df59ab799cd5fd01949ed3521217 100644 (file)
@@ -42,6 +42,10 @@ struct amdgpu_cs;
 
 struct amdgpu_winsys {
    struct pipe_reference reference;
+
+   /* File descriptor which was passed to amdgpu_device_initialize */
+   int fd;
+
    struct pb_cache bo_cache;
 
    /* Each slab buffer can only contain suballocations of equal sizes, so we