From nobody Sun Sep 27 02:19:27 2026 Received: from DM5PR21CU001.outbound.protection.outlook.com (mail-centralusazon11011052.outbound.protection.outlook.com [52.101.62.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ED9742931FF; Thu, 27 Aug 2026 06:22:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.62.52 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787811738; cv=fail; b=C4uvTM89bGLG1pblS2TjSktmg5Pw4ANYGNyOZm6+SbIbVSnBTR1Q8J/d3dR255Zs04mDv4TvDPeRItUEkMxhAQ5VBl47kD4cAlP0j5QhatxGFz3KzMmkN47jF313wzrQiIY4MBxGrhQl43RX8NMimw6ZLUJUoDpkhnAbpuVPSy0= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787811738; c=relaxed/simple; bh=+gt02zbIfZ++db4dLDB7UR1HePEJVra4Yg75xYs12Zg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=MiGaq35ihSoq6ji7H653bD/0gpvZ0ntPhIGz2nTU8sWFRceLBHR9Hadf+SXS6PERyZtisIzmWbEQptkbSxlLEa6gFr+qneTYIEM5GOWnii6ilVEqlHembSIfUVGCD7Bs3S1FEE5FQb7lym1dhoMi3gC2t6vs0gkIFGZYGI0ERkc= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=jfWaby/L; arc=fail smtp.client-ip=52.101.62.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="jfWaby/L" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=DwXD7eMbdIBYQtvhG3sX0kRYWDiYhSrV2IO3oO43wrteVkbkuJoS6t9fje2qPRpgUrexQHYqpdJnoX/50sQHk6cypv6/qhl2bFrOa1jgOVLzmUNut0Z5vhHorZCVvOxeN8u+eH2QZ/ChGYB3+S1I9OsPXJKCipEnP/ri3chJ7J8bNobkaA98Gyt55vjZK7UPpMBAPAmnds3j1Th6mM6X9BgvfV8ZZXl97Nh84tuLuDbeLYu7uDiCNkmNSB+G33868Qg3NA8YifLk/wVU7/f0xbXN8fIPF8UeX1F3g/clnYwgF69fiZjz6Scwpzf7SDim5DhkAvMpiw3uHYYU5f6x9w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=g5KyNvgJnWRa1SKjbGiMjSXI0HHvg2n7iF0u+QtJhPw=; b=QNxmCqLktdtABIXUgBzmaAJw4sWnRVf6NzpDQJ2DICRdBvt6h17vAxigCADe3lpiWKHpiFtneh/RJoob5vH+eYKrUayPrxT59fnvINLZxBzE6CkyLAZC2LupONXDsRmG3RmpQGZ8awuwLDORDuqehKJAG30W6LefbVEK2q5Oy2rn4Si2qRLKGc0k0kl39wW08m2Cv9yfT9gyylyNP0ZHDNprPeCj7N2I7ax8svrROVmvlXu0kpa5EgcxVJV4pLSymhDuvEk/b1xePnvPHIj5tRjPvGK3YDWyjKTmdLxI87KZpUA3QvzJutCYhpm0uQzot3TTPbNtb4YVtIGo7242YA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.freedesktop.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=g5KyNvgJnWRa1SKjbGiMjSXI0HHvg2n7iF0u+QtJhPw=; b=jfWaby/LDxHj7Rs+99q7yjFfG+RMcRSmSAe1gjcukZ1DT8h+Fkmx8zY2Cq58O4KPuNcElB/tyPIeCt/PbVIOK3eS+l3hSmLxouiI89ZHOPE+PaSylIs6427kQHre9C2G2Sm75P8UsbDkpMGmYMFWNNTeILtFWbOZgYWRSVjbhIE= Received: from BN9PR03CA0390.namprd03.prod.outlook.com (2603:10b6:408:f7::35) by IA1PR12MB9523.namprd12.prod.outlook.com (2603:10b6:208:595::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.10; Thu, 27 Aug 2026 06:22:10 +0000 Received: from LV8PEPF0000005F.namprd02.prod.outlook.com (2603:10b6:408:f7:cafe::4) by BN9PR03CA0390.outlook.office365.com (2603:10b6:408:f7::35) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.360.7 via Frontend Transport; Thu, 27 Aug 2026 06:22:10 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by LV8PEPF0000005F.mail.protection.outlook.com (10.167.245.137) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.3 via Frontend Transport; Thu, 27 Aug 2026 06:22:10 +0000 Received: from srishanm-Cloudripper.amd.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.45; Thu, 27 Aug 2026 01:22:05 -0500 From: Srinivasan Shanmugam To: =?UTF-8?q?Christian=20K=C3=B6nig?= , "Alex Deucher" CC: , Srinivasan Shanmugam , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Sumit Semwal , Matthew Brost , =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= , , , , , Subject: [PATCH 1/2] drm: Add common drm_user_fence helper Date: Thu, 27 Aug 2026 11:51:41 +0530 Message-ID: <20260827062142.4038272-2-srinivasan.shanmugam@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260827062142.4038272-1-srinivasan.shanmugam@amd.com> References: <20260827062142.4038272-1-srinivasan.shanmugam@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb08.amd.com (10.181.42.217) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: LV8PEPF0000005F:EE_|IA1PR12MB9523:EE_ X-MS-Office365-Filtering-Correlation-Id: 37d5333a-2f5d-4324-7d3f-08df0403871d X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|82310400026|376014|7416014|1800799024|36860700016|23010399003|11063799006|56012099006|10067099003|22082099003|18002099003; X-Microsoft-Antispam-Message-Info: SplyiW5dOtQGWhFvajXfI4tP81Uooc/D3mbkxXEYQSv6H5IDYndz7uJg3GEgWjsl1J8bF7F07vmF/C5zlpGNQ/3gq/nEVPKXRLCa6EkKDaiUbFz4To5OmfQrrtVwmUHnHwjX7TnwSyVJsCzx1a1zlyW9QdTapcVR3MGk0RgoBK039fIGh7aF/zklPtSV1qf4w5+NDbHkpamnWI7wUrcmsbON3k6jgZFyuVsnqbWl4qYk94ZsCLTFgAE4usq6IbUY59p7wKwfA+Ufzt/O7pIv1cSHcsmegJLklxqsCKZvHudpWoRjl6Vstp6tG2bwqBciCRlfxeXsMmrbpbE7Cd0dsQj9mNhDgLfyEaMmJToSK1rUJepmzQ3Kqh8hWi69EfpPo41sRUIjUDuB2eaHDBad9y/ZKWfeRb+5i2N8Kg5O2n/aHNfJMuyN7NIZY/5F6spacXDHOcMIeLalO9OyNicbsn8ae6pod+qZ8FsQcIzuCWePfTwjMZXm9szlMxUXgIf3PxDc+ZPUWbPTA4zeS/0/RoxZrgZQ2GvAViKP0NER4ois4mDgiydOxOA7VB5AnV1D/6FNeV8c4IiWlLYijK9ght27mMXKd6WZxo0mVHgRkht/s7OlXKv1+Dv7IFp4IvJeOAUmi6gjmkmJCwBl6NMrQLO+IqBbiK/LEBgF54nXvyyGg7ipvMgwc+EBttuqvY1lzOU276vWEDFDG2n0fFdHeg== X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(82310400026)(376014)(7416014)(1800799024)(36860700016)(23010399003)(11063799006)(56012099006)(10067099003)(22082099003)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: R4VY3W+zOYXHKLFQxHLIPU2B6ZvyNyYZ+92emq4ysyY0bqLKwwrs0rFeTyIPY6fXWJsVFq8Dll/DiJ9A6UdyxvrjqL6Dn5ytMIt0e6LK4PJ6QZlTKrziYmAKzlRqUipmTMDSGkxClhAdj86mbbH/h+C8o3DyFo8kU0ypkQva9HumJlHzKwgo79LiWr2NhHBYUGSPhf3UwsUFk6li+YJYlalEWFaiENQNjpWMyvtz14HUpaTW7dfiPpS86W5j3dlJLPfdPDAzTIOS/lpGv35WJQCIcZOkkCxktT1vLrC5qACNaQXFuI4EthUctbdhYaaj1MAbODjaER961Hf93c5CjC7/mdp4lK+sPbgjEviWwXuwP8lUzW+hJM62id3i+s3qelx0br61btZ9ejhmvYhir8jYbGTElfxQpndIyuJRw48kGKF0ygXEgzXzuFo1x9od X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Aug 2026 06:22:10.7716 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 37d5333a-2f5d-4324-7d3f-08df0403871d X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: LV8PEPF0000005F.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA1PR12MB9523 Introduce a common DRM user fence helper providing the kref-managed, MM-borrowing dma-fence-callback-to-workqueue pattern used by drivers that must access userspace memory from a kthread context when a GPU fence signals. XE uses this pattern (xe_sync.c) to write a fence completion value to a userspace VA. AMDGPU will use the same pattern to signal a per-queue eventfd from a user-queue EOP fence callback. The helper provides: - struct drm_user_fence: embeddable base structure - struct drm_user_fence_ops: worker/destroy callbacks - drm_user_fence_init(): initialize and grab the process MM - drm_user_fence_get/put(): reference counting - drm_user_fence_add_callback(): attach to a dma-fence The worker callback receives a bool indicating whether the process MM was successfully obtained, allowing drivers to handle the unavailable-MM case (log, skip the userspace write, etc.) without duplicating the mmget/kthread_use_mm/mmput boilerplate. Suggested-by: Christian K=C3=B6nig Cc: Alex Deucher Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: David Airlie Cc: Simona Vetter Cc: Sumit Semwal Cc: Matthew Brost Cc: Thomas Hellstr=C3=B6m Cc: dri-devel@lists.freedesktop.org Cc: intel-xe@lists.freedesktop.org Cc: linux-media@vger.kernel.org Cc: linaro-mm-sig@lists.linaro.org Cc: linux-kernel@vger.kernel.org Cc: amd-gfx@lists.freedesktop.org Signed-off-by: Srinivasan Shanmugam --- drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/drm_user_fence.c | 130 +++++++++++++++++++++++++++++++ include/drm/drm_user_fence.h | 68 ++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 drivers/gpu/drm/drm_user_fence.c create mode 100644 include/drm/drm_user_fence.h diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index e97faabcd783..52de1f474535 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -69,6 +69,7 @@ drm-y :=3D \ drm_syncobj.o \ drm_sysfs.o \ drm_trace_points.o \ + drm_user_fence.o \ drm_vblank.o \ drm_vblank_work.o \ drm_vma_manager.o \ diff --git a/drivers/gpu/drm/drm_user_fence.c b/drivers/gpu/drm/drm_user_fe= nce.c new file mode 100644 index 000000000000..bd76e3d03120 --- /dev/null +++ b/drivers/gpu/drm/drm_user_fence.c @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright =C2=A9 2024 The Linux Foundation + * + * Common DRM user fence helper. + * + * When a GPU dma-fence signals, drivers often need to write a value to a + * userspace VA or notify userspace via an eventfd. Both operations require + * a valid process MM, which is not available in IRQ context. + * + * This helper queues a work item on fence signal. The work item borrows t= he + * process MM via kthread_use_mm() and calls ops->worker(), which the driv= er + * implements to perform the actual userspace access. + */ + +#include +#include +#include + +#include + +static void drm_user_fence_destroy(struct kref *kref) +{ + struct drm_user_fence *ufence =3D + container_of(kref, struct drm_user_fence, refcount); + + mmdrop(ufence->mm); + ufence->ops->destroy(ufence); +} + +/** + * drm_user_fence_get - Acquire a reference to a user fence + * @ufence: user fence + */ +void drm_user_fence_get(struct drm_user_fence *ufence) +{ + kref_get(&ufence->refcount); +} +EXPORT_SYMBOL_GPL(drm_user_fence_get); + +/** + * drm_user_fence_put - Release a reference to a user fence + * @ufence: user fence + */ +void drm_user_fence_put(struct drm_user_fence *ufence) +{ + kref_put(&ufence->refcount, drm_user_fence_destroy); +} +EXPORT_SYMBOL_GPL(drm_user_fence_put); + +static void drm_user_fence_work(struct work_struct *w) +{ + struct drm_user_fence *ufence =3D + container_of(w, struct drm_user_fence, work); + bool mm_ok =3D false; + + if (mmget_not_zero(ufence->mm)) { + kthread_use_mm(ufence->mm); + mm_ok =3D true; + } + + ufence->ops->worker(ufence, mm_ok); + + if (mm_ok) { + kthread_unuse_mm(ufence->mm); + mmput(ufence->mm); + } + + drm_user_fence_put(ufence); +} + +static void drm_user_fence_cb(struct dma_fence *fence, struct dma_fence_cb= *cb) +{ + struct drm_user_fence *ufence =3D + container_of(cb, struct drm_user_fence, cb); + + INIT_WORK(&ufence->work, drm_user_fence_work); + queue_work(ufence->wq, &ufence->work); +} + +/** + * drm_user_fence_init - Initialize a user fence + * @ufence: user fence to initialize + * @wq: workqueue to run the worker on (must be ordered if sequencing matt= ers) + * @ops: driver operations + * + * Must be called from process context. Grabs a reference to current->mm. + */ +void drm_user_fence_init(struct drm_user_fence *ufence, + struct workqueue_struct *wq, + const struct drm_user_fence_ops *ops) +{ + kref_init(&ufence->refcount); + ufence->mm =3D current->mm; + mmgrab(ufence->mm); + ufence->wq =3D wq; + ufence->ops =3D ops; +} +EXPORT_SYMBOL_GPL(drm_user_fence_init); + +/** + * drm_user_fence_add_callback - Attach a user fence to a dma-fence + * @ufence: user fence + * @fence: dma-fence to watch; caller retains ownership of this reference + * + * When @fence signals, a work item is queued that calls ops->worker() with + * the process MM active. If @fence has already signaled the work item is + * queued immediately. + * + * Return: 0 on success, negative errno on error. + */ +int drm_user_fence_add_callback(struct drm_user_fence *ufence, + struct dma_fence *fence) +{ + int err; + + drm_user_fence_get(ufence); + err =3D dma_fence_add_callback(fence, &ufence->cb, drm_user_fence_cb); + if (err =3D=3D -ENOENT) { + /* fence already signaled =E2=80=94 queue work immediately */ + INIT_WORK(&ufence->work, drm_user_fence_work); + queue_work(ufence->wq, &ufence->work); + err =3D 0; + } else if (err) { + drm_user_fence_put(ufence); + } + + return err; +} +EXPORT_SYMBOL_GPL(drm_user_fence_add_callback); diff --git a/include/drm/drm_user_fence.h b/include/drm/drm_user_fence.h new file mode 100644 index 000000000000..de8e3f47be18 --- /dev/null +++ b/include/drm/drm_user_fence.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright =C2=A9 2024 The Linux Foundation + */ + +#ifndef __DRM_USER_FENCE_H__ +#define __DRM_USER_FENCE_H__ + +#include +#include +#include + +struct drm_user_fence; + +/** + * struct drm_user_fence_ops - driver callbacks for a DRM user fence + */ +struct drm_user_fence_ops { + /** + * @worker: Called from workqueue context. + * + * If @mm_ok is true, kthread_use_mm() is active and userspace memory + * (copy_to_user, eventfd_signal, etc.) may be accessed safely. + * If @mm_ok is false, the process MM was already gone; the driver + * should log a warning and skip the userspace write. + * + * wake_up() or other post-signal housekeeping should also happen here. + */ + void (*worker)(struct drm_user_fence *ufence, bool mm_ok); + + /** + * @destroy: Called when the last reference is dropped. + * Free the containing structure here. + */ + void (*destroy)(struct drm_user_fence *ufence); +}; + +/** + * struct drm_user_fence - embeddable DRM user fence + * + * Drivers embed this in their own structure and implement + * &drm_user_fence_ops. Call drm_user_fence_init() at creation and + * drm_user_fence_add_callback() to arm on a dma-fence. + */ +struct drm_user_fence { + /** @refcount: Reference count. */ + struct kref refcount; + /** @mm: Process MM grabbed at init time. */ + struct mm_struct *mm; + /** @work: Work item queued when the dma-fence signals. */ + struct work_struct work; + /** @cb: dma-fence callback. */ + struct dma_fence_cb cb; + /** @wq: Workqueue to run @work on. */ + struct workqueue_struct *wq; + /** @ops: Driver operations. */ + const struct drm_user_fence_ops *ops; +}; + +void drm_user_fence_init(struct drm_user_fence *ufence, + struct workqueue_struct *wq, + const struct drm_user_fence_ops *ops); +void drm_user_fence_get(struct drm_user_fence *ufence); +void drm_user_fence_put(struct drm_user_fence *ufence); +int drm_user_fence_add_callback(struct drm_user_fence *ufence, + struct dma_fence *fence); + +#endif /* __DRM_USER_FENCE_H__ */ --=20 2.34.1 From nobody Sun Sep 27 02:19:27 2026 Received: from BL2PR02CU003.outbound.protection.outlook.com (mail-eastusazon11011016.outbound.protection.outlook.com [52.101.52.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1FE0A35BDC7; Thu, 27 Aug 2026 06:22:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.52.16 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787811740; cv=fail; b=phirkCe8EdLi+8qnlcrH6W6bJzN4ZlHbqcxcc0ethCCC7XU2X/86dXh1IK5amskruFclerFfPP2oKLxDzjhfyk8PSnby33CrZHUsjeSHWn5HY4JX2HAcrdAt3eH6mdTkcG9elL/FffyUjnQKAl8n9IpZrDZHo97svlqtbR1Wb5g= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787811740; c=relaxed/simple; bh=DTjE4Y8jeaLPjF1+VL0EjodflC8Qy1V8g7elgfYSPDA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=FbZL/lGN+bQH5kgd7eg072Yu1ORlTMFHkTSXd3p8dYkDkdvI0Sm0cTLi32p1LL5TxmG5v5Xx3/BLDTF9pccJ5wAikpoXJfm4KfhZX/5TeOMbCfBqEBbyZfiv0NSYXKdoBLtmgloZdvCrPFxjFwM4hRWRKYqxsRBB+3ckJ6o0mc0= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=wD6FV4pt; arc=fail smtp.client-ip=52.101.52.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="wD6FV4pt" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=VxJJ65JcedbFzZrymvlzlsYvq95TpIwLS3i6zJKJo+/5ZR/l9cz4uFcQRQ2qrPTJfo7hv0IFFGUZQaJEmfXxYvH0fNKtIoLmlQMD9T2g/2SIvZZwKM0diRJJdOOgarak5ICFJXVqj2DXJycXgEZy0uHK7u7rv4L5I1zOApW/aVeYGNAhIC660td3Pr+HO7ycx0dcSZceRO725R96ZvkySu3drOpLlBcVoueisDCJj7cY55hurSzxFVFqrYCSOA1xVJLT7gzjyxsVo8gi6lAN+onLGR1iryUvs7STchJWKiyB9yyELN2JLOwx2OwJPXJ0Z0HH0wAzWso15fjg2L9n1w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=VcJxzJOgDHiuJOVnf5pRVwsfAK2INMPDSUmTdNAUxSI=; b=vAlY8XvQbeZG1GPp1FW+YbDuR+I61gnQPs/eCz6OwoQhfdHQiJrebsi7xARn1Llux48UvxjE/En/8GjEyRokN5OOsFKjG2XYtWltMKFIFZ1qb0Zb73PoNenlyvPjXVk27o6xbrCOUTmwYMKzUv53q1/FmK5T8GimB7zv9XqtRyE9L4fWyF5QNyGBpZatqhlN+3u6YLEeBetu8vBoEg+E1P2MdNqzo5ZzFUJklA4FL8xvsrWDSW7WFY5oR5ybzCoyRSa8IrFKxjKKOW9n63+Hbiaii1TNxbMHmaLTXp23SLoQP4cKG+QH5fpHzPi5nXYxvwxhrUrx3olLAGJep0NtVA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.freedesktop.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=VcJxzJOgDHiuJOVnf5pRVwsfAK2INMPDSUmTdNAUxSI=; b=wD6FV4ptOvQ8qTBH8bNDGYF4uFo7unt4jSvCTkELyhC4turFs1kUVU9xTUnRkR21JzutJkRHPsg+FTfrzTIqNAC3uHuxVK2nCU9GR/zfGCTvMxYqRvPPYBlrCImwfLmeedYxtXylfOhbtbN0xgY1mVmhQjxNXg6gl8RnKF9/DJY= Received: from BN1PR14CA0026.namprd14.prod.outlook.com (2603:10b6:408:e3::31) by DM3PR12MB9351.namprd12.prod.outlook.com (2603:10b6:8:1ac::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.6; Thu, 27 Aug 2026 06:22:14 +0000 Received: from LV8PEPF0000005A.namprd02.prod.outlook.com (2603:10b6:408:e3:cafe::39) by BN1PR14CA0026.outlook.office365.com (2603:10b6:408:e3::31) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.360.10 via Frontend Transport; Thu, 27 Aug 2026 06:22:14 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by LV8PEPF0000005A.mail.protection.outlook.com (10.167.245.135) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.360.3 via Frontend Transport; Thu, 27 Aug 2026 06:22:14 +0000 Received: from srishanm-Cloudripper.amd.com (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.45; Thu, 27 Aug 2026 01:22:09 -0500 From: Srinivasan Shanmugam To: =?UTF-8?q?Christian=20K=C3=B6nig?= , "Alex Deucher" CC: , Srinivasan Shanmugam , Matthew Brost , =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= , Rodrigo Vivi , Mika Kuoppala , David Airlie , "Simona Vetter" , Sumit Semwal , , , , , Subject: [PATCH 2/2] drm/xe: Convert xe_user_fence to drm_user_fence Date: Thu, 27 Aug 2026 11:51:42 +0530 Message-ID: <20260827062142.4038272-3-srinivasan.shanmugam@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260827062142.4038272-1-srinivasan.shanmugam@amd.com> References: <20260827062142.4038272-1-srinivasan.shanmugam@amd.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: satlexmb08.amd.com (10.181.42.217) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: LV8PEPF0000005A:EE_|DM3PR12MB9351:EE_ X-MS-Office365-Filtering-Correlation-Id: 081388c5-1be3-42e1-62fc-08df04038919 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|7416014|1800799024|82310400026|23010399003|36860700016|56012099006|10067099003|22082099003|18002099003|11063799006|6133799003; X-Microsoft-Antispam-Message-Info: YrwuA/e5itQ9A5v6xyng/MUkLEHSBDjm35AZaBO0BdIcemR6dmYUW1yyykD+PfkIYTerr06V8Akh8bDG+yNAsJf3Wyvkx2KN70GbISuzzOrQTZDNgeduWVNh93XsWTK3n2uRc6Z3TJwWAPjUyvPVW1IKHWIVhzs4kKNRIL9JDArht27Uo7SHyrHwN9TmvcBKW+ptzvg4EHKitBF/Y1adI+VUIVBd4CdQUREUyQkSinXL+Nx2IfE/siQ6OtuTaWM+VrOOW7lg223ZXuMn9P9liFWvqVSDYEyT+/wM9MhrmRRB4f/rzbABRK9L7Ihw66Ddpe/6Tyt/hZLqtCFD9UUo2ksZATnPWTrLxBwhhL8vUnudSzHLjYfpbvZjnjm1b9OTwlYrvtuwJoRMZHLUYnq5d/Arjgv1thvZ1CL/cy+oaC2Pa6TNLBdDdh7fBXVZ8762ii28luq/yD2n9IjqxOFOMYqYfK0dHVzLGXoZ3FOmiS/s6Y8ZPDyrm2AQEeZT6+LG8n4zzd4BjzxR0T6bMGSLxG3N7FsCDjXU6kNN9PL+/9sWXfAZ1TSKz6fYu2BotnMG+UEfI1CFveUfQTmNfrfm5v3+WElWB2I/qIOXOlzZAMQZzjQfXOYd2e4kihZf+j6lBafu3Pwp7wXI8slhbix2zdx57JGABPvEt5N95PGSbgdH0uPuwQxkAbWa0JS5hD68jtaozCWn++y+NqIGTO6anw== X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(376014)(7416014)(1800799024)(82310400026)(23010399003)(36860700016)(56012099006)(10067099003)(22082099003)(18002099003)(11063799006)(6133799003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: z5LkNP3gzK1WqLDiJrk/TxqqnWucXk4DcthU169Gn1x7dNkLaBrgnZK8/vXqUbRdMjpoABHTfGQPSp6vKQsIICAJWHzLM8DvQEFW5H1cFetb2D9aiychkdnQRw761kNvXVnoBANQg3qI/TtJr6xmWngbn61pJWwU2idj2MCjR7EGV72stsVNLClFmXO/t7a/j1LIJb/DAD9JL22sOikuYtiFsteIuz11VIGgxum5It3HJiA0PetmjXoZt3jf98vDnm4+kJPp6HGkvwq9+auPrSceG6VM/WaTrezDY0+vBro/upZap9F+MSLqx6mSx6Q851I5cJW9cZAvNrhofTQ7fdqZ3A9EEwVXTeA5OMhRXFyy/Xq+l+WcWDaLDIctcU64Jabb1OEZM0O3izWQjs+5g48Fb+Wfy4ujyEbJppyI11TCRQC7Xai3jQgqrBSzXAEe X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Aug 2026 06:22:14.1033 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 081388c5-1be3-42e1-62fc-08df04038919 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: LV8PEPF0000005A.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM3PR12MB9351 Replace the open-coded user fence implementation in xe_sync.c with the new common drm_user_fence helper. struct xe_user_fence now embeds struct drm_user_fence as its base. XE-specific fields (xe_device pointer for the ufence_wq wake-up, userspace VA, expected value, signalled flag) remain in the wrapper. The local user_fence_destroy/get/put/worker/kick_ufence/user_fence_cb functions are removed. Their logic moves to xe_ufence_ops.worker and xe_ufence_ops.destroy, which are called by drm_user_fence_work(). Cc: Matthew Brost Cc: Thomas Hellstr=C3=B6m Cc: Rodrigo Vivi Cc: Mika Kuoppala Cc: David Airlie Cc: Simona Vetter Cc: Sumit Semwal Cc: Christian K=C3=B6nig Cc: Alex Deucher Cc: intel-xe@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Cc: linux-media@vger.kernel.org Cc: linaro-mm-sig@lists.linaro.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Srinivasan Shanmugam Suggested-by: Christian K=C3=B6nig --- drivers/gpu/drm/xe/xe_sync.c | 114 ++++++++++++----------------- drivers/gpu/drm/xe/xe_sync_types.h | 1 - 2 files changed, 45 insertions(+), 70 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_sync.c b/drivers/gpu/drm/xe/xe_sync.c index 37866768d64c..59ff08010b2f 100644 --- a/drivers/gpu/drm/xe/xe_sync.c +++ b/drivers/gpu/drm/xe/xe_sync.c @@ -6,12 +6,11 @@ #include "xe_sync.h" =20 #include -#include -#include #include =20 #include #include +#include #include =20 #include "xe_device.h" @@ -19,36 +18,51 @@ #include "xe_macros.h" #include "xe_sched_job_types.h" =20 +/* + * xe_user_fence wraps drm_user_fence with XE-specific fields. + * The drm_user_fence base handles MM borrowing and work-item lifetime. + */ struct xe_user_fence { - struct xe_device *xe; - struct kref refcount; - struct dma_fence_cb cb; - struct work_struct worker; - struct mm_struct *mm; - u64 __user *addr; - u64 value; - int signalled; + struct drm_user_fence base; + struct xe_device *xe; + u64 __user *addr; + u64 value; + int signalled; }; =20 -static void user_fence_destroy(struct kref *kref) +static void xe_ufence_worker(struct drm_user_fence *base, bool mm_ok) { - struct xe_user_fence *ufence =3D container_of(kref, struct xe_user_fence, - refcount); + struct xe_user_fence *ufence =3D container_of(base, struct xe_user_fence,= base); =20 - mmdrop(ufence->mm); - kfree(ufence); -} + /* + * Mark signalled before waking waiters so UMD can safely reuse + * the same ufence without hitting -EBUSY. + */ + WRITE_ONCE(ufence->signalled, 1); =20 -static void user_fence_get(struct xe_user_fence *ufence) -{ - kref_get(&ufence->refcount); + if (mm_ok) { + if (copy_to_user(ufence->addr, &ufence->value, sizeof(ufence->value))) + XE_WARN_ON("Copy to user failed"); + } else { + drm_dbg(&ufence->xe->drm, + "mmget_not_zero() failed, ufence wasn't signaled\n"); + } + + wake_up_all(&ufence->xe->ufence_wq); } =20 -static void user_fence_put(struct xe_user_fence *ufence) +static void xe_ufence_destroy(struct drm_user_fence *base) { - kref_put(&ufence->refcount, user_fence_destroy); + struct xe_user_fence *ufence =3D container_of(base, struct xe_user_fence,= base); + + kfree(ufence); } =20 +static const struct drm_user_fence_ops xe_ufence_ops =3D { + .worker =3D xe_ufence_worker, + .destroy =3D xe_ufence_destroy, +}; + static struct xe_user_fence *user_fence_create(struct xe_device *xe, u64 a= ddr, u64 value) { @@ -63,51 +77,22 @@ static struct xe_user_fence *user_fence_create(struct x= e_device *xe, u64 addr, if (!ufence) return ERR_PTR(-ENOMEM); =20 - ufence->xe =3D xe; - kref_init(&ufence->refcount); - ufence->addr =3D ptr; + ufence->xe =3D xe; + ufence->addr =3D ptr; ufence->value =3D value; - ufence->mm =3D current->mm; - mmgrab(ufence->mm); + drm_user_fence_init(&ufence->base, xe->ordered_wq, &xe_ufence_ops); =20 return ufence; } =20 -static void user_fence_worker(struct work_struct *w) -{ - struct xe_user_fence *ufence =3D container_of(w, struct xe_user_fence, wo= rker); - - WRITE_ONCE(ufence->signalled, 1); - if (mmget_not_zero(ufence->mm)) { - kthread_use_mm(ufence->mm); - if (copy_to_user(ufence->addr, &ufence->value, sizeof(ufence->value))) - XE_WARN_ON("Copy to user failed"); - kthread_unuse_mm(ufence->mm); - mmput(ufence->mm); - } else { - drm_dbg(&ufence->xe->drm, "mmget_not_zero() failed, ufence wasn't signal= ed\n"); - } - - /* - * Wake up waiters only after updating the ufence state, allowing the UMD - * to safely reuse the same ufence without encountering -EBUSY errors. - */ - wake_up_all(&ufence->xe->ufence_wq); - user_fence_put(ufence); -} - -static void kick_ufence(struct xe_user_fence *ufence, struct dma_fence *fe= nce) +static void user_fence_get(struct xe_user_fence *ufence) { - INIT_WORK(&ufence->worker, user_fence_worker); - queue_work(ufence->xe->ordered_wq, &ufence->worker); - dma_fence_put(fence); + drm_user_fence_get(&ufence->base); } =20 -static void user_fence_cb(struct dma_fence *fence, struct dma_fence_cb *cb) +static void user_fence_put(struct xe_user_fence *ufence) { - struct xe_user_fence *ufence =3D container_of(cb, struct xe_user_fence, c= b); - - kick_ufence(ufence, fence); + drm_user_fence_put(&ufence->base); } =20 int xe_sync_entry_parse(struct xe_device *xe, struct xe_file *xef, @@ -282,24 +267,15 @@ void xe_sync_entry_signal(struct xe_sync_entry *sync,= struct dma_fence *fence) } else if (sync->syncobj) { drm_syncobj_replace_fence(sync->syncobj, fence); } else if (sync->ufence) { - int err; - drm_syncobj_add_point(sync->ufence_syncobj, sync->ufence_chain_fence, fence, sync->ufence_timeline_value); sync->ufence_chain_fence =3D NULL; =20 fence =3D drm_syncobj_fence_get(sync->ufence_syncobj); - user_fence_get(sync->ufence); - err =3D dma_fence_add_callback(fence, &sync->ufence->cb, - user_fence_cb); - if (err =3D=3D -ENOENT) { - kick_ufence(sync->ufence, fence); - } else if (err) { + if (drm_user_fence_add_callback(&sync->ufence->base, fence)) XE_WARN_ON("failed to add user fence"); - user_fence_put(sync->ufence); - dma_fence_put(fence); - } + dma_fence_put(fence); } } =20 @@ -443,4 +419,3 @@ void xe_sync_ufence_put(struct xe_user_fence *ufence) int xe_sync_ufence_get_status(struct xe_user_fence *ufence) { return READ_ONCE(ufence->signalled); -} +} diff --git a/drivers/gpu/drm/xe/xe_sync_types.h b/drivers/gpu/drm/xe/xe_syn= c_types.h index b88f1833e28c..67048199b070 100644 --- a/drivers/gpu/drm/xe/xe_sync_types.h +++ b/drivers/gpu/drm/xe/xe_sync_types.h @@ -12,7 +12,6 @@ struct drm_syncobj; struct dma_fence; struct dma_fence_chain; struct drm_xe_sync; -struct user_fence; =20 struct xe_sync_entry { struct drm_syncobj *syncobj; --=20 2.34.1