From patchwork Thu Jan 2 19:44:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 13924903 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 CCD76E77198 for ; Thu, 2 Jan 2025 19:44:33 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 19A2210E79B; Thu, 2 Jan 2025 19:44: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="T0WdLL8N"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id C39C910E797 for ; Thu, 2 Jan 2025 19:44: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=qkbz0Sow42rVOmG/NElmaWLsB5EnHGNy6hywVWsQFy8=; b=T0WdLL8N64S4MDqX8c54dnfFCI jyZWiivbBFSLL8Ur3XlFjuUPCJmlZ55aRZyjwhNRFGmpOiuafRNBpSsG8IyUKSxfU+MQ8OfiVevI+ +yCMYTK1QKAJvxVPeAiROSWoVjebbMX8QElK9Ip4U9hiHs0KH3I1p3uGxWEckvuFLb6QbYyYW6fOQ SqzHO6hAwO8+O4QpIbDuGSGu56nFvRkETso9OXUqBTe0qiyRlSC7thn1Azxin9eRmRY6nBoHTkJJK gntTzxTVddVk3evzrmsEEF391DrceHCKyD7A9Cp2Fl+aAv8q0khFD8OBmNFJkIcGe1bH8s9i443pk S/6I5MYw==; 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 1tTR7O-00Au7I-2Y; Thu, 02 Jan 2025 20:44:30 +0100 From: Tvrtko Ursulin To: dri-devel@lists.freedesktop.org Cc: kernel-dev@igalia.com, Tvrtko Ursulin Subject: [PATCH 1/6] drm/syncobj: Avoid double memset in drm_syncobj_find_fence Date: Thu, 2 Jan 2025 19:44:12 +0000 Message-ID: <20250102194418.70383-2-tursulin@igalia.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250102194418.70383-1-tursulin@igalia.com> References: <20250102194418.70383-1-tursulin@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" From: Tvrtko Ursulin On kernels hardened with CONFIG_INIT_STACK_ALL_ZERO we can avoid the double memset by moving the memory clearing to the declaration block. That way the compiler can notice and only emit it once. Signed-off-by: Tvrtko Ursulin --- drivers/gpu/drm/drm_syncobj.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 4f2ab8a7b50f..49cda394db5b 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -437,8 +437,8 @@ int drm_syncobj_find_fence(struct drm_file *file_private, struct dma_fence **fence) { struct drm_syncobj *syncobj = drm_syncobj_find(file_private, handle); - struct syncobj_wait_entry wait; u64 timeout = nsecs_to_jiffies64(DRM_SYNCOBJ_WAIT_FOR_SUBMIT_TIMEOUT); + struct syncobj_wait_entry wait = { }; int ret; if (flags & ~DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) @@ -479,7 +479,6 @@ int drm_syncobj_find_fence(struct drm_file *file_private, if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT)) goto out; - memset(&wait, 0, sizeof(wait)); wait.task = current; wait.point = point; drm_syncobj_fence_add_wait(syncobj, &wait); From patchwork Thu Jan 2 19:44:13 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 13924905 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 97721E77197 for ; Thu, 2 Jan 2025 19:44:34 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A1DDA10E7A7; Thu, 2 Jan 2025 19:44: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="BnffmGvK"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8163210E797 for ; Thu, 2 Jan 2025 19:44: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=pzvEYUbzLDvhAxykHtioUn9QB6Nn4dV9HGfIOZ/7JHU=; b=BnffmGvKDphjADk9uF8xqRARd6 CzyLRiGFKwH6xdICgiLey52hDRBuHCZy8/6+wawTctyqoDfx9n84OC9H66vAK3/UVueFYkvUkOzbc erG6KVnsBHpA0DrjoJMG4nCjp3sDCxAElml+EwfKB3CK4EnsNkQwFj/JvliCPYBq1HoKFRoM8jg46 a/XtvDMCrR4aofB4RYhu6y0B+pq1EpejPInk4LIMpPYxeHzPXtdfedEYs9e5LDi+75eCJAGHnugkW 6EtCYU2Rf8snSpiYJAEF/+TXT/ERPnYHrxtghLU4dAZk/y22lDRes0egjg3UpWSrxBTgeW/EKE3Cs Tn5xd98g==; 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 1tTR7O-00Au7M-PX; Thu, 02 Jan 2025 20:44:30 +0100 From: Tvrtko Ursulin To: dri-devel@lists.freedesktop.org Cc: kernel-dev@igalia.com, Tvrtko Ursulin Subject: [PATCH 2/6] drm/syncobj: Remove unhelpful helper Date: Thu, 2 Jan 2025 19:44:13 +0000 Message-ID: <20250102194418.70383-3-tursulin@igalia.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250102194418.70383-1-tursulin@igalia.com> References: <20250102194418.70383-1-tursulin@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" From: Tvrtko Ursulin 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 --- 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 49cda394db5b..2fb95d6f6c82 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -1220,42 +1220,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, @@ -1318,9 +1282,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)) @@ -1333,27 +1300,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 @@ -1361,9 +1338,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)) @@ -1377,27 +1357,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 Thu Jan 2 19:44:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 13924904 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 AA24BE77199 for ; Thu, 2 Jan 2025 19:44:35 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id ECCB110E7A3; Thu, 2 Jan 2025 19:44: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="HyUpsJam"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id 370FE10E7A3 for ; Thu, 2 Jan 2025 19:44:33 +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=DNek38Xe+DZwo7rYVvnB4j9dMX078ElTYjvT5/zg5qw=; b=HyUpsJamqqJgrl4PL/eg9Ohwfz uKDlbl35W8+7oH9iEDJHRHZ2mwHWQOQ8lTfy2/cSTHBDlqsK+oTNKYmKQkpXOOOUIXdzxlPVp0z5o +IPAvCHOg6JzIPcng8coHZ+FUJdd84z/ywL8VDNBXp67fA8bS50fATwDEmkJH1aYoVaVdh7nNXV+L Q8EELLiXEAp+cKDNRj8b/di3wTnLp0XeJZ/U+qmWQ/VKg1nFf/TjQjWEbEj17J689m+UB4F2pQnfJ bt9xa54YhMpqSS79oDeU/PcwW6IO+kPe6Ct9CxWySB0GhC1uwXBnnfWZy3CoiAUunAb6ZRW/QT3fj eRxkyncg==; 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 1tTR7P-00Au7S-Gl; Thu, 02 Jan 2025 20:44:31 +0100 From: Tvrtko Ursulin To: dri-devel@lists.freedesktop.org Cc: kernel-dev@igalia.com, Tvrtko Ursulin Subject: [PATCH 3/6] drm/syncobj: Do not allocate an array to store zeros Date: Thu, 2 Jan 2025 19:44:14 +0000 Message-ID: <20250102194418.70383-4-tursulin@igalia.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250102194418.70383-1-tursulin@igalia.com> References: <20250102194418.70383-1-tursulin@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" From: Tvrtko Ursulin 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 fetch the timeline point values as we populate the entries array so also do not need this additional temporary allocation. "vkgears -present-mailbox" average framerate: Before: 21410.1089 After: 21609.7225 With a disclaimer that measuring with vkgears feels a bit variable, nevertheless it did not look like noise. Signed-off-by: Tvrtko Ursulin --- drivers/gpu/drm/drm_syncobj.c | 38 +++++++++++++---------------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 2fb95d6f6c82..059d6be3ff1f 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -1027,7 +1027,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, @@ -1035,9 +1035,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)) { @@ -1045,24 +1044,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 @@ -1073,9 +1062,13 @@ 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)) { @@ -1181,9 +1174,6 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, } kfree(entries); -err_free_points: - kfree(points); - return timeout; } From patchwork Thu Jan 2 19:44:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 13924906 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 6E4EEE77188 for ; Thu, 2 Jan 2025 19:44:36 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2CD4010E7A4; Thu, 2 Jan 2025 19:44:35 +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="Zv1dB0hM"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id ECA4F10E7A4 for ; Thu, 2 Jan 2025 19:44:33 +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=W9ezCfBDIMwyDpBZ9rAsPJNtcuhzF+hYYcR/bTE72V0=; b=Zv1dB0hMlZxwsdTN3YpNQ+dscf QUYsYMggAoJSmMUFBdC66mtrqwc4mb4V8JKyRcpGrWG4L/NQ4S3QQrwcs657hbVTSyjcL2t1Q9mUb gFZzyiCr04DYSVfZsXvCh0NyllZ6Q+/aJpAqG7VDycGUkYqBYuhrLr9dLZEFVGoRuDitG22K5Y7cN LjD94DJcdimo5aOkuPg6LpNKNpXjKWHAW5gwH5ujOtwu8ACepkmMpijAusjKe/1r4pL8ULljWNxIR jXe9FP0MVF0wtMUg8vq7XS9OUfiAjOdwXPpQc4wuKBlIs6bNK89Oz6lPrj6WSrP7kmJ5pVmTjTfM7 JU1PLLng==; 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 1tTR7Q-00Au7Y-7N; Thu, 02 Jan 2025 20:44:32 +0100 From: Tvrtko Ursulin To: dri-devel@lists.freedesktop.org Cc: kernel-dev@igalia.com, Tvrtko Ursulin Subject: [PATCH 4/6] drm/syncobj: Avoid one temporary allocation in drm_syncobj_array_find Date: Thu, 2 Jan 2025 19:44:15 +0000 Message-ID: <20250102194418.70383-5-tursulin@igalia.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250102194418.70383-1-tursulin@igalia.com> References: <20250102194418.70383-1-tursulin@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" From: Tvrtko Ursulin Drm_syncobj_array_find() is used from many 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. "vkgears -present-mailbox" average framerate: Before: 21609.7225 After: 21843.1276 With a disclaimer that measuring with vkgears feels a bit variable, nevertheless it did not look like noise. 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 059d6be3ff1f..5838a7c71a76 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -1211,48 +1211,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 Thu Jan 2 19:44:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 13924907 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 40F53E77198 for ; Thu, 2 Jan 2025 19:44:37 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2F79910E7A8; Thu, 2 Jan 2025 19:44:36 +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="rS+3F9x8"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id A1D6610E7A3 for ; Thu, 2 Jan 2025 19:44:34 +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=FQ5A9W9ZLTBiJtsr+i23qEAdyUGsDQgwgROsAboy+5c=; b=rS+3F9x8yEbY4Qbzlpz97chrBp zXCg6NEmGSq2+V+6Rr4tFsHYmhnp06f8DmZRY9Fj00ECih+CK5kz2OVGldLbbhzw47P7hV7x/Ergd 26xhi7F+zcyk6o1lHS1DROY4m0TCi3EkiL/KAW7QOytvITOQ1Bu1G0w4ufYNXd7N8uxJu5EOSmweD XuzJuHZwDYjWDLLxigMhNOeQChcXGGryzjGHBmXihDOT17fn6GkcEWhQqGN/qrF5Dm5LI3lTBSmk3 1tShSuoJhF5UaVyaGpVPeOA3uAGNiQvlYHIO17GXJ2KxqTq+msn2Qr1BiGynySCjFTnj1ii2gOCcV C5CfuWVw==; 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 1tTR7Q-00Au7d-UK; Thu, 02 Jan 2025 20:44:33 +0100 From: Tvrtko Ursulin To: dri-devel@lists.freedesktop.org Cc: kernel-dev@igalia.com, Tvrtko Ursulin Subject: [PATCH 5/6] drm/syncobj: Use put_user in drm_syncobj_query_ioctl Date: Thu, 2 Jan 2025 19:44:16 +0000 Message-ID: <20250102194418.70383-6-tursulin@igalia.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250102194418.70383-1-tursulin@igalia.com> References: <20250102194418.70383-1-tursulin@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" From: Tvrtko Ursulin 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 --- 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 5838a7c71a76..d8756763f517 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 Thu Jan 2 19:44:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tvrtko Ursulin X-Patchwork-Id: 13924908 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 EE362E7719B for ; Thu, 2 Jan 2025 19:44:37 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6A99210E7A9; Thu, 2 Jan 2025 19:44:36 +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="LO1x9qPk"; dkim-atps=neutral Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5389510E7A6 for ; Thu, 2 Jan 2025 19:44:35 +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=5f6D1vv/u9l+w15jx30lwYkeuaE8ITnALXkWRGgl4q8=; b=LO1x9qPkFdovgvyFUxqG+f46iT 5+ukpRwQlRgmEm0hOOZ2pU0uppB28QjGB+oPie8BhFrwNlEy0WboxbUJdCCcc+R+Zgqax2Nhgb4RT yOfxQbmPC72sob7RL2dF6nVYt0UC1/8GKLjPgOGt/fQs7u6haQkTtPEoHSYn9jyYjrnqSVxluvmhu CpynEQiXbjrOzQtU3jzQF8ighGet9ecAXzhv/W+tcOr4JF15FRXEFGO+XD5rDeUev/7w/+1z0s69w 7qhRQJkI7zYjR6v+WujfLY3OucL/GellYNectnZcwJHG9kmQ7xKGtg/9OZIf/GEzT5EpiXcsm03JQ tg+9TNZw==; 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 1tTR7R-00Au7j-LH; Thu, 02 Jan 2025 20:44:33 +0100 From: Tvrtko Ursulin To: dri-devel@lists.freedesktop.org Cc: kernel-dev@igalia.com, Tvrtko Ursulin Subject: [PATCH 6/6] drm/syncobj: Avoid temporary allocation in drm_syncobj_timeline_signal_ioctl Date: Thu, 2 Jan 2025 19:44:17 +0000 Message-ID: <20250102194418.70383-7-tursulin@igalia.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250102194418.70383-1-tursulin@igalia.com> References: <20250102194418.70383-1-tursulin@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" From: Tvrtko Ursulin 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 --- 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 d8756763f517..b358fd1d3df3 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; }