From patchwork Tue Mar 18 15:54: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: 14021194 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 893DCC28B28 for ; Tue, 18 Mar 2025 15:54:37 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2DDEE10E21A; Tue, 18 Mar 2025 15:54:34 +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="ZnKFGJTu"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id B2FC910E21A for ; Tue, 18 Mar 2025 15:54: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:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: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=SFEv54O13ZTMq7bjwa4CK3pUwWb/MgUhBdTmj4LntBs=; b=ZnKFGJTuOADFo0GlbxRPCOf18f 3W4zvfyddA9fhyVwjiEGHHkFsnqpFILXnUaXLfdQkzlAHXwSmWmLYObRnSmN3EnxvYmpLUF2cXB2f W+JrmHhmgnIpuS48iRuufB1t8KUIUkaIXa5rSzGyFKi32bfq+M6M88BWQL7J+SBsPH4dfhRK21DGF k5dZHmcEYx6KPCCYOjqVWlBJLZc/5jmN4Jz/lvMJUUJiWATib5jfx7k7MRaG6MJZlkuZ7EKKwseoh rbfa0LG+QGtdP+Ogcy/OPjuevKp5sy14VWkYEze5aHGitPlBF/RzzfZ59o/QwloOlgb9tmMCRG7Zh pb/3FqLA==; 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 1tuZGs-002ngU-Ut; Tue, 18 Mar 2025 16:54:27 +0100 From: Tvrtko Ursulin To: dri-devel@lists.freedesktop.org Cc: kernel-dev@igalia.com, Tvrtko Ursulin Subject: [PATCH 1/7] drm/syncobj: Remove unhelpful helper Date: Tue, 18 Mar 2025 15:54:17 +0000 Message-ID: <20250318155424.78552-2-tvrtko.ursulin@igalia.com> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250318155424.78552-1-tvrtko.ursulin@igalia.com> References: <20250318155424.78552-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 --- drivers/gpu/drm/drm_syncobj.c | 98 ++++++++++++++++------------------- 1 file changed, 44 insertions(+), 54 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 4f2ab8a7b50f..d0d60c331df8 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,37 @@ 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_syncobj_array_wait_timeout(syncobjs, + NULL, + count, + args->flags, + drm_timeout_abs_to_jiffies(args->timeout_nsec), + &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 +1339,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 +1358,37 @@ 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_syncobj_array_wait_timeout(syncobjs, + u64_to_user_ptr(args->points), + count, + args->flags, + drm_timeout_abs_to_jiffies(args->timeout_nsec), + &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 Tue Mar 18 15:54: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: 14021192 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 744A2C282EC for ; Tue, 18 Mar 2025 15:54:34 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id AC86310E1D4; Tue, 18 Mar 2025 15:54:33 +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="sn8lzhL2"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id B818A10E21D for ; Tue, 18 Mar 2025 15:54: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:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: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=j3nZ7h00rA3Is6Jdmo07unsKphre7EfJ5IHnBSVmFxA=; b=sn8lzhL2gZZsoK6xjdJjyeYAlc GEb3pSFuZ5wVyiMYLoj/ICgDZJ/MeJpjLnFxl3RpK08Twt1y26/MGKK+kVm5dehtEy3WkX7D63Noz 7uMY0NNnWk/VmjwJlOc2IwhmR8kZu1PV8OYS/VJ/5n2fotOILpxu8T372i2Juz0fIxnJvbRpyRJJ3 ZNKdSJ95LkCIJkaUN0tS9Um81jrpkBjzijVrVzrtHQZfccYeh5mBOWfviPf2qwM1/j/2lqYDm4U8M lVU624humnOZhuO3ZVrLA1SZDcnjw8LM10Z21YCdfGcUFiTih70ULpa/EsXs9IjbaAbSsRQCJqope FysWkmKA==; 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 1tuZGt-002ngb-Lv; Tue, 18 Mar 2025 16:54:27 +0100 From: Tvrtko Ursulin To: dri-devel@lists.freedesktop.org Cc: kernel-dev@igalia.com, Tvrtko Ursulin Subject: [PATCH 2/7] drm/syncobj: Do not allocate an array to store zeros when waiting Date: Tue, 18 Mar 2025 15:54:18 +0000 Message-ID: <20250318155424.78552-3-tvrtko.ursulin@igalia.com> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250318155424.78552-1-tvrtko.ursulin@igalia.com> References: <20250318155424.78552-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 d0d60c331df8..fd5ba6c89666 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 Tue Mar 18 15:54:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 14021198 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 C5602C282EC for ; Tue, 18 Mar 2025 15:54:48 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 345C510E4AB; Tue, 18 Mar 2025 15:54:48 +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="GptJIt4P"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1E74C10E223 for ; Tue, 18 Mar 2025 15:54: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:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: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=PAt9yeccigKpqHuLr9PM6lHeWkKthPLmxUbcJcP1XTI=; b=GptJIt4Ps1oCVwATW1LfKM0jl3 NF9w/NgzJlqyElmeAPKaV8rGUp2jLrZDpRs4xiRyEfG74L9bxQUcXyM3QBfBLNCLJPaNJ4BRu5Zue nGVa4MJkMzsgkUJpZZEFC6QgBAn1CNi9GSqWl2xplRv8r6zAYQXEu4FOzmDte0nxns9izUDICqIiw KkSJDlYGQz3f63YrjzRIbuvVF6W+KZNQGonOsxIWZVmvwN0swHhJr/Ad6GK8ZLjUoFlsPzNUidwbb QipDLJzzerjarILAfy88xsARFr0IXcrT5jOlvyfY2TyvmTY3Dwpo+Va4hL2ao+yIBtADmVoiTCN+1 KQWsSIJA==; 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 1tuZGu-002ngf-Cw; Tue, 18 Mar 2025 16:54:28 +0100 From: Tvrtko Ursulin To: dri-devel@lists.freedesktop.org Cc: kernel-dev@igalia.com, Tvrtko Ursulin Subject: [PATCH 3/7] drm/syncobj: Avoid one temporary allocation in drm_syncobj_array_find Date: Tue, 18 Mar 2025 15:54:19 +0000 Message-ID: <20250318155424.78552-4-tvrtko.ursulin@igalia.com> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250318155424.78552-1-tvrtko.ursulin@igalia.com> References: <20250318155424.78552-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 --- drivers/gpu/drm/drm_syncobj.c | 44 +++++++++++++++++------------------ 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index fd5ba6c89666..cdda2df06bec 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -1213,48 +1213,46 @@ 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++) { + u64 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; + syncobjs[i] = NULL; + 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; err_put_syncobjs: - while (i-- > 0) - drm_syncobj_put(syncobjs[i]); + while (i > 0) { + if (syncobjs[i]) + drm_syncobj_put(syncobjs[i]); + i--; + } kfree(syncobjs); -err_free_handles: - kfree(handles); return ret; } From patchwork Tue Mar 18 15:54: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: 14021199 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 4C01AC28B2F for ; Tue, 18 Mar 2025 15:54:49 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9320310E4AD; Tue, 18 Mar 2025 15:54:48 +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="LF+5z2GG"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id C50EA10E227 for ; Tue, 18 Mar 2025 15:54: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:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: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=Du89kFAzAGKSeETEZWdUbbwxtkK2iO2p2z8eTkLyl4k=; b=LF+5z2GGBYI2S/f+Lw17yhX5WI upV/jkLNYCQS+dZIyWgtdSsrDo7QgAtPTR3QafdCDDRi/XtQXUop/CBW4LDUL9vnurte6uTjuz2Q4 w0NmxetTg32RX7e0uBkJ2f0+pCx+skX9h1Cyz8qc44Ucm9SlM9xcfE82503O2Cpe+lbr5WtATW+t/ fL+1hHGJjgtBQj9LDv6PUiP4o/AREQApmRHlsv426J5IF75U/9BPsXWXNaOLR4jB4GfhVdJ6F9Jhk w4ICntMoLBKgXckroipIse2TuXPEVwg2ECjNwI8+OJvmrE2q+dYRIuD1XpmjKN2ArmDcbTy99ZMKA 9+LFbYiQ==; 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 1tuZGv-002ngl-3n; Tue, 18 Mar 2025 16:54:29 +0100 From: Tvrtko Ursulin To: dri-devel@lists.freedesktop.org Cc: kernel-dev@igalia.com, Tvrtko Ursulin Subject: [PATCH 4/7] drm/syncobj: Use put_user in drm_syncobj_query_ioctl Date: Tue, 18 Mar 2025 15:54:20 +0000 Message-ID: <20250318155424.78552-5-tvrtko.ursulin@igalia.com> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250318155424.78552-1-tvrtko.ursulin@igalia.com> References: <20250318155424.78552-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 cdda2df06bec..74d1dc0d1f8b 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -1643,6 +1643,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, @@ -1684,10 +1687,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 Tue Mar 18 15:54:21 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 14021193 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 494FAC28B2F for ; Tue, 18 Mar 2025 15:54:39 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7591810E21D; Tue, 18 Mar 2025 15:54:34 +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="gEq6rmNE"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8472610E4AB for ; Tue, 18 Mar 2025 15:54: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:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: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=22c/VkFM9nfTdGKjjNkX+AayMdwXYVCgSlW96ygKRx8=; b=gEq6rmNElMRltUj8jOZantX09C gbiHx7Svzw9dqIQJyFeW61QsttqrhDpMp4sm0gemtvZ+lZeXAgryHmDjL7Xoxmq4YFJyC2JVAgBDr A3tFEMgsADi+T5M/g8p9FCpiFM5IDKaIdyyzqr57xTF3xPS4j8vNkLv9Gn3VKgRKOeN6OJLTTHcQl CfwIhuVhqHTZEjZEYKrq1jWFZafZmcu1hA9sNOgwt1DJ7Cz2X9eB8UXsuUJ8UUu8BPPNj7S/1kFb/ DjTjRquZ3TEZXpzv18z5rpCOneUI8WqtQVFYdjnZ/IPZtL/kTdQiosj73dJ8CmGVMjittqLP82XGT HaE2qmUA==; 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 1tuZGv-002ngq-Qb; Tue, 18 Mar 2025 16:54:29 +0100 From: Tvrtko Ursulin To: dri-devel@lists.freedesktop.org Cc: kernel-dev@igalia.com, Tvrtko Ursulin Subject: [PATCH 5/7] drm/syncobj: Avoid temporary allocation in drm_syncobj_timeline_signal_ioctl Date: Tue, 18 Mar 2025 15:54:21 +0000 Message-ID: <20250318155424.78552-6-tvrtko.ursulin@igalia.com> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250318155424.78552-1-tvrtko.ursulin@igalia.com> References: <20250318155424.78552-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 74d1dc0d1f8b..b4563c696056 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -1557,10 +1557,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)) @@ -1572,33 +1572,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++) @@ -1608,19 +1597,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 Tue Mar 18 15:54:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 14021196 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 9BA72C35FF3 for ; Tue, 18 Mar 2025 15:54:40 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7BA5510E223; Tue, 18 Mar 2025 15:54:34 +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="Gydv7ZcT"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id 42B0910E4AD for ; Tue, 18 Mar 2025 15:54:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: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=MPw4W1oTiy8uVtYhgs/Ie0mJvTnS8UuHz9AHoRA/Ea0=; b=Gydv7ZcTeb+mmy9IrDr5NXLfFY m7/nUSTQ6Rm2EanuKtnrZFJVa+lwzudP1fDOC5+us5bk4h1KbCWmn9zi5CngKINfhh9k9BQ6C5bYO 9Sv23i2hLECGCr7sNxosRgyePpA1ahrNfSRXYC4OoOetE2wbZYbIac3kwXqu6RFl3szFSn5HfZtkQ 2EDuRRfMDTvFiexSJ9Mk/vu242ZRF0UHws+O9/AfY/HGx6Id13erokzoQzcoFrmGEc4bHXx21xlkI Bo1yrhEegu+DcoTp6EVxixcQYVO4yA4Y0SYxKEjlJpLSrSXn/PPBLvXujsQgGtFMXWBhrVefFh7wT 28KRwkHQ==; 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 1tuZGw-002ngw-HZ; Tue, 18 Mar 2025 16:54:30 +0100 From: Tvrtko Ursulin To: dri-devel@lists.freedesktop.org Cc: kernel-dev@igalia.com, Tvrtko Ursulin Subject: [PATCH 6/7] drm/syncobj: Add a fast path to drm_syncobj_array_wait_timeout Date: Tue, 18 Mar 2025 15:54:22 +0000 Message-ID: <20250318155424.78552-7-tvrtko.ursulin@igalia.com> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250318155424.78552-1-tvrtko.ursulin@igalia.com> References: <20250318155424.78552-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 --- drivers/gpu/drm/drm_syncobj.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index b4563c696056..94932b89298f 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -1035,6 +1035,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[4]; struct syncobj_wait_entry *entries; uint32_t signaled_count, i; struct dma_fence *fence; @@ -1049,9 +1050,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 +1180,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 Tue Mar 18 15:54:23 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 14021197 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 C6449C282EC for ; Tue, 18 Mar 2025 15:54:41 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7C16310E227; Tue, 18 Mar 2025 15:54:34 +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="RMmVobfq"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id EFD9610E4AE for ; Tue, 18 Mar 2025 15:54:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: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=n4nCKw6f1PS7jJvVyZUIfu1pxucK32vlNnMsPlOgGhQ=; b=RMmVobfqowPRKv1L8vWEiPJFfj opc4CiKk5X6rRGLrdXqD3iDvRHcpc9TH2koXtcfZvXgpuX07EuQ9+vzHQpmO22lwMh5iawEBLkL/h G88IFGIL0rDQ9T7/z1DXY/vhdKkpFWfnpHjArFa4xkCb4JVLc5kOkzf6IJPGdU/wX6+qMYEqmBFli 2wO7O2/Pr66LEsoHHyTTEThq462RnrHJOYlsK+V6LPZSdVeVGIb0J0ddqjFfE60H/WVHJJl6AvQoM 0byL0DKXqH8wWY6UoJyS69QbNxwg29UCUEIXGKT6Pat7L0+pbLB5JC4+wiv/bdDnd6ke+g5eXFubK JgID8bNg==; 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 1tuZGx-002nh1-8G; Tue, 18 Mar 2025 16:54:31 +0100 From: Tvrtko Ursulin To: dri-devel@lists.freedesktop.org Cc: kernel-dev@igalia.com, Tvrtko Ursulin Subject: [PATCH 7/7] drm/syncobj: Add a fast path to drm_syncobj_array_find Date: Tue, 18 Mar 2025 15:54:23 +0000 Message-ID: <20250318155424.78552-8-tvrtko.ursulin@igalia.com> X-Mailer: git-send-email 2.48.0 In-Reply-To: <20250318155424.78552-1-tvrtko.ursulin@igalia.com> References: <20250318155424.78552-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 --- drivers/gpu/drm/drm_syncobj.c | 53 +++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 94932b89298f..233bdef53c87 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -1223,6 +1223,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; @@ -1232,9 +1234,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++) { u64 handle; @@ -1260,25 +1266,31 @@ static int drm_syncobj_array_find(struct drm_file *file_private, drm_syncobj_put(syncobjs[i]); 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, + struct drm_syncobj **stack_syncobjs) { uint32_t i; for (i = 0; i < count; i++) drm_syncobj_put(syncobjs[i]); - kfree(syncobjs); + + if (syncobjs != stack_syncobjs) + kfree(syncobjs); } int drm_syncobj_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private) { + struct drm_syncobj *stack_syncobjs[4]; struct drm_syncobj_wait *args = data; ktime_t deadline, *pdeadline = NULL; u32 count = args->count_handles; @@ -1304,6 +1316,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; @@ -1321,7 +1335,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, stack_syncobjs); if (timeout < 0) return timeout; @@ -1336,6 +1350,7 @@ drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private) { struct drm_syncobj_timeline_wait *args = data; + struct drm_syncobj *stack_syncobjs[4]; ktime_t deadline, *pdeadline = NULL; u32 count = args->count_handles; struct drm_syncobj **syncobjs; @@ -1361,6 +1376,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; @@ -1378,7 +1395,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, stack_syncobjs); if (timeout < 0) return timeout; @@ -1496,6 +1513,7 @@ drm_syncobj_reset_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private) { struct drm_syncobj_array *args = data; + struct drm_syncobj *stack_syncobjs[4]; struct drm_syncobj **syncobjs; uint32_t i; int ret; @@ -1512,6 +1530,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; @@ -1519,7 +1539,7 @@ 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, stack_syncobjs); return 0; } @@ -1529,6 +1549,7 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private) { struct drm_syncobj_array *args = data; + struct drm_syncobj *stack_syncobjs[4]; struct drm_syncobj **syncobjs; uint32_t i; int ret; @@ -1545,6 +1566,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; @@ -1555,7 +1578,7 @@ 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, stack_syncobjs); return ret; } @@ -1567,6 +1590,7 @@ drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data, 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 *stack_syncobjs[4]; struct drm_syncobj **syncobjs; struct dma_fence_chain **chains; int ret; @@ -1586,6 +1610,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; @@ -1622,7 +1648,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, stack_syncobjs); return ret; } @@ -1631,6 +1657,7 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file_private) { struct drm_syncobj_timeline_array *args = data; + struct drm_syncobj *stack_syncobjs[4]; struct drm_syncobj **syncobjs; uint64_t __user *points = u64_to_user_ptr(args->points); uint32_t i; @@ -1651,6 +1678,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; @@ -1694,7 +1723,7 @@ 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, stack_syncobjs); return ret; }