From patchwork Mon Jun 24 16:54:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Michel_D=C3=A4nzer?= X-Patchwork-Id: 11013801 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8433A76 for ; Mon, 24 Jun 2019 16:54:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 71B3B28AA7 for ; Mon, 24 Jun 2019 16:54:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6573C28BD0; Mon, 24 Jun 2019 16:54:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id F3FF628BC9 for ; Mon, 24 Jun 2019 16:54:17 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6D08589CE0; Mon, 24 Jun 2019 16:54:10 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from netline-mail3.netline.ch (mail.netline.ch [148.251.143.178]) by gabe.freedesktop.org (Postfix) with ESMTP id 5276B89C88; Mon, 24 Jun 2019 16:54:09 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by netline-mail3.netline.ch (Postfix) with ESMTP id A93042AA128; Mon, 24 Jun 2019 18:54:08 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at netline-mail3.netline.ch Received: from netline-mail3.netline.ch ([127.0.0.1]) by localhost (netline-mail3.netline.ch [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 5BO_z1AyrPPl; Mon, 24 Jun 2019 18:54:08 +0200 (CEST) Received: from thor (116.245.63.188.dynamic.wline.res.cust.swisscom.ch [188.63.245.116]) by netline-mail3.netline.ch (Postfix) with ESMTPSA id 427E22A6046; Mon, 24 Jun 2019 18:54:07 +0200 (CEST) Received: from daenzer by thor with local (Exim 4.92) (envelope-from ) id 1hfSEI-0003Zk-Nm; Mon, 24 Jun 2019 18:54:06 +0200 From: =?utf-8?q?Michel_D=C3=A4nzer?= To: amd-gfx@lists.freedesktop.org Subject: [PATCH libdrm 6/9] amdgpu: Re-use an existing amdgpu_device when possible Date: Mon, 24 Jun 2019 18:54:03 +0200 Message-Id: <20190624165406.13682-7-michel@daenzer.net> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190624165406.13682-1-michel@daenzer.net> References: <20190624165406.13682-1-michel@daenzer.net> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Emil Velikov , dri-devel@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Michel Dänzer It's possible if amdgpu_device's user_fd references the same file description as the fd passed to amdgpu_device_initialize. Signed-off-by: Michel Dänzer --- amdgpu/amdgpu_device.c | 76 +++++++++++++++++++++++++++++----------- amdgpu/amdgpu_internal.h | 3 +- 2 files changed, 58 insertions(+), 21 deletions(-) diff --git a/amdgpu/amdgpu_device.c b/amdgpu/amdgpu_device.c index abf5f942..8d9a85c2 100644 --- a/amdgpu/amdgpu_device.c +++ b/amdgpu/amdgpu_device.c @@ -28,6 +28,11 @@ * */ +#ifdef __linux__ +#include +#include +#endif + #include #include #include @@ -44,7 +49,7 @@ #define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x))) static pthread_mutex_t dev_mutex = PTHREAD_MUTEX_INITIALIZER; -static struct amdgpu_core_device *dev_list; +static amdgpu_device_handle dev_list; static int fd_compare(int fd1, int fd2) { @@ -67,12 +72,6 @@ static int fd_compare(int fd1, int fd2) static void amdgpu_device_free(struct amdgpu_core_device *dev) { - struct amdgpu_core_device **node = &dev_list; - - while (*node != dev && (*node)->next) - node = &(*node)->next; - *node = (*node)->next; - close(dev->fd); amdgpu_vamgr_deinit(&dev->vamgr_32); @@ -86,20 +85,35 @@ static void amdgpu_device_free(struct amdgpu_core_device *dev) free(dev); } +static bool same_file_description(int fd1, int fd2) +{ +#ifdef __linux__ + pid_t pid = getpid(); + + return syscall(SYS_kcmp, pid, pid, KCMP_FILE, fd1, fd2) == 0; +#endif + + /* NOTE: This is never true at this point, since we always duplicate the + * fd passed to amdgpu_device_initialize + */ + return fd1 == fd2; +} + static int amdgpu_device_init(amdgpu_device_handle user_dev) { + struct amdgpu_device *dev_iter; struct amdgpu_core_device *dev; drmVersionPtr version; uint64_t start, max; int r; - for (dev = dev_list; dev; dev = dev->next) - if (fd_compare(dev->fd, user_dev->user_fd) == 0) + for (dev_iter = dev_list; dev_iter; dev_iter = dev_iter->next) + if (fd_compare(dev_iter->core->fd, user_dev->user_fd) == 0) break; - if (dev) { - atomic_inc(&dev->refcount); - user_dev->core = dev; + if (dev_iter) { + atomic_inc(&dev_iter->core->refcount); + user_dev->core = dev_iter->core; return 0; } @@ -115,9 +129,6 @@ static int amdgpu_device_init(amdgpu_device_handle user_dev) dev->fd = user_dev->user_fd; user_dev->core = dev; - dev->next = dev_list; - dev_list = dev; - version = drmGetVersion(dev->fd); if (version->version_major != 3) { fprintf(stderr, "%s: DRM version is %d.%d.%d but this driver is " @@ -184,6 +195,17 @@ drm_public int amdgpu_device_initialize(int fd, *device_handle = NULL; + pthread_mutex_lock(&dev_mutex); + + for (user_dev = dev_list; user_dev; user_dev = user_dev->next) { + if (same_file_description(user_dev->user_fd, fd)) { + atomic_inc(&user_dev->refcount); + goto out; + } + } + + pthread_mutex_unlock(&dev_mutex); + user_dev = calloc(1, sizeof(struct amdgpu_device)); if (!user_dev) { fprintf(stderr, "%s: calloc failed\n", __func__); @@ -211,6 +233,11 @@ drm_public int amdgpu_device_initialize(int fd, goto cleanup; } + atomic_set(&user_dev->refcount, 1); + user_dev->next = dev_list; + dev_list = user_dev; + +out: *major_version = user_dev->core->major_version; *minor_version = user_dev->core->minor_version; *device_handle = user_dev; @@ -234,14 +261,23 @@ drm_public int amdgpu_device_deinitialize(amdgpu_device_handle user_dev) pthread_mutex_lock(&dev_mutex); - if (user_dev->user_fd != dev->fd) - close(user_dev->user_fd); + if (update_references(&user_dev->refcount, NULL)) { + struct amdgpu_device **node = &dev_list; - if (update_references(&dev->refcount, NULL)) - amdgpu_device_free(dev); + while (*node != user_dev && (*node)->next) + node = &(*node)->next; + *node = (*node)->next; + + if (user_dev->user_fd != dev->fd) + close(user_dev->user_fd); + + if (update_references(&dev->refcount, NULL)) + amdgpu_device_free(dev); + + free(user_dev); + } pthread_mutex_unlock(&dev_mutex); - free(user_dev); return 0; } diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h index a08a4ae8..686d50ec 100644 --- a/amdgpu/amdgpu_internal.h +++ b/amdgpu/amdgpu_internal.h @@ -70,7 +70,6 @@ struct amdgpu_core_device { 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,8 +90,10 @@ struct amdgpu_core_device { }; struct amdgpu_device { + atomic_t refcount; int user_fd; struct amdgpu_core_device *core; + struct amdgpu_device *next; }; struct amdgpu_core_bo {