From patchwork Fri Mar 28 16:46:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 14032241 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id ADFE7C28B20 for ; Fri, 28 Mar 2025 16:46:31 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1E26310EA72; Fri, 28 Mar 2025 16:46:31 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=igalia.com header.i=@igalia.com header.b="cB1JHnhi"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id 44DA510EA72 for ; Fri, 28 Mar 2025 16:46:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=XE0xfVllFY/UyE8wLrbE3Lg6mp6kghFd/UtXSiOrZ44=; b=cB1JHnhiCaE1Z5hTLqGr2n98cl y95iargaTjmf/mbRUc5/e5dwUYl/zWxKyjg2Uz0axyQcpTj4ltk+9Ar4m3HBHVWCauQ925lDn3KCC kA2ZVqJO6IL2sDc0aVyOq2hQpBWbQVBSRzdTnXGhaEmT8+8ULcQMjPrUaFDd0GD4MR/G3V1bUGo9I LGMcrUnEmAyuW+zZm94r0BQhJiSPO5sKK5ySRxNz0sVjXJaHUC+Kh5Y1Xm8T9qSnaDNpb84Sx3dSc Es0gLIE6OySgDJ5l7SxeTjPUyTmnHBpY4xPG1j2QBYOc589OoPq3ttpn/Acj0OLbiTYQVi3X0KLAy dTlfzloA==; Received: from [90.241.98.187] (helo=localhost) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1tyCqf-0082Nb-Hz; Fri, 28 Mar 2025 17:46:25 +0100 From: Tvrtko Ursulin To: dri-devel@lists.freedesktop.org Cc: kernel-dev@igalia.com, =?utf-8?q?Ma=C3=ADra_Canal?= , Tvrtko Ursulin Subject: [PATCH v3 1/7] drm/syncobj: Remove unhelpful helper Date: Fri, 28 Mar 2025 16:46:14 +0000 Message-ID: <20250328164621.59150-2-tvrtko.ursulin@igalia.com> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250328164621.59150-1-tvrtko.ursulin@igalia.com> References: <20250328164621.59150-1-tvrtko.ursulin@igalia.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Helper which fails to consolidate the code and instead just forks into two copies of the code based on a boolean parameter is not very helpful or readable. Lets just remove it and proof in the pudding is the net smaller code. Signed-off-by: Tvrtko Ursulin Reviewed-by: Maíra Canal --- v2: * Assign timeout to a local variable. --- drivers/gpu/drm/drm_syncobj.c | 100 ++++++++++++++++------------------ 1 file changed, 46 insertions(+), 54 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 4f2ab8a7b50f..55bb99f1af7e 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -1221,42 +1221,6 @@ signed long drm_timeout_abs_to_jiffies(int64_t timeout_nsec) } EXPORT_SYMBOL(drm_timeout_abs_to_jiffies); -static int drm_syncobj_array_wait(struct drm_device *dev, - struct drm_file *file_private, - struct drm_syncobj_wait *wait, - struct drm_syncobj_timeline_wait *timeline_wait, - struct drm_syncobj **syncobjs, bool timeline, - ktime_t *deadline) -{ - signed long timeout = 0; - uint32_t first = ~0; - - if (!timeline) { - timeout = drm_timeout_abs_to_jiffies(wait->timeout_nsec); - timeout = drm_syncobj_array_wait_timeout(syncobjs, - NULL, - wait->count_handles, - wait->flags, - timeout, &first, - deadline); - if (timeout < 0) - return timeout; - wait->first_signaled = first; - } else { - timeout = drm_timeout_abs_to_jiffies(timeline_wait->timeout_nsec); - timeout = drm_syncobj_array_wait_timeout(syncobjs, - u64_to_user_ptr(timeline_wait->points), - timeline_wait->count_handles, - timeline_wait->flags, - timeout, &first, - deadline); - if (timeout < 0) - return timeout; - timeline_wait->first_signaled = first; - } - return 0; -} - static int drm_syncobj_array_find(struct drm_file *file_private, void __user *user_handles, uint32_t count_handles, @@ -1319,9 +1283,12 @@ drm_syncobj_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private) { struct drm_syncobj_wait *args = data; + ktime_t deadline, *pdeadline = NULL; + u32 count = args->count_handles; struct drm_syncobj **syncobjs; unsigned int possible_flags; - ktime_t t, *tp = NULL; + u32 first = ~0; + long timeout; int ret = 0; if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) @@ -1334,27 +1301,38 @@ drm_syncobj_wait_ioctl(struct drm_device *dev, void *data, if (args->flags & ~possible_flags) return -EINVAL; - if (args->count_handles == 0) + if (count == 0) return 0; ret = drm_syncobj_array_find(file_private, u64_to_user_ptr(args->handles), - args->count_handles, + count, &syncobjs); if (ret < 0) return ret; if (args->flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_DEADLINE) { - t = ns_to_ktime(args->deadline_nsec); - tp = &t; + deadline = ns_to_ktime(args->deadline_nsec); + pdeadline = &deadline; } - ret = drm_syncobj_array_wait(dev, file_private, - args, NULL, syncobjs, false, tp); + timeout = drm_timeout_abs_to_jiffies(args->timeout_nsec); + timeout = drm_syncobj_array_wait_timeout(syncobjs, + NULL, + count, + args->flags, + timeout, + &first, + pdeadline); - drm_syncobj_array_free(syncobjs, args->count_handles); + drm_syncobj_array_free(syncobjs, count); - return ret; + if (timeout < 0) + return timeout; + + args->first_signaled = first; + + return 0; } int @@ -1362,9 +1340,12 @@ drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private) { struct drm_syncobj_timeline_wait *args = data; + ktime_t deadline, *pdeadline = NULL; + u32 count = args->count_handles; struct drm_syncobj **syncobjs; unsigned int possible_flags; - ktime_t t, *tp = NULL; + u32 first = ~0; + long timeout; int ret = 0; if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE)) @@ -1378,27 +1359,38 @@ drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data, if (args->flags & ~possible_flags) return -EINVAL; - if (args->count_handles == 0) + if (count == 0) return 0; ret = drm_syncobj_array_find(file_private, u64_to_user_ptr(args->handles), - args->count_handles, + count, &syncobjs); if (ret < 0) return ret; if (args->flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_DEADLINE) { - t = ns_to_ktime(args->deadline_nsec); - tp = &t; + deadline = ns_to_ktime(args->deadline_nsec); + pdeadline = &deadline; } - ret = drm_syncobj_array_wait(dev, file_private, - NULL, args, syncobjs, true, tp); + timeout = drm_timeout_abs_to_jiffies(args->timeout_nsec); + timeout = drm_syncobj_array_wait_timeout(syncobjs, + u64_to_user_ptr(args->points), + count, + args->flags, + timeout, + &first, + pdeadline); - drm_syncobj_array_free(syncobjs, args->count_handles); + drm_syncobj_array_free(syncobjs, count); - return ret; + if (timeout < 0) + return timeout; + + args->first_signaled = first; + + return 0; } static void syncobj_eventfd_entry_fence_func(struct dma_fence *fence, From patchwork Fri Mar 28 16:46:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 14032243 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7128FC36014 for ; Fri, 28 Mar 2025 16:46:34 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8DE7A10EA7B; Fri, 28 Mar 2025 16:46:31 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=igalia.com header.i=@igalia.com header.b="NWk5KmpZ"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id 0328810EA72 for ; Fri, 28 Mar 2025 16:46:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=mo/zS0AR04mbs1TeRdiXaSHrD+7lvTGjkC/E/q0r3VI=; b=NWk5KmpZj6lEAoOscR6gROAk4j KDnmGMbfORnpqrUJpYAyfizU0HNozEZMlv3QjHDDUfS+jEVK1EpO5c4rX2mpWrzUaJuApPPctZxJY 0Q4EXVBxHfyHafgG2+Oa4zbXRCNpm+gGSdEohZZ5CQX2Qy7jZLXRSOgftfpDzXNbng8FSJGVcwJ0Z SCrctyGulIraaY3HcoH5lXqZzNNODZDfQcKMP5neI/9w1OEL3sEaSsR4ByzRjSmFuxDF9JE8ARMsO BVodk1GWUXviLZzbGjPS6TdwGJUSoDE3ixDyXGiiQS3IS16Ob2bY6y4Hyf2gxrN3Ur31nZICCp+7K TwY1SthQ==; Received: from [90.241.98.187] (helo=localhost) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1tyCqg-0082Nm-9g; Fri, 28 Mar 2025 17:46:26 +0100 From: Tvrtko Ursulin To: dri-devel@lists.freedesktop.org Cc: kernel-dev@igalia.com, =?utf-8?q?Ma=C3=ADra_Canal?= , Tvrtko Ursulin Subject: [PATCH v3 2/7] drm/syncobj: Do not allocate an array to store zeros when waiting Date: Fri, 28 Mar 2025 16:46:15 +0000 Message-ID: <20250328164621.59150-3-tvrtko.ursulin@igalia.com> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250328164621.59150-1-tvrtko.ursulin@igalia.com> References: <20250328164621.59150-1-tvrtko.ursulin@igalia.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" When waiting on syncobjs the current code allocates a temporary array only to fill it up with all zeros. We can avoid that by relying on the allocated entry array already being zero allocated. For the timeline mode we can fetch the timeline point values as we populate the entries array so also do not need this additional temporary allocation. Signed-off-by: Tvrtko Ursulin Reviewed-by: Maíra Canal --- drivers/gpu/drm/drm_syncobj.c | 39 ++++++++++++++--------------------- 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 55bb99f1af7e..28081cf74052 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -1028,7 +1028,7 @@ static void syncobj_wait_syncobj_func(struct drm_syncobj *syncobj, } static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, - void __user *user_points, + u64 __user *user_points, uint32_t count, uint32_t flags, signed long timeout, @@ -1036,9 +1036,8 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, ktime_t *deadline) { struct syncobj_wait_entry *entries; - struct dma_fence *fence; - uint64_t *points; uint32_t signaled_count, i; + struct dma_fence *fence; if (flags & (DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT | DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE)) { @@ -1046,24 +1045,14 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, lockdep_assert_none_held_once(); } - points = kmalloc_array(count, sizeof(*points), GFP_KERNEL); - if (points == NULL) - return -ENOMEM; - - if (!user_points) { - memset(points, 0, count * sizeof(uint64_t)); - - } else if (copy_from_user(points, user_points, - sizeof(uint64_t) * count)) { - timeout = -EFAULT; - goto err_free_points; - } + if (user_points && + !access_ok(user_points, count * sizeof(*user_points))) + return -EFAULT; entries = kcalloc(count, sizeof(*entries), GFP_KERNEL); - if (!entries) { - timeout = -ENOMEM; - goto err_free_points; - } + if (!entries) + return -ENOMEM; + /* Walk the list of sync objects and initialize entries. We do * this up-front so that we can properly return -EINVAL if there is * a syncobj with a missing fence and then never have the chance of @@ -1074,9 +1063,14 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, struct dma_fence *fence; entries[i].task = current; - entries[i].point = points[i]; + if (user_points && + __get_user(entries[i].point, user_points++)) { + timeout = -EFAULT; + goto cleanup_entries; + } fence = drm_syncobj_fence_get(syncobjs[i]); - if (!fence || dma_fence_chain_find_seqno(&fence, points[i])) { + if (!fence || + dma_fence_chain_find_seqno(&fence, entries[i].point)) { dma_fence_put(fence); if (flags & (DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT | DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE)) { @@ -1182,9 +1176,6 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, } kfree(entries); -err_free_points: - kfree(points); - return timeout; } From patchwork Fri Mar 28 16:46:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 14032244 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D4390C28B20 for ; Fri, 28 Mar 2025 16:46:40 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3248C10EA7E; Fri, 28 Mar 2025 16:46:40 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=igalia.com header.i=@igalia.com header.b="QgiEyLQ9"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id B04E110EA72 for ; Fri, 28 Mar 2025 16:46:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=N4+BK+tFpkZ9N23fW6HRH3PSGHpOt2ZW4Td7GIeOI1k=; b=QgiEyLQ975TsFwdDZfeSfNNMs4 UvNa6jwnaQQIHiGpLvOYvvpD/x0KeZuVvaehp7Xcsy345zOY41+58yrGOCeUU2XoIsvag16Yx60Qm qMsF5shVgFq6xfDzAMPyp5UYchN23p/O1R+znuQ5r5q4FN37PMjA72eIIYUzzIHhiubBnjK4wpkfa OdaDkssl8//PkCBurcCfM8dWUxGgRXEsVFrAzKfw4r/FOrQFERssK7b0y6P7UCQtluYZw+tkWQWTx 8YacHRe/5o2vewLxBLjyfnqdN+cAmv9cvJ5KRrVhrBGvvc9ul9x3wPY8U+z8jdrex9WCAfiEWe2Dn O3NaZeTA==; Received: from [90.241.98.187] (helo=localhost) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1tyCqh-0082Nq-1K; Fri, 28 Mar 2025 17:46:27 +0100 From: Tvrtko Ursulin To: dri-devel@lists.freedesktop.org Cc: kernel-dev@igalia.com, =?utf-8?q?Ma=C3=ADra_Canal?= , Tvrtko Ursulin Subject: [PATCH v3 3/7] drm/syncobj: Avoid one temporary allocation in drm_syncobj_array_find Date: Fri, 28 Mar 2025 16:46:16 +0000 Message-ID: <20250328164621.59150-4-tvrtko.ursulin@igalia.com> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250328164621.59150-1-tvrtko.ursulin@igalia.com> References: <20250328164621.59150-1-tvrtko.ursulin@igalia.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Drm_syncobj_array_find() helper is used from many userspace ioctl entry points with the task of looking up userspace handles to internal objects. We can easily avoid one temporary allocation by making it read the handles as it is looking them up. Signed-off-by: Tvrtko Ursulin Reviewed-by: Maíra Canal --- v2: * Fix handle type. * Undo pointless unwind change. --- drivers/gpu/drm/drm_syncobj.c | 36 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 28081cf74052..cd36c888f112 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -1213,39 +1213,35 @@ signed long drm_timeout_abs_to_jiffies(int64_t timeout_nsec) EXPORT_SYMBOL(drm_timeout_abs_to_jiffies); static int drm_syncobj_array_find(struct drm_file *file_private, - void __user *user_handles, - uint32_t count_handles, + u32 __user *handles, + uint32_t count, struct drm_syncobj ***syncobjs_out) { - uint32_t i, *handles; struct drm_syncobj **syncobjs; + uint32_t i; int ret; - handles = kmalloc_array(count_handles, sizeof(*handles), GFP_KERNEL); - if (handles == NULL) + if (!access_ok(handles, count * sizeof(*handles))) + return -EFAULT; + + syncobjs = kmalloc_array(count, sizeof(*syncobjs), GFP_KERNEL); + if (!syncobjs) return -ENOMEM; - if (copy_from_user(handles, user_handles, - sizeof(uint32_t) * count_handles)) { - ret = -EFAULT; - goto err_free_handles; - } + for (i = 0; i < count; i++) { + u32 handle; - syncobjs = kmalloc_array(count_handles, sizeof(*syncobjs), GFP_KERNEL); - if (syncobjs == NULL) { - ret = -ENOMEM; - goto err_free_handles; - } - - for (i = 0; i < count_handles; i++) { - syncobjs[i] = drm_syncobj_find(file_private, handles[i]); + if (__get_user(handle, handles++)) { + ret = -EFAULT; + goto err_put_syncobjs; + } + syncobjs[i] = drm_syncobj_find(file_private, handle); if (!syncobjs[i]) { ret = -ENOENT; goto err_put_syncobjs; } } - kfree(handles); *syncobjs_out = syncobjs; return 0; @@ -1253,8 +1249,6 @@ static int drm_syncobj_array_find(struct drm_file *file_private, while (i-- > 0) drm_syncobj_put(syncobjs[i]); kfree(syncobjs); -err_free_handles: - kfree(handles); return ret; } From patchwork Fri Mar 28 16:46:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 14032242 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1CF29C36013 for ; Fri, 28 Mar 2025 16:46:33 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 67DB910EA75; Fri, 28 Mar 2025 16:46:31 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=igalia.com header.i=@igalia.com header.b="sjSi/SYf"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6DAB410EA72 for ; Fri, 28 Mar 2025 16:46:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=HI/REpNzZw8EFH7D7Dudv6QJr7vF6ziPJAMEZFVkcGw=; b=sjSi/SYfEv7mqPwHApr9jLj+wg 2v4/w6NdH/THKEkh0WbLJ0HFIkDvlrR3Hqn7IMXT44l/QFOxLDDuSCLCBLpfqgAMNmhhMBGdOH/0R paVdG4TerUBOPsMbtx1Qn4wH7jfCcf20OKSDxOKs89DcJDbCkvRk1f8bI0kTu5gpSRdtgOfGo231v uRPezrcJZXQlNyef6+o+RdusvNjFnP6l/57Z0T+3EtjzDqFFuO2G8m8u1QLf9JOc02LIfIsuWaCO7 4cPVQy74taF/TNNzzniCI8nSrC/d8yx05wBTRoQbtjckXYtZZjVwqoooi7JTwxZJ9GuT3zQsahaXs Sh6rraTQ==; Received: from [90.241.98.187] (helo=localhost) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1tyCqh-0082Nw-Oh; Fri, 28 Mar 2025 17:46:27 +0100 From: Tvrtko Ursulin To: dri-devel@lists.freedesktop.org Cc: kernel-dev@igalia.com, =?utf-8?q?Ma=C3=ADra_Canal?= , Tvrtko Ursulin Subject: [PATCH v3 4/7] drm/syncobj: Use put_user in drm_syncobj_query_ioctl Date: Fri, 28 Mar 2025 16:46:17 +0000 Message-ID: <20250328164621.59150-5-tvrtko.ursulin@igalia.com> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250328164621.59150-1-tvrtko.ursulin@igalia.com> References: <20250328164621.59150-1-tvrtko.ursulin@igalia.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Since the query loop is using copy_to_user() to write out a single u64 at a time it feels more natural (and is a tiny bit more compact) to replace it with put_user(). Access_ok() check is added to the input checking for an early bailout in case of a bad buffer passed in. Signed-off-by: Tvrtko Ursulin Reviewed-by: Maíra Canal --- drivers/gpu/drm/drm_syncobj.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index cd36c888f112..9f51bd4dbfc4 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -1641,6 +1641,9 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void *data, if (args->count_handles == 0) return -EINVAL; + if (!access_ok(points, args->count_handles * sizeof(*points))) + return -EFAULT; + ret = drm_syncobj_array_find(file_private, u64_to_user_ptr(args->handles), args->count_handles, @@ -1682,10 +1685,10 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void *data, point = 0; } dma_fence_put(fence); - ret = copy_to_user(&points[i], &point, sizeof(uint64_t)); - ret = ret ? -EFAULT : 0; - if (ret) + if (__put_user(point, points++)) { + ret = -EFAULT; break; + } } drm_syncobj_array_free(syncobjs, args->count_handles); From patchwork Fri Mar 28 16:46:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 14032245 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E3945C36013 for ; Fri, 28 Mar 2025 16:46:40 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 33BE210EA80; Fri, 28 Mar 2025 16:46:40 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=igalia.com header.i=@igalia.com header.b="IFepqtNV"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2A4FA10EA72 for ; Fri, 28 Mar 2025 16:46:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=wZXx3sHF1k1Yx5LlZENkCx+Vktr73zpXlL+YEjRy9Sg=; b=IFepqtNVVFszExV0im+ojVlVsf rNeA9vudDypeVYDy7p2pDmGISTnYAAz8yCqZOWa3Bnx3XWuWdgQhve3Y4FFWXKlsRqOu+7JoLQG33 o3Ty+C1wXXw9RQHwOS1Pr+er5Bkdhd55Jg8TGi6bPzcsOee5nUjv126GvvTUZAPa/BBaLaPGynp1E 5YdZgPJmQVUjsjC3KrfDsXy9oZi647D3WN45BtvJRFcthy3/aGy7uAAbEM5GqC3HJCN0BJFwqtK2t GxY/vxo4GfIrotVbiXlqLdOFRI5GgKtb27U4nub255BTTKSb4tqZl8ADeX7UXsZVm3JqICtzD8KH4 /o5x2eIQ==; Received: from [90.241.98.187] (helo=localhost) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1tyCqi-0082O1-Fd; Fri, 28 Mar 2025 17:46:28 +0100 From: Tvrtko Ursulin To: dri-devel@lists.freedesktop.org Cc: kernel-dev@igalia.com, =?utf-8?q?Ma=C3=ADra_Canal?= , Tvrtko Ursulin Subject: [PATCH v3 5/7] drm/syncobj: Avoid temporary allocation in drm_syncobj_timeline_signal_ioctl Date: Fri, 28 Mar 2025 16:46:18 +0000 Message-ID: <20250328164621.59150-6-tvrtko.ursulin@igalia.com> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250328164621.59150-1-tvrtko.ursulin@igalia.com> References: <20250328164621.59150-1-tvrtko.ursulin@igalia.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" We can avoid one of the two temporary allocations if we read the userspace supplied timeline points as we go along. The only new complication is to unwind unused fence chains on the error path, but even that code was already present in the function. Signed-off-by: Tvrtko Ursulin Reviewed-by: Maíra Canal --- drivers/gpu/drm/drm_syncobj.c | 46 +++++++++++++++-------------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 9f51bd4dbfc4..bf2fbe07add2 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -1555,10 +1555,10 @@ drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private) { struct drm_syncobj_timeline_array *args = data; + uint64_t __user *points = u64_to_user_ptr(args->points); + uint32_t i, j, count = args->count_handles; struct drm_syncobj **syncobjs; struct dma_fence_chain **chains; - uint64_t *points; - uint32_t i, j; int ret; if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE)) @@ -1570,33 +1570,22 @@ drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data, if (args->count_handles == 0) return -EINVAL; + if (!access_ok(points, count * sizeof(*points))) + return -EFAULT; + ret = drm_syncobj_array_find(file_private, u64_to_user_ptr(args->handles), - args->count_handles, + count, &syncobjs); if (ret < 0) return ret; - points = kmalloc_array(args->count_handles, sizeof(*points), - GFP_KERNEL); - if (!points) { - ret = -ENOMEM; - goto out; - } - if (!u64_to_user_ptr(args->points)) { - memset(points, 0, args->count_handles * sizeof(uint64_t)); - } else if (copy_from_user(points, u64_to_user_ptr(args->points), - sizeof(uint64_t) * args->count_handles)) { - ret = -EFAULT; - goto err_points; - } - - chains = kmalloc_array(args->count_handles, sizeof(void *), GFP_KERNEL); + chains = kmalloc_array(count, sizeof(void *), GFP_KERNEL); if (!chains) { ret = -ENOMEM; - goto err_points; + goto out; } - for (i = 0; i < args->count_handles; i++) { + for (i = 0; i < count; i++) { chains[i] = dma_fence_chain_alloc(); if (!chains[i]) { for (j = 0; j < i; j++) @@ -1606,19 +1595,24 @@ drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data, } } - for (i = 0; i < args->count_handles; i++) { + for (i = 0; i < count; i++) { struct dma_fence *fence = dma_fence_get_stub(); + u64 point = 0; - drm_syncobj_add_point(syncobjs[i], chains[i], - fence, points[i]); + if (points && __get_user(point, points++)) { + ret = -EFAULT; + for (j = i; j < count; j++) + dma_fence_chain_free(chains[j]); + goto err_chains; + } + + drm_syncobj_add_point(syncobjs[i], chains[i], fence, point); dma_fence_put(fence); } err_chains: kfree(chains); -err_points: - kfree(points); out: - drm_syncobj_array_free(syncobjs, args->count_handles); + drm_syncobj_array_free(syncobjs, count); return ret; } From patchwork Fri Mar 28 16:46:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 14032247 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id CE1F3C28B20 for ; Fri, 28 Mar 2025 16:46:49 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 43E0910EA84; Fri, 28 Mar 2025 16:46:49 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=igalia.com header.i=@igalia.com header.b="EIzYig1a"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id DC2C110EA72 for ; Fri, 28 Mar 2025 16:46:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=sgu1FnmPGEHmr9bhUSRXubCLO/3C6ejbxS55eGfK6Xg=; b=EIzYig1apG/h3ZNSL0mZQ2m1UW tyl//wglTyO2Paxek320bOb3r5rz57ch9vW4ynknYA6+K+asPEXEuRlr/YOOztzKBCdfcyBlo3Zv3 +3fPsqYMlu0tPBQl9E6IQeq1BF5mXW2FFMCmKx0WDesQv5V63rjG6UuN80nRbipydF5ZbjSYOdV+6 C/s8yjmAeykt/41oEp//IruRsA3gDt3HL2l+GkdtcdFZlULfE68P+/NCrhiDo3LP5aJbf2fnKCEAR JkO+snyi4LH3fKFvXeTLNoQCIoDClG6vtUSKDQEuo+RnUi+jQZgvCVzOs6MuxCmnBBkU7h/na4FzC XQ8qm/Kw==; Received: from [90.241.98.187] (helo=localhost) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1tyCqj-0082O9-76; Fri, 28 Mar 2025 17:46:29 +0100 From: Tvrtko Ursulin To: dri-devel@lists.freedesktop.org Cc: kernel-dev@igalia.com, =?utf-8?q?Ma=C3=ADra_Canal?= , Tvrtko Ursulin Subject: [PATCH v3 6/7] drm/syncobj: Add a fast path to drm_syncobj_array_wait_timeout Date: Fri, 28 Mar 2025 16:46:19 +0000 Message-ID: <20250328164621.59150-7-tvrtko.ursulin@igalia.com> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250328164621.59150-1-tvrtko.ursulin@igalia.com> References: <20250328164621.59150-1-tvrtko.ursulin@igalia.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Running the Cyberpunk 2077 benchmark we can observe that waiting on DRM sycobjs is relatively hot, but the 96% of the calls are for a single object. (~4% for two points, and never more than three points. While a more trivial workload like vkmark under Plasma is even more skewed to single point waits.) Therefore lets add a fast path to bypass the kcalloc/kfree and use a pre- allocated stack array for those cases. Signed-off-by: Tvrtko Ursulin Reviewed-by: Maíra Canal --- v2: * Document rationale for stack array in a comment. v3: * Added DRM_SYNCOBJ_FAST_PATH_ENTRIES to avoid hardcoding fast path array size. --- drivers/gpu/drm/drm_syncobj.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index bf2fbe07add2..34a6dc50ec31 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -236,6 +236,14 @@ static void syncobj_eventfd_entry_func(struct drm_syncobj *syncobj, struct syncobj_eventfd_entry *entry); +/* + * Empirically vast majority of ioctls pass in a single syncobj (96%) and never + * more than three points. Therefore implement a fast path with a small stack + * array to avoid going into the allocator sometimes several times per + * userspace rendered frame. + */ +#define DRM_SYNCOBJ_FAST_PATH_ENTRIES 4 + /** * drm_syncobj_find - lookup and reference a sync object. * @file_private: drm file private pointer @@ -1035,6 +1043,7 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, uint32_t *idx, ktime_t *deadline) { + struct syncobj_wait_entry stack_entries[DRM_SYNCOBJ_FAST_PATH_ENTRIES]; struct syncobj_wait_entry *entries; uint32_t signaled_count, i; struct dma_fence *fence; @@ -1049,9 +1058,14 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, !access_ok(user_points, count * sizeof(*user_points))) return -EFAULT; - entries = kcalloc(count, sizeof(*entries), GFP_KERNEL); - if (!entries) - return -ENOMEM; + if (count > ARRAY_SIZE(stack_entries)) { + entries = kcalloc(count, sizeof(*entries), GFP_KERNEL); + if (!entries) + return -ENOMEM; + } else { + memset(stack_entries, 0, sizeof(stack_entries)); + entries = stack_entries; + } /* Walk the list of sync objects and initialize entries. We do * this up-front so that we can properly return -EINVAL if there is @@ -1174,7 +1188,9 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, &entries[i].fence_cb); dma_fence_put(entries[i].fence); } - kfree(entries); + + if (entries != stack_entries) + kfree(entries); return timeout; } From patchwork Fri Mar 28 16:46:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 14032246 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 05845C36011 for ; Fri, 28 Mar 2025 16:46:42 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9EB9E10EA81; Fri, 28 Mar 2025 16:46:40 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=igalia.com header.i=@igalia.com header.b="Oe3umECI"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id 97FD410EA7E for ; Fri, 28 Mar 2025 16:46:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=oFdYMgXJRSvV+g7KlNdVHdP7XMS6CWyhVK2Jn2Q6M9k=; b=Oe3umECId30VweExAY+jdNSk05 umu3gVCxUjif2ORU79vEygKCtDjiq5dJyZ60Szn5JoSy5r6s5gStvuy/RK10ptm2za2eKaXm8L9pj 1d7Aehna/1km5Fl54krcGHBT044cWV5sissz36N745wGmG1CjIhbqcrpEG0hPyAu2kUOJILbZfPyt r+M/6OBtUYJrXiU18drbMQ371befdhqjr6rLUbI1framG+zWTdI2gvIALHeqf/cT4AcBttKzh0OVh yuro7sCnh4OHL1m408T8MMLD8sK8kTHM3+nFTmbhTZtzwFjr9Ba9mbvLGBh3xNnSwfpz3Q/1m2EtW ZGs8YjYg==; Received: from [90.241.98.187] (helo=localhost) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1tyCqj-0082OG-UF; Fri, 28 Mar 2025 17:46:30 +0100 From: Tvrtko Ursulin To: dri-devel@lists.freedesktop.org Cc: kernel-dev@igalia.com, =?utf-8?q?Ma=C3=ADra_Canal?= , Tvrtko Ursulin Subject: [PATCH v3 7/7] drm/syncobj: Add a fast path to drm_syncobj_array_find Date: Fri, 28 Mar 2025 16:46:20 +0000 Message-ID: <20250328164621.59150-8-tvrtko.ursulin@igalia.com> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250328164621.59150-1-tvrtko.ursulin@igalia.com> References: <20250328164621.59150-1-tvrtko.ursulin@igalia.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Running the Cyberpunk 2077 benchmark we can observe that the lookup helper is relatively hot, but the 97% of the calls are for a single object. (~3% for two points, and never more than three points. While a more trivial workload like vkmark under Plasma is even more skewed to single point lookups.) Therefore lets add a fast path to bypass the kmalloc_array/kfree and use a pre-allocated stack array for those cases. Signed-off-by: Tvrtko Ursulin Reviewed-by: Maíra Canal --- v2: * Added comments describing how the fast path arrays were sized. * Make container freeing criteria clearer by using a boolean. --- drivers/gpu/drm/drm_syncobj.c | 56 +++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 34a6dc50ec31..d5b99bfea9a5 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -1231,6 +1231,8 @@ EXPORT_SYMBOL(drm_timeout_abs_to_jiffies); static int drm_syncobj_array_find(struct drm_file *file_private, u32 __user *handles, uint32_t count, + struct drm_syncobj **stack_syncobjs, + u32 stack_count, struct drm_syncobj ***syncobjs_out) { struct drm_syncobj **syncobjs; @@ -1240,9 +1242,13 @@ static int drm_syncobj_array_find(struct drm_file *file_private, if (!access_ok(handles, count * sizeof(*handles))) return -EFAULT; - syncobjs = kmalloc_array(count, sizeof(*syncobjs), GFP_KERNEL); - if (!syncobjs) - return -ENOMEM; + if (count > stack_count) { + syncobjs = kmalloc_array(count, sizeof(*syncobjs), GFP_KERNEL); + if (!syncobjs) + return -ENOMEM; + } else { + syncobjs = stack_syncobjs; + } for (i = 0; i < count; i++) { u32 handle; @@ -1264,25 +1270,31 @@ static int drm_syncobj_array_find(struct drm_file *file_private, err_put_syncobjs: while (i-- > 0) drm_syncobj_put(syncobjs[i]); - kfree(syncobjs); + + if (syncobjs != stack_syncobjs) + kfree(syncobjs); return ret; } static void drm_syncobj_array_free(struct drm_syncobj **syncobjs, - uint32_t count) + uint32_t count, + bool free_container) { uint32_t i; for (i = 0; i < count; i++) drm_syncobj_put(syncobjs[i]); - kfree(syncobjs); + + if (free_container) + kfree(syncobjs); } int drm_syncobj_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private) { + struct drm_syncobj *stack_syncobjs[DRM_SYNCOBJ_FAST_PATH_ENTRIES]; struct drm_syncobj_wait *args = data; ktime_t deadline, *pdeadline = NULL; u32 count = args->count_handles; @@ -1308,6 +1320,8 @@ drm_syncobj_wait_ioctl(struct drm_device *dev, void *data, ret = drm_syncobj_array_find(file_private, u64_to_user_ptr(args->handles), count, + stack_syncobjs, + ARRAY_SIZE(stack_syncobjs), &syncobjs); if (ret < 0) return ret; @@ -1326,7 +1340,7 @@ drm_syncobj_wait_ioctl(struct drm_device *dev, void *data, &first, pdeadline); - drm_syncobj_array_free(syncobjs, count); + drm_syncobj_array_free(syncobjs, count, syncobjs != stack_syncobjs); if (timeout < 0) return timeout; @@ -1340,6 +1354,7 @@ int drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private) { + struct drm_syncobj *stack_syncobjs[DRM_SYNCOBJ_FAST_PATH_ENTRIES]; struct drm_syncobj_timeline_wait *args = data; ktime_t deadline, *pdeadline = NULL; u32 count = args->count_handles; @@ -1366,6 +1381,8 @@ drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data, ret = drm_syncobj_array_find(file_private, u64_to_user_ptr(args->handles), count, + stack_syncobjs, + ARRAY_SIZE(stack_syncobjs), &syncobjs); if (ret < 0) return ret; @@ -1384,7 +1401,7 @@ drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data, &first, pdeadline); - drm_syncobj_array_free(syncobjs, count); + drm_syncobj_array_free(syncobjs, count, syncobjs != stack_syncobjs); if (timeout < 0) return timeout; @@ -1501,6 +1518,7 @@ int drm_syncobj_reset_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private) { + struct drm_syncobj *stack_syncobjs[DRM_SYNCOBJ_FAST_PATH_ENTRIES]; struct drm_syncobj_array *args = data; struct drm_syncobj **syncobjs; uint32_t i; @@ -1518,6 +1536,8 @@ drm_syncobj_reset_ioctl(struct drm_device *dev, void *data, ret = drm_syncobj_array_find(file_private, u64_to_user_ptr(args->handles), args->count_handles, + stack_syncobjs, + ARRAY_SIZE(stack_syncobjs), &syncobjs); if (ret < 0) return ret; @@ -1525,7 +1545,8 @@ drm_syncobj_reset_ioctl(struct drm_device *dev, void *data, for (i = 0; i < args->count_handles; i++) drm_syncobj_replace_fence(syncobjs[i], NULL); - drm_syncobj_array_free(syncobjs, args->count_handles); + drm_syncobj_array_free(syncobjs, args->count_handles, + syncobjs != stack_syncobjs); return 0; } @@ -1534,6 +1555,7 @@ int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private) { + struct drm_syncobj *stack_syncobjs[DRM_SYNCOBJ_FAST_PATH_ENTRIES]; struct drm_syncobj_array *args = data; struct drm_syncobj **syncobjs; uint32_t i; @@ -1551,6 +1573,8 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, ret = drm_syncobj_array_find(file_private, u64_to_user_ptr(args->handles), args->count_handles, + stack_syncobjs, + ARRAY_SIZE(stack_syncobjs), &syncobjs); if (ret < 0) return ret; @@ -1561,7 +1585,8 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, break; } - drm_syncobj_array_free(syncobjs, args->count_handles); + drm_syncobj_array_free(syncobjs, args->count_handles, + syncobjs != stack_syncobjs); return ret; } @@ -1570,6 +1595,7 @@ int drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private) { + struct drm_syncobj *stack_syncobjs[DRM_SYNCOBJ_FAST_PATH_ENTRIES]; struct drm_syncobj_timeline_array *args = data; uint64_t __user *points = u64_to_user_ptr(args->points); uint32_t i, j, count = args->count_handles; @@ -1592,6 +1618,8 @@ drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data, ret = drm_syncobj_array_find(file_private, u64_to_user_ptr(args->handles), count, + stack_syncobjs, + ARRAY_SIZE(stack_syncobjs), &syncobjs); if (ret < 0) return ret; @@ -1628,7 +1656,7 @@ drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data, err_chains: kfree(chains); out: - drm_syncobj_array_free(syncobjs, count); + drm_syncobj_array_free(syncobjs, count, syncobjs != stack_syncobjs); return ret; } @@ -1636,6 +1664,7 @@ drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data, int drm_syncobj_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private) { + struct drm_syncobj *stack_syncobjs[DRM_SYNCOBJ_FAST_PATH_ENTRIES]; struct drm_syncobj_timeline_array *args = data; struct drm_syncobj **syncobjs; uint64_t __user *points = u64_to_user_ptr(args->points); @@ -1657,6 +1686,8 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void *data, ret = drm_syncobj_array_find(file_private, u64_to_user_ptr(args->handles), args->count_handles, + stack_syncobjs, + ARRAY_SIZE(stack_syncobjs), &syncobjs); if (ret < 0) return ret; @@ -1700,7 +1731,8 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void *data, break; } } - drm_syncobj_array_free(syncobjs, args->count_handles); + drm_syncobj_array_free(syncobjs, args->count_handles, + syncobjs != stack_syncobjs); return ret; }