From nobody Sun Dec 14 19:31:51 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (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 CA7142BD033 for ; Wed, 21 May 2025 20:47:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860452; cv=none; b=NzJpK2uCVqeZsbHl8+8KiMWYj4/LBxuiP5cz0aZlMFD5p0tJDekla+YxA1IGq5cJhWf951ufJlkjuKxYDn4V1vd3+yqvScB37h+1PZeDZZq0QPmtzAfZJSuY0ipkCeQvBS1PVFVNiHVKmdKYV+7huBJA1Vj2x/n5veD48N1OODs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860452; c=relaxed/simple; bh=1wSa76uvekgQE01+MQeWukvMp4xVzsb72HGt4+9lMdA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lkD94Do4x0Jnx5lKPQof5QEcMJoCVjTSD0erXSEB3HCVfjeULYn6DGCmosfTJo5VYNqSm4hXXUlPwxHAvF27aTmxHQMzamkQNUtJEF1G24Dv4gGAGyCi4AwR1hLckZy2uqnaspRj6Bhm5ptcXphsFosOoMRIWgK2+MhgacnMLwI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=SDkxh4gT; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="SDkxh4gT" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747860449; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=PmeIsR+A9CWCGJ6MrpGMC5fCHJO5oO+SAH4nW/MP2Dw=; b=SDkxh4gTgLFiiA5sFWG0V5/Kj5aFMplXfTP2ux032qIEZA7vTtmHlaus+42J/CBVCl+BFr eyxWk+C6P/mM2GwYCuyp7aM7j7uutJ+VXAwS0eER3kiIX6DjQpgZOzqGVgkXu5fc6PxL2C xSE9wVZD5MuNHK81sNpcuE/biQqXizg= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-132-woAIiBBtP0-c_UXCoodg9Q-1; Wed, 21 May 2025 16:47:26 -0400 X-MC-Unique: woAIiBBtP0-c_UXCoodg9Q-1 X-Mimecast-MFC-AGG-ID: woAIiBBtP0-c_UXCoodg9Q_1747860443 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 2D828195608E; Wed, 21 May 2025 20:47:23 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.80.100]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 3040019560B7; Wed, 21 May 2025 20:47:18 +0000 (UTC) From: Lyude Paul To: dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Asahi Lina , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Sumit Semwal , =?UTF-8?q?Christian=20K=C3=B6nig?= , Greg Kroah-Hartman , Viresh Kumar , Wedson Almeida Filho , Daniel Almeida , linux-media@vger.kernel.org (open list:DMA BUFFER SHARING FRAMEWORK:Keyword:\bdma_(?:buf|fence|resv)\b), linaro-mm-sig@lists.linaro.org (moderated list:DMA BUFFER SHARING FRAMEWORK:Keyword:\bdma_(?:buf|fence|resv)\b) Subject: [PATCH v2 01/12] rust: helpers: Add bindings/wrappers for dma_resv_lock Date: Wed, 21 May 2025 16:29:08 -0400 Message-ID: <20250521204654.1610607-2-lyude@redhat.com> In-Reply-To: <20250521204654.1610607-1-lyude@redhat.com> References: <20250521204654.1610607-1-lyude@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 Content-Type: text/plain; charset="utf-8" From: Asahi Lina This is just for basic usage in the DRM shmem abstractions for implied locking, not intended as a full DMA Reservation abstraction yet. Signed-off-by: Asahi Lina Signed-off-by: Daniel Almeida Signed-off-by: Lyude Paul --- rust/bindings/bindings_helper.h | 1 + rust/helpers/dma-resv.c | 13 +++++++++++++ rust/helpers/helpers.c | 1 + 3 files changed, 15 insertions(+) create mode 100644 rust/helpers/dma-resv.c diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helpe= r.h index 31369b7b23884..409e9a595e051 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/rust/helpers/dma-resv.c b/rust/helpers/dma-resv.c new file mode 100644 index 0000000000000..05501cb814513 --- /dev/null +++ b/rust/helpers/dma-resv.c @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include + +int rust_helper_dma_resv_lock(struct dma_resv *obj, struct ww_acquire_ctx = *ctx) +{ + return dma_resv_lock(obj, ctx); +} + +void rust_helper_dma_resv_unlock(struct dma_resv *obj) +{ + dma_resv_unlock(obj); +} diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c index 20a4ee59acd89..3ba1652899c2b 100644 --- a/rust/helpers/helpers.c +++ b/rust/helpers/helpers.c @@ -15,6 +15,7 @@ #include "cpumask.c" #include "cred.c" #include "device.c" +#include "dma-resv.c" #include "drm.c" #include "err.c" #include "fs.c" --=20 2.49.0 From nobody Sun Dec 14 19:31:51 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (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 735A52BD5AD for ; Wed, 21 May 2025 20:47:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860462; cv=none; b=c7PYnp8ZfHR9O8NMLJikc9VwHpYPyS8Y3f0tys9Iq/Kxe73RaON3EvW9S4w66bWL3DiqCuvZ4ISURtD/10lklK1gZmJAptIoQp8DsMRY+TkEp9w0yqEZk31Chv+AbAsaQ0c/t1XxQg0EzaHf1scVwoj2l5zygQ+J0p6NLA2ZOu4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860462; c=relaxed/simple; bh=0c2oplzE7ye6DqYq04TMP1x07rAa307O9OXTTRZnud4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=L0YQk5XYyB8YxATmLEhtRrpjxKQajvZN+RSspaXpMa+ay/ucWfLs6CbATIL/4uCeGuYAaXadIYhvxGYiEEwuATHIGNC1/mOZSxfUvifhrTtEsxBKp6Rbb4CVjbFJgXANTxF3ToFwzwIGA3NJ0qGP4peUtsQVL6ycVduQs0LOwIw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=T2qHVm1z; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="T2qHVm1z" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747860459; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pDc7UrnplZlvIH+UwUNJeqjQtwIG9fWAmJ0c6OZ2V0k=; b=T2qHVm1ztRAoTXgNuoheoAvDO75q2QGDdklKaiXCtmEbzw6LjCJOZmawZQqW+ZE1JVSZrt pjmPx7yljEjNCzKAMAMDZR/ww4ZbQCLUqViCXLGjUn5Mnfqu1NMOWWjqbeZHxFo8UzpmLo Uf3ZrLGGqVbeGvUH7KYEl7F5Np+RBxc= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-457-80NufYDvOvmNHzpndZQ9SQ-1; Wed, 21 May 2025 16:47:35 -0400 X-MC-Unique: 80NufYDvOvmNHzpndZQ9SQ-1 X-Mimecast-MFC-AGG-ID: 80NufYDvOvmNHzpndZQ9SQ_1747860453 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id B6B74180035C; Wed, 21 May 2025 20:47:31 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.80.100]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 34EC119560B7; Wed, 21 May 2025 20:47:26 +0000 (UTC) From: Lyude Paul To: dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Sumit Semwal , =?UTF-8?q?Christian=20K=C3=B6nig?= , Daniel Almeida , Asahi Lina , Alyssa Rosenzweig , linux-media@vger.kernel.org (open list:DMA BUFFER SHARING FRAMEWORK:Keyword:\bdma_(?:buf|fence|resv)\b), linaro-mm-sig@lists.linaro.org (moderated list:DMA BUFFER SHARING FRAMEWORK:Keyword:\bdma_(?:buf|fence|resv)\b) Subject: [PATCH v2 02/12] rust: drm: gem: Add raw_dma_resv() function Date: Wed, 21 May 2025 16:29:09 -0400 Message-ID: <20250521204654.1610607-3-lyude@redhat.com> In-Reply-To: <20250521204654.1610607-1-lyude@redhat.com> References: <20250521204654.1610607-1-lyude@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 Content-Type: text/plain; charset="utf-8" For retrieving a pointer to the struct dma_resv for a given GEM object. We also introduce it in a new trait, BaseObjectPrivate, which we automatically implement for all gem objects and don't expose to users outside of the crate. Signed-off-by: Lyude Paul --- rust/kernel/drm/gem/mod.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs index 992e098d0a3e2..1165417b22df6 100644 --- a/rust/kernel/drm/gem/mod.rs +++ b/rust/kernel/drm/gem/mod.rs @@ -186,6 +186,17 @@ fn create_mmap_offset(&self) -> Result { =20 impl BaseObject for T {} =20 +/// Crate-private base operations shared by all GEM object classes. +pub(crate) trait BaseObjectPrivate: IntoGEMObject { + /// Return a pointer to this object's dma_resv. + fn raw_dma_resv(&self) -> *mut bindings::dma_resv { + // SAFETY: `as_gem_obj()` always returns a valid pointer to the ba= se DRM gem object + unsafe { (*self.as_raw()).resv } + } +} + +impl BaseObjectPrivate for T {} + /// A base GEM object. /// /// Invariants --=20 2.49.0 From nobody Sun Dec 14 19:31:51 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (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 4721A2C1781 for ; Wed, 21 May 2025 20:47:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860465; cv=none; b=BIcyZnACAPrQSRxfTaJDlPaMnZ83YGFJtgmlUmqD6P4GFq9QF22FhIn5FL/8652ph7obYGixtz6c6NFpkwlmYxRrfCqCuRAJlU3sndxuU9JyAHz71LDRN8uRGmnTjPyZ7AaOGqgtUEcbigJSpB9swxPRQzHRb0Gi2SX+aj/7r/4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860465; c=relaxed/simple; bh=7fCVuftSN1aBnYJ9hYXJ+RIa/hUOPO3fR89aM9voWhQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FT2gyf/u0X6WW8qTL7gRC3J/mNotD9bW1Qce3FQM33UPUs9MhyIgokhs79YpYucD9fr6FkrKV/F9pV2SwXNptOua/7Pwey39/7cDhiiVdc7md+netiD5By1J2+MRzk3bkPQEkE5JG103+DiHov5F4/6k51gwEDIf/dk9SHEot+0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=bHceHa0r; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="bHceHa0r" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747860463; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WZFnjWwVw3G9FTHb5RE01lQ8HhDpRBWEySGBEF+FoVQ=; b=bHceHa0r41R95IC3UoXWj8bJ5pVNPOC/ZZnZ15/Maxn2nN4cEhTQnKlLOgQAicuz0GFPHf PsAf2UH202Oi+5AhUoy8FnFwR3R6OfwxRj0DO4NLhyc6PuYaiT0YLujbgGNyooVZAMrE3J idmxut1+p5PBZb3zC0gaCHvu3zEEUcg= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-363-Gsrj4wuoMHGmCvM2fLFDuA-1; Wed, 21 May 2025 16:47:38 -0400 X-MC-Unique: Gsrj4wuoMHGmCvM2fLFDuA-1 X-Mimecast-MFC-AGG-ID: Gsrj4wuoMHGmCvM2fLFDuA_1747860456 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 744FD180036E; Wed, 21 May 2025 20:47:36 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.80.100]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 602931956066; Wed, 21 May 2025 20:47:32 +0000 (UTC) From: Lyude Paul To: dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich Subject: [PATCH v2 03/12] drm/gem/shmem: Extract drm_gem_shmem_init() from drm_gem_shmem_create() Date: Wed, 21 May 2025 16:29:10 -0400 Message-ID: <20250521204654.1610607-4-lyude@redhat.com> In-Reply-To: <20250521204654.1610607-1-lyude@redhat.com> References: <20250521204654.1610607-1-lyude@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 Content-Type: text/plain; charset="utf-8" With gem objects in rust, the most ideal way for us to be able to handle gem shmem object creation is to be able to handle the memory allocation of a gem object ourselves - and then have the DRM gem shmem helpers initialize the object we've allocated afterwards. So, let's spit out drm_gem_shmem_init() from drm_gem_shmem_create() to allow for doing this. Signed-off-by: Lyude Paul --- drivers/gpu/drm/drm_gem_shmem_helper.c | 75 +++++++++++++++++--------- include/drm/drm_gem_shmem_helper.h | 1 + 2 files changed, 51 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_g= em_shmem_helper.c index a4144e0ef67ef..f3e88fb579b52 100644 --- a/drivers/gpu/drm/drm_gem_shmem_helper.c +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c @@ -48,28 +48,12 @@ static const struct drm_gem_object_funcs drm_gem_shmem_= funcs =3D { .vm_ops =3D &drm_gem_shmem_vm_ops, }; =20 -static struct drm_gem_shmem_object * -__drm_gem_shmem_create(struct drm_device *dev, size_t size, bool private, - struct vfsmount *gemfs) +static int __drm_gem_shmem_init(struct drm_device *dev, struct drm_gem_shm= em_object *shmem, + size_t size, bool private, struct vfsmount *gemfs) { - struct drm_gem_shmem_object *shmem; - struct drm_gem_object *obj; + struct drm_gem_object *obj =3D &shmem->base; int ret =3D 0; =20 - size =3D PAGE_ALIGN(size); - - if (dev->driver->gem_create_object) { - obj =3D dev->driver->gem_create_object(dev, size); - if (IS_ERR(obj)) - return ERR_CAST(obj); - shmem =3D to_drm_gem_shmem_obj(obj); - } else { - shmem =3D kzalloc(sizeof(*shmem), GFP_KERNEL); - if (!shmem) - return ERR_PTR(-ENOMEM); - obj =3D &shmem->base; - } - if (!obj->funcs) obj->funcs =3D &drm_gem_shmem_funcs; =20 @@ -81,7 +65,7 @@ __drm_gem_shmem_create(struct drm_device *dev, size_t siz= e, bool private, } if (ret) { drm_gem_private_object_fini(obj); - goto err_free; + return ret; } =20 ret =3D drm_gem_create_mmap_offset(obj); @@ -102,14 +86,55 @@ __drm_gem_shmem_create(struct drm_device *dev, size_t = size, bool private, __GFP_RETRY_MAYFAIL | __GFP_NOWARN); } =20 - return shmem; - + return 0; err_release: drm_gem_object_release(obj); -err_free: - kfree(obj); + return ret; +} =20 - return ERR_PTR(ret); +/** + * drm_gem_shmem_init - Initialize an allocated object. + * @dev: DRM device + * @obj: The allocated shmem GEM object. + * + * Returns: + * 0 on success, or a negative error code on failure. + */ +int drm_gem_shmem_init(struct drm_device *dev, struct drm_gem_shmem_object= *shmem, size_t size) +{ + return __drm_gem_shmem_init(dev, shmem, size, false, NULL); +} +EXPORT_SYMBOL_GPL(drm_gem_shmem_init); + +static struct drm_gem_shmem_object * +__drm_gem_shmem_create(struct drm_device *dev, size_t size, bool private, + struct vfsmount *gemfs) +{ + struct drm_gem_shmem_object *shmem; + struct drm_gem_object *obj; + int ret =3D 0; + + size =3D PAGE_ALIGN(size); + + if (dev->driver->gem_create_object) { + obj =3D dev->driver->gem_create_object(dev, size); + if (IS_ERR(obj)) + return ERR_CAST(obj); + shmem =3D to_drm_gem_shmem_obj(obj); + } else { + shmem =3D kzalloc(sizeof(*shmem), GFP_KERNEL); + if (!shmem) + return ERR_PTR(-ENOMEM); + obj =3D &shmem->base; + } + + ret =3D __drm_gem_shmem_init(dev, shmem, size, private, gemfs); + if (ret) { + kfree(obj); + return ERR_PTR(ret); + } + + return shmem; } /** * drm_gem_shmem_create - Allocate an object with the given size diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem= _helper.h index cef5a6b5a4d63..ea0785d1700a5 100644 --- a/include/drm/drm_gem_shmem_helper.h +++ b/include/drm/drm_gem_shmem_helper.h @@ -96,6 +96,7 @@ struct drm_gem_shmem_object { #define to_drm_gem_shmem_obj(obj) \ container_of(obj, struct drm_gem_shmem_object, base) =20 +int drm_gem_shmem_init(struct drm_device *dev, struct drm_gem_shmem_object= *shmem, size_t size); struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, = size_t size); struct drm_gem_shmem_object *drm_gem_shmem_create_with_mnt(struct drm_devi= ce *dev, size_t size, --=20 2.49.0 From nobody Sun Dec 14 19:31:51 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (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 C4B4F2C17A3 for ; Wed, 21 May 2025 20:47:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860470; cv=none; b=i6kSz8Gfiq6BcAODTSzP1xB7ABJUIaZ3GA+tPKpWP3qWJ2u6wbQcyl5mGPLNQ2yHqF+NErVMlZpyB+uk95gGikOvub72JGrnbqYnBB2uli8SEGd29D2o60Vnh6dkyOqQgwsK5IBsxrNGs6sKXBDTJRivm8JutiVm02Y8JoTiQ34= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860470; c=relaxed/simple; bh=fK1MynsL225wWo3dHGnSbcLRkU5iw/wknAYv04lLgS8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AZusfTxSVKQfUEoEMLDEg6knG5VAsR7stJMF/RB++9wvMxCieEL8AKLo15uxS0cLcAb/yE8U8h0EgT//V/kW7e4xDX23yhovLmKsYVOWreCt5V/yT84mPMKarM4kFXz6wJH9CzcfyB7XSbCFafPwbMUVKVqsnZnHXkEWpjwywus= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=MBLaDBtU; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="MBLaDBtU" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747860467; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=T5V2okoaOmmH00na+R0WqQ3AiEj1bd5ShKvbaofJb94=; b=MBLaDBtUpOIf9cKsqP+4gsoWhiARPogI42Jc9mzwXDj2EXsKcLeyUKPErpgkQ1L6REUNpr LmBOpt4im40onJvy+oq6cRHK/5xo9h+83m1E8IuMScGaU5mXPGmdgsSPE2hbHMveJBZYDP jQ8nil9aHF0uhJvdyTgd1T3p+QJF6Yo= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-562-jZQT4f8POSOyI2WeOE0xgw-1; Wed, 21 May 2025 16:47:44 -0400 X-MC-Unique: jZQT4f8POSOyI2WeOE0xgw-1 X-Mimecast-MFC-AGG-ID: jZQT4f8POSOyI2WeOE0xgw_1747860461 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 723D1180034A; Wed, 21 May 2025 20:47:41 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.80.100]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id E441819560B7; Wed, 21 May 2025 20:47:36 +0000 (UTC) From: Lyude Paul To: dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich Subject: [PATCH v2 04/12] drm/gem/shmem: Extract drm_gem_shmem_release() from drm_gem_shmem_free() Date: Wed, 21 May 2025 16:29:11 -0400 Message-ID: <20250521204654.1610607-5-lyude@redhat.com> In-Reply-To: <20250521204654.1610607-1-lyude@redhat.com> References: <20250521204654.1610607-1-lyude@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 Content-Type: text/plain; charset="utf-8" At the moment the way that freeing gem shmem objects is not ideal for rust bindings. drm_gem_shmem_free() releases all of the associated memory with a gem shmem object with kfree(), which means that for us to correctly release a gem shmem object in rust we have to manually drop all of the contents of our gem object structure in-place by hand before finally calling drm_gem_shmem_free() to release the shmem resources and the allocation for the gem object. Since the only reason this is an issue is because of drm_gem_shmem_free() calling kfree(), we can fix this by splitting drm_gem_shmem_free() out into itself and drm_gem_shmem_release(), where drm_gem_shmem_release() releases the various gem shmem resources without freeing the structure itself. With this, we can safely re-acquire the KBox for the gem object's memory allocation and let rust handle cleaning up all of the other struct members automatically. Signed-off-by: Lyude Paul --- drivers/gpu/drm/drm_gem_shmem_helper.c | 23 ++++++++++++++++++----- include/drm/drm_gem_shmem_helper.h | 1 + 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_g= em_shmem_helper.c index f3e88fb579b52..42652be37ba77 100644 --- a/drivers/gpu/drm/drm_gem_shmem_helper.c +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c @@ -175,13 +175,13 @@ struct drm_gem_shmem_object *drm_gem_shmem_create_wit= h_mnt(struct drm_device *de EXPORT_SYMBOL_GPL(drm_gem_shmem_create_with_mnt); =20 /** - * drm_gem_shmem_free - Free resources associated with a shmem GEM object - * @shmem: shmem GEM object to free + * drm_gem_shmem_release - Release resources associated with a shmem GEM o= bject. + * @shmem: shmem GEM object * - * This function cleans up the GEM object state and frees the memory used = to - * store the object itself. + * This function cleans up the GEM object state, but does not free the mem= ory used to store the + * object itself. This function is meant to be a dedicated helper for the = Rust GEM bindings. */ -void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) +void drm_gem_shmem_release(struct drm_gem_shmem_object *shmem) { struct drm_gem_object *obj =3D &shmem->base; =20 @@ -207,6 +207,19 @@ void drm_gem_shmem_free(struct drm_gem_shmem_object *s= hmem) } =20 drm_gem_object_release(obj); +} +EXPORT_SYMBOL_GPL(drm_gem_shmem_release); + +/** + * drm_gem_shmem_free - Free resources associated with a shmem GEM object + * @shmem: shmem GEM object to free + * + * This function cleans up the GEM object state and frees the memory used = to + * store the object itself. + */ +void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) +{ + drm_gem_shmem_release(shmem); kfree(shmem); } EXPORT_SYMBOL_GPL(drm_gem_shmem_free); diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem= _helper.h index ea0785d1700a5..e009022b0bb48 100644 --- a/include/drm/drm_gem_shmem_helper.h +++ b/include/drm/drm_gem_shmem_helper.h @@ -101,6 +101,7 @@ struct drm_gem_shmem_object *drm_gem_shmem_create(struc= t drm_device *dev, size_t struct drm_gem_shmem_object *drm_gem_shmem_create_with_mnt(struct drm_devi= ce *dev, size_t size, struct vfsmount *gemfs); +void drm_gem_shmem_release(struct drm_gem_shmem_object *shmem); void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem); =20 void drm_gem_shmem_put_pages(struct drm_gem_shmem_object *shmem); --=20 2.49.0 From nobody Sun Dec 14 19:31:51 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (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 60B7D233D85 for ; Wed, 21 May 2025 20:48:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860483; cv=none; b=fipjmNLvJUdgcNM3JUo5yAkRSIhexTFx7JLB+dejN9v1ZysoDIwK5h9TVSjZZMkO3enWB6iURPob93d5NEg5OX2NMZEmYX/aBSY98q9sm9ymLVsorM036gDs7OmHjEf8aBZO9HpKHRxlqROF2yn5Cr+J4FoTCn4tEdHcAq4utJA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860483; c=relaxed/simple; bh=DuvypMr/sE/KpBVknOlgRGkISCm1LawO64dkNdpNx3o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UXjB1aNSOHRMGEepXzhlSLTXqemfavQWN3ur1DFtqpbBqWCYIEIXxC5lkIxQY51OuUgR90D1t06qxUyokwR+uE3efxsVmHvRSEn5JPgepDvCr/TrkSR7dqjG2Vn0VgnUZroQDAdsgPMSWjhEcOsMXytJYQQULKXfte+r7efB/hE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=CdPNkAE+; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="CdPNkAE+" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747860480; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=RgwTalUkkAEy4l2DBxsf/Vl1dLrGg/xqBOQv/M/fvO0=; b=CdPNkAE+cAnZpfmSmgF0II/BYQ9f8CpsaVebQPqvNZFNMX1XL74VdxrMBgLDw75Cag1yTf 5DFd4nh4g6a7rRtK/k0ZFzbutY1teR7Nh8netpg9K/yb8jfSubUxZQxJNYlZ4X/xlEf9yr ylsmAvD9pwq0IR5qONJR2T7YOUyuSXw= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-302-FkNUIldNNVeR8qfxLEVciQ-1; Wed, 21 May 2025 16:47:56 -0400 X-MC-Unique: FkNUIldNNVeR8qfxLEVciQ-1 X-Mimecast-MFC-AGG-ID: FkNUIldNNVeR8qfxLEVciQ_1747860469 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 3C2E3195608E; Wed, 21 May 2025 20:47:49 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.80.100]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 82E8B19560B7; Wed, 21 May 2025 20:47:44 +0000 (UTC) From: Lyude Paul To: dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Danilo Krummrich , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Daniel Almeida , Asahi Lina , Alyssa Rosenzweig , nouveau@lists.freedesktop.org (open list:DRM DRIVER FOR NVIDIA GPUS [RUST]) Subject: [PATCH v2 05/12] rust: gem: Introduce BaseDriverObject::Args Date: Wed, 21 May 2025 16:29:12 -0400 Message-ID: <20250521204654.1610607-6-lyude@redhat.com> In-Reply-To: <20250521204654.1610607-1-lyude@redhat.com> References: <20250521204654.1610607-1-lyude@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 Content-Type: text/plain; charset="utf-8" This is an associated type that may be used in order to specify a data-type to pass to gem objects when construction them, allowing for drivers to more easily initialize their private-data for gem objects. Signed-off-by: Lyude Paul --- drivers/gpu/drm/nova/gem.rs | 5 +++-- rust/kernel/drm/gem/mod.rs | 17 ++++++++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nova/gem.rs b/drivers/gpu/drm/nova/gem.rs index a3024922f0d90..f2f23320110dd 100644 --- a/drivers/gpu/drm/nova/gem.rs +++ b/drivers/gpu/drm/nova/gem.rs @@ -19,8 +19,9 @@ pub(crate) struct NovaObject {} impl gem::BaseDriverObject for NovaObject { type Driver =3D NovaDriver; type Object =3D gem::Object; + type Args =3D (); =20 - fn new(_dev: &NovaDevice, _size: usize) -> impl PinInit { + fn new(_dev: &NovaDevice, _size: usize, _args: Self::Args) -> impl Pin= Init { try_pin_init!(NovaObject {}) } } @@ -34,7 +35,7 @@ pub(crate) fn new(dev: &NovaDevice, size: usize) -> Resul= t, size: usize) -> impl PinInit; + fn new( + dev: &drm::Device, + size: usize, + args: Self::Args, + ) -> impl PinInit; =20 /// Open a new handle to an existing object, associated with a File. fn open(_obj: &Self::Object, _file: &DriverFile) -> Result { @@ -232,11 +239,15 @@ impl Object { }; =20 /// Create a new GEM object. - pub fn new(dev: &drm::Device, size: usize) -> Result> { + pub fn new( + dev: &drm::Device, + size: usize, + args: T::Args, + ) -> Result> { let obj: Pin> =3D KBox::pin_init( try_pin_init!(Self { obj: Opaque::new(bindings::drm_gem_object::default()), - data <- T::new(dev, size), + data <- T::new(dev, size, args), // INVARIANT: The drm subsystem guarantees that the `struc= t drm_device` will live // as long as the GEM object lives. dev: dev.into(), --=20 2.49.0 From nobody Sun Dec 14 19:31:51 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (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 25B2A2BE0F7 for ; Wed, 21 May 2025 20:48:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860484; cv=none; b=bBgthoLPmio3+BthUMTqIB0780+Hv+372HG75e9hPYU5uoQH5ckT09jXHsy4OfQtzFw1soQ/bVtoxd/2unJXcFP+gqb7JH79nExTQ18MFSCGud8rQdygrNGS0Ro3NpwKS8phnFBeQkauR8uNUpXT6jDUQKJFsV9OMWTfzfTifzU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860484; c=relaxed/simple; bh=bWAGvHQEuhg2kWRsnwranJiiIUeYhq9gJB0Nrnj1CfQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=o3vbF4nOqxme9LqOEeBx/8VaJlNAFueaxJeV2zSrL8ojCPLnR8ig4dCMm3/tVTtS/dKDIG05UuhRHFhMMFo/jaqm0AqZcMufYdK5dJpXnq3A+La7zmPyB7OjEIUHHnDpj6/OTkaHCCXRG39YFIMldS+J0Na6rMvz+dBjluAeaRw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=ZoRT0lTn; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="ZoRT0lTn" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747860482; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=e7RkpFLJnA47LTzwk8o4U9PeS8nU4fCkKj3jasQpFZE=; b=ZoRT0lTn8LvpRa7F9G0dIYzgeu5O4cPds8u3fK/GhILf0em4U2QQa8N2qC+6zphql92M6/ TuW5LRjCUpsvmMUYK/guXgjDO1Z/ZMFAlBnCgrVDwBPQuE4PLcP1SGDWs7mrTU8AuTMamI Bv8660UrlQSNk/sSKa9bPvQyl1jxiTg= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-77-BLGIfQEcP6OcNxgkLVqypg-1; Wed, 21 May 2025 16:47:59 -0400 X-MC-Unique: BLGIfQEcP6OcNxgkLVqypg-1 X-Mimecast-MFC-AGG-ID: BLGIfQEcP6OcNxgkLVqypg_1747860477 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 08BEE19560B1; Wed, 21 May 2025 20:47:57 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.80.100]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 47F9119560B7; Wed, 21 May 2025 20:47:52 +0000 (UTC) From: Lyude Paul To: dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Daniel Almeida , Asahi Lina , Alyssa Rosenzweig Subject: [PATCH v2 06/12] rust: drm: gem: Add OpaqueObject Date: Wed, 21 May 2025 16:29:13 -0400 Message-ID: <20250521204654.1610607-7-lyude@redhat.com> In-Reply-To: <20250521204654.1610607-1-lyude@redhat.com> References: <20250521204654.1610607-1-lyude@redhat.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-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 In the future, we want to have the ability for a driver to have private gem objects - or use gem objects across ffi boundaries that don't use our driver's GEM object implementation. So, let's take some inspiration from the KMS bindings I've been working on and introduce an OpaqueObject type. This type can be used identically to a normal gem object, with the exception that the private-data layout of the object is not known. Signed-off-by: Lyude Paul --- rust/kernel/drm/gem/mod.rs | 61 +++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs index f0029e6989ed6..aeec847b80aa7 100644 --- a/rust/kernel/drm/gem/mod.rs +++ b/rust/kernel/drm/gem/mod.rs @@ -6,13 +6,13 @@ =20 use crate::{ alloc::flags::*, - bindings, drm, + bindings, drm::{self, private::Sealed}, drm::driver::{AllocImpl, AllocOps}, error::{to_result, Result}, prelude::*, types::{ARef, AlwaysRefCounted, Opaque}, }; -use core::{ops::Deref, ptr::NonNull}; +use core::{ops::Deref, ptr::NonNull, marker::PhantomData}; =20 /// A type alias for retrieving a [`Driver`]s [`DriverFile`] implementatio= n from its /// [`DriverObject`] implementation. @@ -21,6 +21,26 @@ /// [`DriverFile`]: drm::file::DriverFile pub type DriverFile =3D drm::File<<::Driver as d= rm::Driver>::File>; =20 +/// A helper macro for implementing AsRef> +macro_rules! impl_as_opaque { + ($type:ty where $tparam:ident : $tparam_trait:ident) =3D> { + impl core::convert::AsRef> for $type + where + D: kernel::drm::driver::Driver, + Self: kernel::drm::gem::BaseDriverObject, + Self: kernel::drm::gem::IntoGEMObject, + $tparam: $tparam_trait + { + fn as_ref(&self) -> &kernel::drm::gem::OpaqueObject { + // SAFETY: This cast is safe via our type invariant. + unsafe { &*((self.as_raw().cast_const()).cast()) } + } + } + }; +} + +pub(crate) use impl_as_opaque; + /// GEM object functions, which must be implemented by drivers. pub trait BaseDriverObject: Sync + Send + Sized { /// Parent `Driver` for this object. @@ -49,7 +69,7 @@ fn close(_obj: &Self::Object, _file: &DriverFile) {} } =20 /// Trait that represents a GEM object subtype -pub trait IntoGEMObject: Sized + super::private::Sealed + AlwaysRefCounted= { +pub trait IntoGEMObject: Sized + Sealed + AlwaysRefCounted { /// Returns a reference to the raw `drm_gem_object` structure, which m= ust be valid as long as /// this owning object is valid. fn as_raw(&self) -> *mut bindings::drm_gem_object; @@ -297,7 +317,7 @@ extern "C" fn free_callback(obj: *mut bindings::drm_gem= _object) { } } =20 -impl super::private::Sealed for Object {} +impl Sealed for Object {} =20 impl Deref for Object { type Target =3D T; @@ -321,6 +341,39 @@ impl AllocImpl for Object { }; } =20 +impl_as_opaque!(Object where T: BaseDriverObject); + +/// A GEM object whose private-data layout is not known. +/// +/// Not all GEM objects are created equal, and subsequently drivers may oc= casionally need to deal +/// with situations where they are working with a GEM object but have no k= nowledge of its +/// private-data layout. +/// +/// It may be used just like a normal [`Object`], with the exception that = it cannot access +/// driver-private data. +/// +/// # Invariant +/// +/// Via `#[repr(transparent)]`, this type is guaranteed to have an identic= al data layout to +/// `struct drm_gem_object`. +#[repr(transparent)] +pub struct OpaqueObject(Opaque, = PhantomData); + +impl IntoGEMObject for OpaqueObject { + unsafe fn as_ref<'a>(self_ptr: *mut bindings::drm_gem_object) -> &'a S= elf { + // SAFETY: + // - This cast is safe via our type invariant. + // - `self_ptr` is guaranteed to be a valid pointer to a gem objec= t by our safety contract. + unsafe { &*self_ptr.cast::().cast_const() } + } + + fn as_raw(&self) -> *mut bindings::drm_gem_object { + self.0.get() + } +} + +impl Sealed for OpaqueObject {} + pub(super) const fn create_fops() -> bindings::file_operations { // SAFETY: As by the type invariant, it is safe to initialize `binding= s::file_operations` // zeroed. --=20 2.49.0 From nobody Sun Dec 14 19:31:51 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (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 63F542BEC39 for ; Wed, 21 May 2025 20:50:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860605; cv=none; b=KHJv91vQGK2ZW4G1g9l5UI0Vj0GC79ehmW+8zkqUVHVVZVTiQXKrRp7XCQinF65NF/I0rgIuidDIgAJw85jpG99H4H0ACuoeaJyVA4hnp8C5KUwOHMAR1/ra1OYoIna90TslgkBcAz69etbc9NYe1rf6rv31fETTUdlRTLgGk/s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860605; c=relaxed/simple; bh=eB/smrwyfKePa2JUmP3TAsM2ZqRpyziTa+2yqMFLxjc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=BEAicds7oGIpymV+QDc0oD+NtFVWUxGUssCIKEUondsn0lu+nJIuykHX/rOFRSf8ziOAb51F58HM4T0sxS04+NQ3kx0+KuuUsrizSlRvGXv6n8zTFCd7RzNuVkp0zbjmakJU5Y7H8QRQNgBtpcxcW5nHnpR6rImPkYiSO06b1Ss= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Ah2nvWwQ; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Ah2nvWwQ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747860602; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=eWPAY86FjVFxJBNFMEUO0kgthARI07yeX7jKuVR/RKc=; b=Ah2nvWwQsNu5M0PZY7zC67/mtRQAT1/8SUayWy9Lop+jnIB4jTjBqnIOMQuxqnLPN1Z1KT lq1wUDF02GeTQEkoNVWoB699ciL6bBPNHd7rms6eWujvkQH1h74buakLx2UeJ/j/rd6Tk5 nncbkClGKvgiYfxfdAHa9KUdNHLWSjQ= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-645-jxV0QQyzNcqwRdmY8KmDAw-1; Wed, 21 May 2025 16:48:12 -0400 X-MC-Unique: jxV0QQyzNcqwRdmY8KmDAw-1 X-Mimecast-MFC-AGG-ID: jxV0QQyzNcqwRdmY8KmDAw_1747860490 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 52587195608F; Wed, 21 May 2025 20:48:09 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.80.100]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7621319560B7; Wed, 21 May 2025 20:48:04 +0000 (UTC) From: Lyude Paul To: dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Asahi Lina , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Greg Kroah-Hartman , Wedson Almeida Filho , Daniel Almeida , Alyssa Rosenzweig Subject: [PATCH v2 07/12] rust: drm: gem: shmem: Add DRM shmem helper abstraction Date: Wed, 21 May 2025 16:29:14 -0400 Message-ID: <20250521204654.1610607-8-lyude@redhat.com> In-Reply-To: <20250521204654.1610607-1-lyude@redhat.com> References: <20250521204654.1610607-1-lyude@redhat.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-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 From: Asahi Lina The DRM shmem helper includes common code useful for drivers which allocate GEM objects as anonymous shmem. Add a Rust abstraction for this. Drivers can choose the raw GEM implementation or the shmem layer, depending on their needs. Signed-off-by: Asahi Lina Signed-off-by: Daniel Almeida Signed-off-by: Lyude Paul --- V2: * Use the drm_gem_shmem_init() and drm_gem_shmem_release() that I extracted so we can handle memory allocation in rust, which means we no longer have to handle freeing rust members of the struct by hand and have a closer implementation to the main gem object (this also gets rid of gem_create_object) * Get rid of GemObjectRef and UniqueGemObjectRef, we have ARef at home. * Use Device in Object * Cleanup Object::::new() a bit: * Cleanup safety comment * Use cast_mut() * Just import container_of!(), we use it all over anyhow * mut_shmem() -> as_shmem(), make it safe (there's no reason for being unsa= fe) * Remove any *const and *muts in structs, just use NonNull * Get rid of the previously hand-rolled sg_table bindings in shmem, use the bindings from Abdiel's sg_table patch series * Add a TODO at the top about DMA reservation APIs and a desire for WwMutex * Get rid of map_wc() and replace it with a new ObjectConfig struct. While it currently only specifies the map_wc flag, the idea here is that settings like map_wc() and parent_resv_obj() shouldn't be exposed as normal functions since the only place where it's safe to set them is when we're still guaranteed unique access to the GEM object, e.g. before returning it to the caller. Using a struct instead of individual arguments here is mainly because we'll be adding at least one more argument, and there's enough other gem shmem settings that trying to add all of them as individual function arguments in the future would be a bit messy. * Get rid of vm_numa_fields!, Lina didn't like this macro much either and I think that it's fine for us to just specify the #[cfg(=E2=80=A6)] attribu= tes by hand since we only need to do it twice. * Set drm_gem_object_funcs.vm_ops directly to drm_gem_shmem_vm_ops, don't export the various shmem funcs. I'm not sure why this wasn't possible before but it seems to work fine now. Signed-off-by: Lyude Paul --- rust/bindings/bindings_helper.h | 3 + rust/helpers/drm.c | 48 ++++- rust/kernel/drm/gem/mod.rs | 2 + rust/kernel/drm/gem/shmem.rs | 338 ++++++++++++++++++++++++++++++++ 4 files changed, 390 insertions(+), 1 deletion(-) create mode 100644 rust/kernel/drm/gem/shmem.rs diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helpe= r.h index 409e9a595e051..3974cb1a252d3 100644 --- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/rust/helpers/drm.c b/rust/helpers/drm.c index 450b406c6f273..a4e997d0b4732 100644 --- a/rust/helpers/drm.c +++ b/rust/helpers/drm.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 =20 #include +#include #include =20 #ifdef CONFIG_DRM @@ -20,4 +21,49 @@ __u64 rust_helper_drm_vma_node_offset_addr(struct drm_vm= a_offset_node *node) return drm_vma_node_offset_addr(node); } =20 -#endif +#ifdef CONFIG_DRM_GEM_SHMEM_HELPER +void rust_helper_drm_gem_shmem_object_free(struct drm_gem_object *obj) +{ + return drm_gem_shmem_object_free(obj); +} + +void rust_helper_drm_gem_shmem_object_print_info(struct drm_printer *p, un= signed int indent, + const struct drm_gem_obj= ect *obj) +{ + drm_gem_shmem_object_print_info(p, indent, obj); +} + +int rust_helper_drm_gem_shmem_object_pin(struct drm_gem_object *obj) +{ + return drm_gem_shmem_object_pin(obj); +} + +void rust_helper_drm_gem_shmem_object_unpin(struct drm_gem_object *obj) +{ + drm_gem_shmem_object_unpin(obj); +} + +struct sg_table *rust_helper_drm_gem_shmem_object_get_sg_table(struct drm_= gem_object *obj) +{ + return drm_gem_shmem_object_get_sg_table(obj); +} + +int rust_helper_drm_gem_shmem_object_vmap(struct drm_gem_object *obj, + struct iosys_map *map) +{ + return drm_gem_shmem_object_vmap(obj, map); +} + +void rust_helper_drm_gem_shmem_object_vunmap(struct drm_gem_object *obj, + struct iosys_map *map) +{ + drm_gem_shmem_object_vunmap(obj, map); +} + +int rust_helper_drm_gem_shmem_object_mmap(struct drm_gem_object *obj, stru= ct vm_area_struct *vma) +{ + return drm_gem_shmem_object_mmap(obj, vma); +} + +#endif /* CONFIG_DRM_GEM_SHMEM_HELPER */ +#endif /* CONFIG_DRM */ diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs index aeec847b80aa7..6d87e75690d2f 100644 --- a/rust/kernel/drm/gem/mod.rs +++ b/rust/kernel/drm/gem/mod.rs @@ -3,6 +3,8 @@ //! DRM GEM API //! //! C header: [`include/linux/drm/drm_gem.h`](srctree/include/linux/drm/dr= m_gem.h) +#[cfg(CONFIG_DRM_GEM_SHMEM_HELPER =3D "y")] +pub mod shmem; =20 use crate::{ alloc::flags::*, diff --git a/rust/kernel/drm/gem/shmem.rs b/rust/kernel/drm/gem/shmem.rs new file mode 100644 index 0000000000000..57ec2538a905e --- /dev/null +++ b/rust/kernel/drm/gem/shmem.rs @@ -0,0 +1,338 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! DRM GEM shmem helper objects +//! +//! C header: [`include/linux/drm/drm_gem_shmem_helper.h`](srctree/include= /linux/drm/drm_gem_shmem_helper.h) + +// TODO: +// - There are a number of spots here that manually acquire/release the DM= A reservation lock using +// dma_resv_(un)lock(). In the future we should add support for ww mutex= , expose a method to +// acquire a reference to the WwMutex, and then use that directly instea= d of the C functions here. + +use crate::{ + drm::{ + device, + driver, + gem, + private::Sealed + }, + error::{from_err_ptr, to_result}, + prelude::*, + types::{ARef, Opaque}, + container_of, + scatterlist, +}; +use core::{ + mem::MaybeUninit, + ops::{Deref, DerefMut}, + ptr::{addr_of_mut, NonNull}, + slice, +}; +use gem::{ + BaseObject, + BaseObjectPrivate, + BaseDriverObject, + OpaqueObject, + IntoGEMObject +}; + +/// A struct for controlling the creation of shmem-backed GEM objects. +/// +/// This is used with [`Object::new()`] to control various properties that= can only be set when +/// initially creating a shmem-backed GEM object. +#[derive(Default)] +pub struct ObjectConfig { + /// Whether to set the write-combine map flag. + pub map_wc: bool, +} + +/// A shmem-backed GEM object. +/// +/// # Invariants +/// +/// The DRM core ensures that `dev` will remain valid for as long as the o= bject. +#[repr(C)] +#[pin_data] +pub struct Object { + #[pin] + obj: Opaque, + dev: NonNull>, + #[pin] + inner: T, +} + +super::impl_as_opaque!(Object where T: BaseDriverObject); + +impl Object { + /// `drm_gem_object_funcs` vtable suitable for GEM shmem objects. + const VTABLE: bindings::drm_gem_object_funcs =3D bindings::drm_gem_obj= ect_funcs { + free: Some(Self::free_callback), + open: Some(super::open_callback::), + close: Some(super::close_callback::), + print_info: Some(bindings::drm_gem_shmem_object_print_info), + export: None, + pin: Some(bindings::drm_gem_shmem_object_pin), + unpin: Some(bindings::drm_gem_shmem_object_unpin), + get_sg_table: Some(bindings::drm_gem_shmem_object_get_sg_table), + vmap: Some(bindings::drm_gem_shmem_object_vmap), + vunmap: Some(bindings::drm_gem_shmem_object_vunmap), + mmap: Some(bindings::drm_gem_shmem_object_mmap), + status: None, + rss: None, + // SAFETY: `drm_gem_shmem_vm_ops` is static const on the C side, s= o immutable references are + // safe here and such references shall be valid forever + vm_ops: unsafe { &bindings::drm_gem_shmem_vm_ops }, + evict: None, + }; + + /// Return a raw pointer to the embedded drm_gem_shmem_object. + fn as_shmem(&self) -> *mut bindings::drm_gem_shmem_object { + self.obj.get() + } + + /// Create a new shmem-backed DRM object of the given size. + /// + /// Additional config options can be specified using `config`. + pub fn new( + dev: &device::Device, + size: usize, + config: ObjectConfig, + args: T::Args, + ) -> Result> { + let new: Pin> =3D KBox::try_pin_init( + try_pin_init!(Self { + obj <- pin_init::zeroed(), + dev: NonNull::from(dev), + inner <- T::new(dev, size, args), + }), + GFP_KERNEL + )?; + + // SAFETY: `obj.as_raw()` is guaranteed to be valid by the initial= ization above. + unsafe { (*new.as_raw()).funcs =3D &Self::VTABLE }; + + // SAFETY: The arguments are all valid via the type invariants. + to_result(unsafe { bindings::drm_gem_shmem_init(dev.as_raw(), new.= as_shmem(), size) })?; + + // SAFETY: We never move out of `self`. + let new =3D KBox::into_raw(unsafe { Pin::into_inner_unchecked(new)= }); + + // SAFETY: We're taking over the owned refcount from `drm_gem_shme= m_init`. + let mut obj =3D unsafe { ARef::from_raw(NonNull::new_unchecked(new= )) }; + + // SAFETY: We have yet to expose this object outside of this funct= ion, so we're guaranteed + // to have exclusive access - thus making this safe to hold a muta= ble reference to. + let shmem =3D unsafe { &mut *obj.as_shmem() }; + shmem.set_map_wc(config.map_wc); + + Ok(obj) + } + + /// Returns the `Device` that owns this GEM object. + pub fn dev(&self) -> &device::Device { + // SAFETY: We are guaranteed that `dev` is valid for as long as th= is object is valid by our + // type invariants + unsafe { self.dev.as_ref() } + } + + extern "C" fn free_callback(obj: *mut bindings::drm_gem_object) { + // SAFETY: + // - DRM always passes a valid gem object here + // - We used drm_gem_shmem_create() in our create_gem_object callb= ack, so we know that + // `obj` is contained within a drm_gem_shmem_object + let this =3D unsafe { container_of!(obj, bindings::drm_gem_shmem_o= bject, base) }; + + // SAFETY: + // - We're in free_callback - so this function is safe to call. + // - We won't be using the gem resources on `this` after this call. + unsafe { bindings::drm_gem_shmem_release(this.cast_mut()) }; + + // SAFETY: + // - We verified above that `obj` is valid, which makes `this` val= id + // - This function is set in AllocOps, so we know that `this` is c= ontained within a + // `Object` + let this =3D unsafe { container_of!(this, Self, obj).cast_mut() }; + + // SAFETY: We're recovering the Kbox<> we created in gem_create_ob= ject() + let _ =3D unsafe { KBox::from_raw(this) }; + } + + /// Creates (if necessary) and returns a scatter-gather table of DMA p= ages for this object. + /// + /// This will pin the object in memory. + pub fn sg_table(&self) -> Result> { + // SAFETY: + // - drm_gem_shmem_get_pages_sgt is thread-safe. + // - drm_gem_shmem_get_pages_sgt returns either a valid pointer to= a scatterlist, or an + // error pointer. + let sgt =3D from_err_ptr(unsafe { bindings::drm_gem_shmem_get_page= s_sgt(self.as_shmem()) })?; + + Ok(SGTable { + // SAFETY: We checked that `sgt` is not an error pointer, so i= t must be a valid pointer + // to a scatterlist. + sgt: NonNull::from(unsafe { scatterlist::SGTable::as_ref(sgt) = }), + // INVARIANT: We take an owned refcount to `self` here, ensuri= ng that `sgt` remains + // valid for as long as this `OwnedSGTable`. + _owner: self.into() + }) + } + + /// Creates and returns a virtual kernel memory mapping for this objec= t. + pub fn vmap(&self) -> Result> { + let mut map: MaybeUninit =3D MaybeUninit::uni= nit(); + + // SAFETY: + // - drm_gem_shmem_vmap can be called with the DMA reservation loc= k held + // - Our ARef is proof that `obj` is safe to deref + to_result(unsafe { + // TODO: see top of file + bindings::dma_resv_lock(self.raw_dma_resv(), core::ptr::null_m= ut()); + let ret =3D bindings::drm_gem_shmem_vmap(self.as_shmem(), map.= as_mut_ptr()); + bindings::dma_resv_unlock(self.raw_dma_resv()); + ret + })?; + + // SAFETY: if drm_gem_shmem_vmap did not fail, map is initialized = now + let map =3D unsafe { map.assume_init() }; + + Ok(VMap { + map, + owner: self.into(), + }) + } +} + +impl Deref for Object { + type Target =3D T; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl DerefMut for Object { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } +} + +impl Sealed for Object {} + +impl gem::IntoGEMObject for Object { + fn as_raw(&self) -> *mut bindings::drm_gem_object { + // SAFETY: Our immutable reference is proof that this is afe to de= reference + unsafe { addr_of_mut!((*self.obj.get()).base) } + } + + unsafe fn as_ref<'a>(obj: *mut bindings::drm_gem_object) -> &'a Object= { + // SAFETY: The safety contract of from_gem_obj() guarantees that `= obj` is contained within + // `Self` + unsafe { + let obj =3D container_of!(obj, bindings::drm_gem_shmem_object,= base); + + &*container_of!(obj, Object, obj) + } + } +} + +impl driver::AllocImpl for Object { + type Driver =3D T::Driver; + + const ALLOC_OPS: driver::AllocOps =3D driver::AllocOps { + gem_create_object: None, + prime_handle_to_fd: None, + prime_fd_to_handle: None, + gem_prime_import: None, + gem_prime_import_sg_table: Some(bindings::drm_gem_shmem_prime_impo= rt_sg_table), + dumb_create: Some(bindings::drm_gem_shmem_dumb_create), + dumb_map_offset: None, + }; +} + +/// A virtual mapping for a shmem-backed GEM object in kernel address spac= e. +pub struct VMap { + map: bindings::iosys_map, + owner: ARef>, +} + +impl VMap { + /// Returns a const raw pointer to the start of the mapping. + pub fn as_ptr(&self) -> *const core::ffi::c_void { + // SAFETY: The shmem helpers always return non-iomem maps + unsafe { self.map.__bindgen_anon_1.vaddr } + } + + /// Returns a mutable raw pointer to the start of the mapping. + pub fn as_mut_ptr(&mut self) -> *mut core::ffi::c_void { + // SAFETY: The shmem helpers always return non-iomem maps + unsafe { self.map.__bindgen_anon_1.vaddr } + } + + /// Returns a byte slice view of the mapping. + pub fn as_slice(&self) -> &[u8] { + // SAFETY: The vmap maps valid memory up to the owner size + unsafe { slice::from_raw_parts(self.as_ptr() as *const u8, self.ow= ner.size()) } + } + + /// Returns mutable a byte slice view of the mapping. + pub fn as_mut_slice(&mut self) -> &mut [u8] { + // SAFETY: The vmap maps valid memory up to the owner size + unsafe { slice::from_raw_parts_mut(self.as_mut_ptr() as *mut u8, s= elf.owner.size()) } + } + + /// Borrows a reference to the object that owns this virtual mapping. + pub fn owner(&self) -> &ARef> { + &self.owner + } +} + +impl Drop for VMap { + fn drop(&mut self) { + // SAFETY: + // - This function is safe to call with the DMA reservation lock h= eld + // - Our `ARef` is proof that the underlying gem object here is in= itialized and thus safe to + // dereference. + unsafe { + let resv =3D self.owner.raw_dma_resv(); + + // TODO: see top of file + bindings::dma_resv_lock(resv, core::ptr::null_mut()); + bindings::drm_gem_shmem_vunmap(self.owner.as_shmem(), &mut sel= f.map); + bindings::dma_resv_unlock(resv); + } + } +} + +/// SAFETY: `iosys_map` objects are safe to send across threads. +unsafe impl Send for VMap {} +/// SAFETY: `iosys_map` objects are safe to send across threads. +unsafe impl Sync for VMap {} + +/// An owned scatter-gather table of DMA address spans for a GEM shmem obj= ect. +/// +/// # Invariants +/// +/// - `sgt` is kept alive by `_owner`, ensuring it remains valid for as lo= ng as `Self`. +/// - `sgt` corresponds to the owned object in `_owner`. +/// - This object is only exposed in situations where we know the underlyi= ng `SGTable` will not be +/// modified for the lifetime of this object. +pub struct OwnedSGTable { + sgt: NonNull, + _owner: ARef>, +} + +// SAFETY: This object is only exposed in situations where we know the und= erlying `SGTable` will not +// be modified for the lifetime of this object. +unsafe impl Send for OwnedSGTable {} +// SAFETY: This object is only exposed in situations where we know the und= erlying `SGTable` will not +// be modified for the lifetime of this object. +unsafe impl Sync for OwnedSGTable {} + +impl Deref for OwnedSGTable { + type Target =3D SGTable; + + fn deref(&self) -> &Self::Target { + // SAFETY: Creating an immutable reference to this is safe via our= type invariants. + unsafe { self.sgt.as_ref() } + } +} --=20 2.49.0 From nobody Sun Dec 14 19:31:51 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (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 B6B962BE115 for ; Wed, 21 May 2025 20:48:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860505; cv=none; b=QNIbrpexH0FQd+T9KkAt0YmWIj1cEEOxZFjdCtZQ/QLk5yLQirjFgBaeFFKgdJcEhKmrt6eAMueA2LwQsW5uYFE7xA0BWD9bki/d0GTlHM+ntbrAg1zX8NutcgWcRrMdnw4xPXNvlouKX3tnMgP4+5AGE7X8+E46TQwJFoQPKsA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860505; c=relaxed/simple; bh=1hLp9YB0dUeupve8c1B71AcVofklKMworlY+n6rCOK0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WgzlZp78NeitmcnjUHev45al0GxWNQnp3t7beCNajNKHbMUHZFXn17CauCx6FxRtpa9rditcMWpw9cA/FTiGiAWwIplpONfIlprHFKaHF0dMwZ1cHAA9tZ22vzeuyoVsyqtLXBGNcXpNaSs35GEmuBC9uX+5VqYIHhdMykkjUKU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=cLQncVSQ; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="cLQncVSQ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747860502; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bc4vl3FfO4NWd/Y8TRWSzMpXYyQRCKKle6LlSMQQ/wk=; b=cLQncVSQSZXDHoEFGIwv5msrZm7bdlQ0ZzrCmXrJoW7+zKY1qhuPn59/7pbvhq4HX/iLpX 5OWMGvmoHKqMEZL1jLyMkow/fSx/W3oOM3pB2bwaKc7EcbV4fJay9DjoRXX18vJLRvbUrc 5E0H8aN6whG1RuuneoteKsF295nvRzk= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-496-ZDoT-cCNMqG29_PosTHevQ-1; Wed, 21 May 2025 16:48:19 -0400 X-MC-Unique: ZDoT-cCNMqG29_PosTHevQ-1 X-Mimecast-MFC-AGG-ID: ZDoT-cCNMqG29_PosTHevQ_1747860496 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 9BF281800447; Wed, 21 May 2025 20:48:16 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.80.100]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5A9A519560B7; Wed, 21 May 2025 20:48:12 +0000 (UTC) From: Lyude Paul To: dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Asahi Lina , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Daniel Almeida Subject: [PATCH v2 08/12] rust: drm: gem: shmem: Add share_dma_resv to ObjectConfig Date: Wed, 21 May 2025 16:29:15 -0400 Message-ID: <20250521204654.1610607-9-lyude@redhat.com> In-Reply-To: <20250521204654.1610607-1-lyude@redhat.com> References: <20250521204654.1610607-1-lyude@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 Content-Type: text/plain; charset="utf-8" From: Asahi Lina Allow a GEM object to share another object's DMA reservation, for use with drm_gpuvm. To keep memory safety, we hold a reference to the GEM object owning the resv, and drop it when the child object is freed. Signed-off-by: Asahi Lina Signed-off-by: Lyude Paul --- rust/kernel/drm/gem/shmem.rs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/rust/kernel/drm/gem/shmem.rs b/rust/kernel/drm/gem/shmem.rs index 57ec2538a905e..c38fca715429e 100644 --- a/rust/kernel/drm/gem/shmem.rs +++ b/rust/kernel/drm/gem/shmem.rs @@ -41,9 +41,14 @@ /// This is used with [`Object::new()`] to control various properties that= can only be set when /// initially creating a shmem-backed GEM object. #[derive(Default)] -pub struct ObjectConfig { +pub struct ObjectConfig<'a, T: BaseDriverObject> { /// Whether to set the write-combine map flag. pub map_wc: bool, + + /// Reuse the DMA reservation from another GEM object. + /// + /// The newly created [`Object`] will hold an owned refcount to `paren= t_resv_obj` if specified. + pub parent_resv_obj: Option<&'a OpaqueObject>, } =20 /// A shmem-backed GEM object. @@ -57,6 +62,8 @@ pub struct Object { #[pin] obj: Opaque, dev: NonNull>, + // Parent object that owns this object's DMA reservation object + parent_resv_obj: Option>>, #[pin] inner: T, } @@ -96,13 +103,14 @@ fn as_shmem(&self) -> *mut bindings::drm_gem_shmem_obj= ect { pub fn new( dev: &device::Device, size: usize, - config: ObjectConfig, + config: ObjectConfig<'_, T>, args: T::Args, ) -> Result> { let new: Pin> =3D KBox::try_pin_init( try_pin_init!(Self { obj <- pin_init::zeroed(), dev: NonNull::from(dev), + parent_resv_obj: config.parent_resv_obj.map(|p| p.into()), inner <- T::new(dev, size, args), }), GFP_KERNEL @@ -118,7 +126,14 @@ pub fn new( let new =3D KBox::into_raw(unsafe { Pin::into_inner_unchecked(new)= }); =20 // SAFETY: We're taking over the owned refcount from `drm_gem_shme= m_init`. - let mut obj =3D unsafe { ARef::from_raw(NonNull::new_unchecked(new= )) }; + let obj =3D unsafe { ARef::from_raw(NonNull::new_unchecked(new)) }; + + // Start filling out values from `config` + if let Some(parent_resv) =3D config.parent_resv_obj { + // SAFETY: We have yet to expose the new gem object outside of= this function, so it is + // safe to modify this field. + unsafe { (*obj.obj.get()).base.resv =3D parent_resv.raw_dma_re= sv() }; + } =20 // SAFETY: We have yet to expose this object outside of this funct= ion, so we're guaranteed // to have exclusive access - thus making this safe to hold a muta= ble reference to. --=20 2.49.0 From nobody Sun Dec 14 19:31:51 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (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 A00D52BEC58 for ; Wed, 21 May 2025 20:48:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860513; cv=none; b=QH+aFZv9eoA7xusB/rDHs9bwMCg9LS0A+V/FaOQvJACvBWy53t5BYl89ffVMgvcPzr4mtiDoXOVWhhkuQmVD4LlEk0r7L6sdHRKSRey0t7fj1ytqf0GfIPsX6urOHFRaj/KodKyvbsnP7Ti/Fc46O64WwdaxlUYfNBt4vhozAAI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860513; c=relaxed/simple; bh=5E4c3+cOe9MfMSRIXJV1QQOv9I46FpcTmGVomGEV9kI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OjsQ4WpqaRLWpiTfGAKku5dJEf7x4HU8mjLtPQl4iru/0gfviBL0MgKbvy2/dE1/lzyYE6Q7cLUE+u3yKObvUXv5V2zvOxTbFSpJ0+rStG1vEdlO9HceamW5RWTQiR659jrS7AIjl4KPUg0TCsbIDYZPn781JZBh9T7dJE0Kmc8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=DTlX0vSk; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="DTlX0vSk" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747860510; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=B07NYKKXvANlIZfpwmKg8iAUTUr0H/iCuFhmRkbUJU8=; b=DTlX0vSk2/tLOZO56N/lrirB9r37fagCAR2O3kIlF9LlOAb4ahFT/u6q3FDZ38wjWrCkmb R9PRXGOGqqL5Vx4DaaiyecDvcF2CHIsr4aWSAtnR5qk53x4IioLcuYFhZerzTFNCHQRz8D L2WAt0dumeTvT0fSJSALYyJPIzitoeI= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-68-YbFIHZ_dMxi94vPwO_OTsw-1; Wed, 21 May 2025 16:48:26 -0400 X-MC-Unique: YbFIHZ_dMxi94vPwO_OTsw-1 X-Mimecast-MFC-AGG-ID: YbFIHZ_dMxi94vPwO_OTsw_1747860503 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A841819560AA; Wed, 21 May 2025 20:48:23 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.80.100]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id A2D601956066; Wed, 21 May 2025 20:48:19 +0000 (UTC) From: Lyude Paul To: dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org Cc: David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Asahi Lina , Daniel Almeida Subject: [PATCH v2 09/12] rust: drm: gem: Introduce OwnedSGTable Date: Wed, 21 May 2025 16:29:16 -0400 Message-ID: <20250521204654.1610607-10-lyude@redhat.com> In-Reply-To: <20250521204654.1610607-1-lyude@redhat.com> References: <20250521204654.1610607-1-lyude@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 Content-Type: text/plain; charset="utf-8" Currently we expose the ability to retrieve an SGTable for an shmem gem object using gem::shmem::Object::::sg_table(). However, this only gives = us a borrowed reference. This being said - retrieving an SGTable is a fallible operation, and as such it's reasonable that a driver may want to hold onto an SGTable for longer then a reference would allow in order to avoid having to deal with fallibility every time they want to access the SGTable. One such driver with this usecase is the Asahi driver. So to support this, let's introduce OwnedSGTable - which both holds a pointer to the SGTable and a reference to its respective GEM object in order to keep the GEM object alive for as long as the OwnedSGTable. The type can be used identically to a normal SGTable. Signed-off-by: Lyude Paul --- rust/kernel/drm/gem/shmem.rs | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/rust/kernel/drm/gem/shmem.rs b/rust/kernel/drm/gem/shmem.rs index c38fca715429e..bff038df93334 100644 --- a/rust/kernel/drm/gem/shmem.rs +++ b/rust/kernel/drm/gem/shmem.rs @@ -20,7 +20,7 @@ prelude::*, types::{ARef, Opaque}, container_of, - scatterlist, + scatterlist::SGTable, }; use core::{ mem::MaybeUninit, @@ -172,23 +172,36 @@ extern "C" fn free_callback(obj: *mut bindings::drm_g= em_object) { let _ =3D unsafe { KBox::from_raw(this) }; } =20 - /// Creates (if necessary) and returns a scatter-gather table of DMA p= ages for this object. + /// Creates (if necessary) and returns an immutable reference to a sca= tter-gather table of DMA + /// pages for this object. /// /// This will pin the object in memory. - pub fn sg_table(&self) -> Result> { + #[inline] + pub fn sg_table(&self) -> Result<&SGTable> { // SAFETY: // - drm_gem_shmem_get_pages_sgt is thread-safe. // - drm_gem_shmem_get_pages_sgt returns either a valid pointer to= a scatterlist, or an // error pointer. let sgt =3D from_err_ptr(unsafe { bindings::drm_gem_shmem_get_page= s_sgt(self.as_shmem()) })?; =20 - Ok(SGTable { - // SAFETY: We checked that `sgt` is not an error pointer, so i= t must be a valid pointer - // to a scatterlist. - sgt: NonNull::from(unsafe { scatterlist::SGTable::as_ref(sgt) = }), + // SAFETY: We checked above that `sgt` is not an error pointer, so= it must be a valid + // pointer to a scatterlist + Ok(unsafe { SGTable::as_ref(sgt) }) + } + + /// Creates (if necessary) and returns an owned scatter-gather table o= f DMA pages for this + /// object. + /// + /// This is the same as [`sg_table`](Self::sg_table), except that it i= nstead returns a + /// [`OwnedSGTable`] which holds a reference to the associated gem obj= ect. + /// + /// This will pin the object in memory. + pub fn owned_sg_table(&self) -> Result> { + Ok(OwnedSGTable { + sgt: self.sg_table()?.into(), // INVARIANT: We take an owned refcount to `self` here, ensuri= ng that `sgt` remains // valid for as long as this `OwnedSGTable`. - _owner: self.into() + _owner: self.into(), }) } =20 --=20 2.49.0 From nobody Sun Dec 14 19:31:51 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (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 730AA2BFC89 for ; Wed, 21 May 2025 20:49:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860544; cv=none; b=bMmchGWuiW3ez2NWQ/pACNHNqOhU3bKfi8ziJiO52YXNRSnN1gBJAWskeaqdOTICWCoN4CQ7adaktJ3YGFfSNAjHMpFzpT1v8N4Glp1NsKdZnuX3KrPHerXOo9mRJLYS+of5kjiAcmxtp/wm/F5fYUSmAcc1cAtwXE/v3iW1DIk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860544; c=relaxed/simple; bh=3xouPFq+QfUA7590BKH5N+mHnFY8gUh31jE6jRZaJS4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TliFY5z+OoT86FVFisPyMPB3TFggv5GIDxquHSKgh3gTsKLIPTx9zBObUYbipm4aJIyjGG+H2RX8Xtu+s8ZdhhNVFsyBV2ghDUe2Cq+orucSYTl2LYJ1fNXg7GlMfVzDnkZFQJHnk87GA1GqBOvPtrS1gfPX0bXbjuCXeUgbzuI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=W/NmyVCp; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="W/NmyVCp" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747860541; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=mD23raNQ8ZbMrMICq/gFGTjyDRhqWnP+hWWFLjdKFbY=; b=W/NmyVCp6JEBWh7ROzlBcjm28f56wrqVXsDXVosGFXIs/y68fHMJPhd7nogl8vSb1+uoMH trg49vqNq6zVfYwKYEClRD1cdsrH13Dvp7AMoIcJlNIbcLuRusjVBHgsLlXl09lpuO9K2m kTJfD9eYd8RrgfWxkZP4kAaIpUS1R/8= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-587-WCuYGeHcPVG1goaQZEv7DA-1; Wed, 21 May 2025 16:48:32 -0400 X-MC-Unique: WCuYGeHcPVG1goaQZEv7DA-1 X-Mimecast-MFC-AGG-ID: WCuYGeHcPVG1goaQZEv7DA_1747860510 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id E94E91955DAB; Wed, 21 May 2025 20:48:29 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.80.100]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id F141F19560B7; Wed, 21 May 2025 20:48:25 +0000 (UTC) From: Lyude Paul To: dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Sumit Semwal , =?UTF-8?q?Christian=20K=C3=B6nig?= , Greg Kroah-Hartman , Wedson Almeida Filho , Xiangfei Ding , linux-media@vger.kernel.org (open list:DMA BUFFER SHARING FRAMEWORK:Keyword:\bdma_(?:buf|fence|resv)\b), linaro-mm-sig@lists.linaro.org (moderated list:DMA BUFFER SHARING FRAMEWORK:Keyword:\bdma_(?:buf|fence|resv)\b) Subject: [PATCH v2 10/12] rust: Add dma_buf stub bindings Date: Wed, 21 May 2025 16:29:17 -0400 Message-ID: <20250521204654.1610607-11-lyude@redhat.com> In-Reply-To: <20250521204654.1610607-1-lyude@redhat.com> References: <20250521204654.1610607-1-lyude@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 Content-Type: text/plain; charset="utf-8" In order to implement the gem export callback, we need a type to represent struct dma_buf. So - this commit introduces a set of stub bindings for dma_buf. These bindings provide a ref-counted DmaBuf object, but don't currently implement any functionality for using the DmaBuf. Signed-off-by: Lyude Paul --- rust/kernel/dma_buf.rs | 39 +++++++++++++++++++++++++++++++++++++++ rust/kernel/lib.rs | 1 + 2 files changed, 40 insertions(+) create mode 100644 rust/kernel/dma_buf.rs diff --git a/rust/kernel/dma_buf.rs b/rust/kernel/dma_buf.rs new file mode 100644 index 0000000000000..318518ff0b28f --- /dev/null +++ b/rust/kernel/dma_buf.rs @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! DMA buffer API +//! +//! C header: [`include/linux/dma-buf.h`](srctree/include/linux/dma-buf.h) + +use bindings; +use kernel::types::*; + +/// A DMA buffer object. +/// +/// # Invariants +/// +/// The data layout of this type is equivalent to that of `struct dma_buf`. +#[repr(transparent)] +pub struct DmaBuf(Opaque); + +// SAFETY: `struct dma_buf` is thread-safe +unsafe impl Send for DmaBuf {} +// SAFETY: `struct dma_buf` is thread-safe +unsafe impl Sync for DmaBuf {} + +impl DmaBuf { + /// Convert from a `*mut bindings::dma_buf` to a [`DmaBuf`]. + /// + /// # Safety + /// + /// The caller guarantees that `self_ptr` points to a valid initialize= d `struct dma_buf` for the + /// duration of the lifetime of `'a`, and promises to not violate rust= 's data aliasing rules + /// using the reference provided by this function. + pub(crate) unsafe fn as_ref<'a>(self_ptr: *mut bindings::dma_buf) -> &= 'a Self { + // SAFETY: Our data layout is equivalent to `dma_buf` . + unsafe { &*self_ptr.cast() } + } + + pub(crate) fn as_raw(&self) -> *mut bindings::dma_buf { + self.0.get() + } +} diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index cbacedfe54434..02d4311bb080c 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -49,6 +49,7 @@ pub mod device_id; pub mod devres; pub mod dma; +pub mod dma_buf; pub mod driver; #[cfg(CONFIG_DRM =3D "y")] pub mod drm; --=20 2.49.0 From nobody Sun Dec 14 19:31:51 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (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 29B102BE7B0 for ; Wed, 21 May 2025 20:48:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860531; cv=none; b=o3JGbVvl+FNPM1Gf3M9XDm+d7fWpT0/kr//pEo9vY2iHTHOWJv/rPzn+HIE60V22JND5/NN2TCKFI1lKqyONiLB/CZ3pBs439Fm2apOQiM0CUEyVv9wQmHu64CGPX8tBMKtVO22oYPV/v5/ZcEkHZl6i0WMw1zk4zjUxU2s5mb0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860531; c=relaxed/simple; bh=Dw0lhtTBS6OW9ZQ2YGyoktsM6mdieP2QrcPR4fqFA6I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tIVL5lYLv0BN4SkU41eCkhIMubxM1loH/uS7Kc/GIXUR5dLXIsn8D+sCPxciT73gjDzN1ILK2qhudDAOkt2BsIlyF2HzLG73aTectYe6gH650dUlx/4BaINro+USaZMdOVgghCvV6XXeoKqvxakIM87UoQva7dKT82gyPk38t+g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=PLjUeNoZ; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="PLjUeNoZ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747860529; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0Xzufaa4aZgtFIYzj8zYYCFRxQVb/zwFe5HxzSZJWxY=; b=PLjUeNoZ+p2BvYEiMaeUiPmOM2xa7Zq7QPZG6/Pel4pOqKRfiyVWxdKSv8Ns35lYYB3Xvi /Kk1S29uF/Ym5Ry0Vigbozb5vitOsMzlmO4Sbdq6LHrLDBXzd6vox7mpYkhZYFXFnGsjOE Lmlq/JlhLDG/7snbVJopQHG9CmRA29k= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-641-cHEFoZDJMu2ztuwO7P5b-Q-1; Wed, 21 May 2025 16:48:45 -0400 X-MC-Unique: cHEFoZDJMu2ztuwO7P5b-Q-1 X-Mimecast-MFC-AGG-ID: cHEFoZDJMu2ztuwO7P5b-Q_1747860520 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A474D180036E; Wed, 21 May 2025 20:48:40 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.80.100]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id AED9F19560B7; Wed, 21 May 2025 20:48:35 +0000 (UTC) From: Lyude Paul To: dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Danilo Krummrich , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Sumit Semwal , =?UTF-8?q?Christian=20K=C3=B6nig?= , Daniel Almeida , Asahi Lina , Alyssa Rosenzweig , nouveau@lists.freedesktop.org (open list:DRM DRIVER FOR NVIDIA GPUS [RUST]), linux-media@vger.kernel.org (open list:DMA BUFFER SHARING FRAMEWORK:Keyword:\bdma_(?:buf|fence|resv)\b), linaro-mm-sig@lists.linaro.org (moderated list:DMA BUFFER SHARING FRAMEWORK:Keyword:\bdma_(?:buf|fence|resv)\b) Subject: [PATCH v2 11/12] rust: drm: gem: Add export() callback Date: Wed, 21 May 2025 16:29:18 -0400 Message-ID: <20250521204654.1610607-12-lyude@redhat.com> In-Reply-To: <20250521204654.1610607-1-lyude@redhat.com> References: <20250521204654.1610607-1-lyude@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 Content-Type: text/plain; charset="utf-8" This introduces an optional export() callback for GEM objects, which is used to implement the drm_gem_object_funcs->export function. Signed-off-by: Lyude Paul --- drivers/gpu/drm/nova/gem.rs | 1 + rust/kernel/drm/gem/mod.rs | 73 +++++++++++++++++++++++++++++++++++- rust/kernel/drm/gem/shmem.rs | 6 ++- 3 files changed, 77 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nova/gem.rs b/drivers/gpu/drm/nova/gem.rs index f2f23320110dd..6cc7a65a50fae 100644 --- a/drivers/gpu/drm/nova/gem.rs +++ b/drivers/gpu/drm/nova/gem.rs @@ -16,6 +16,7 @@ #[pin_data] pub(crate) struct NovaObject {} =20 +#[vtable] impl gem::BaseDriverObject for NovaObject { type Driver =3D NovaDriver; type Object =3D gem::Object; diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs index 6d87e75690d2f..ef697f323e52c 100644 --- a/rust/kernel/drm/gem/mod.rs +++ b/rust/kernel/drm/gem/mod.rs @@ -10,7 +10,8 @@ alloc::flags::*, bindings, drm::{self, private::Sealed}, drm::driver::{AllocImpl, AllocOps}, - error::{to_result, Result}, + dma_buf, + error::{to_result, from_err_ptr, Result}, prelude::*, types::{ARef, AlwaysRefCounted, Opaque}, }; @@ -44,6 +45,7 @@ fn as_ref(&self) -> &kernel::drm::gem::OpaqueObject { pub(crate) use impl_as_opaque; =20 /// GEM object functions, which must be implemented by drivers. +#[vtable] pub trait BaseDriverObject: Sync + Send + Sized { /// Parent `Driver` for this object. type Driver: drm::Driver; @@ -68,6 +70,11 @@ fn open(_obj: &Self::Object, _file: &DriverFile) -= > Result { =20 /// Close a handle to an existing object, associated with a File. fn close(_obj: &Self::Object, _file: &DriverFile) {} + + /// Optional handle for exporting a gem object. + fn export(_obj: &Self::Object, _flags: u32) -> Result> { + unimplemented!() + } } =20 /// Trait that represents a GEM object subtype @@ -137,6 +144,21 @@ extern "C" fn close_callback( T::close(obj, file); } =20 +extern "C" fn export_callback( + raw_obj: *mut bindings::drm_gem_object, + flags: i32, +) -> *mut bindings::dma_buf { + // SAFETY: `export_callback` is specified in the AllocOps structure fo= r `Object`, ensuring + // that `raw_obj` is contained within a `Object`. + let obj =3D unsafe { T::Object::as_ref(raw_obj) }; + + match T::export(obj, flags as _) { + // DRM takes a hold of the reference + Ok(buf) =3D> buf.into_raw(), + Err(e) =3D> e.to_ptr(), + } +} + impl IntoGEMObject for Object { fn as_raw(&self) -> *mut bindings::drm_gem_object { self.obj.get() @@ -247,7 +269,11 @@ impl Object { open: Some(open_callback::), close: Some(close_callback::), print_info: None, - export: None, + export: if T::HAS_EXPORT { + Some(export_callback::) + } else { + None + }, pin: None, unpin: None, get_sg_table: None, @@ -376,6 +402,49 @@ fn as_raw(&self) -> *mut bindings::drm_gem_object { =20 impl Sealed for OpaqueObject {} =20 +/// A [`dma_buf::DmaBuf`] which has been exported from a GEM object. +/// +/// The [`dma_buf::DmaBuf`] will be released when this type is dropped. +/// +/// # Invariants +/// +/// - `self.0` points to a valid initialized [`dma_buf::DmaBuf`] for the l= ifetime of this object. +/// - The GEM object from which this [`dma_buf::DmaBuf`] was exported from= is guaranteed to be of +/// type `T`. +pub struct DmaBuf(NonNull, PhantomData<= T>); + +impl Deref for DmaBuf { + type Target =3D dma_buf::DmaBuf; + + #[inline] + fn deref(&self) -> &Self::Target { + // SAFETY: This pointer is guaranteed to be valid by our type inva= riants. + unsafe { self.0.as_ref() } + } +} + +impl Drop for DmaBuf { + #[inline] + fn drop(&mut self) { + // SAFETY: + // - `dma_buf::DmaBuf` is guaranteed to have an identical layout t= o `struct dma_buf` + // by its type invariants. + // - We hold the last reference to this `DmaBuf`, making it safe t= o destroy. + unsafe { bindings::drm_gem_dmabuf_release(self.0.cast().as_ptr()) } + } +} + +impl DmaBuf { + /// Leak the reference for this [`DmaBuf`] and return a raw pointer to= it. + #[inline] + pub(crate) fn into_raw(self) -> *mut bindings::dma_buf { + let dma_ptr =3D self.as_raw(); + + core::mem::forget(self); + dma_ptr + } +} + pub(super) const fn create_fops() -> bindings::file_operations { // SAFETY: As by the type invariant, it is safe to initialize `binding= s::file_operations` // zeroed. diff --git a/rust/kernel/drm/gem/shmem.rs b/rust/kernel/drm/gem/shmem.rs index bff038df93334..799f15c38cc36 100644 --- a/rust/kernel/drm/gem/shmem.rs +++ b/rust/kernel/drm/gem/shmem.rs @@ -77,7 +77,11 @@ impl Object { open: Some(super::open_callback::), close: Some(super::close_callback::), print_info: Some(bindings::drm_gem_shmem_object_print_info), - export: None, + export: if T::HAS_EXPORT { + Some(super::export_callback::) + } else { + None + }, pin: Some(bindings::drm_gem_shmem_object_pin), unpin: Some(bindings::drm_gem_shmem_object_unpin), get_sg_table: Some(bindings::drm_gem_shmem_object_get_sg_table), --=20 2.49.0 From nobody Sun Dec 14 19:31:51 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (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 243F02BFC67 for ; Wed, 21 May 2025 20:48:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860538; cv=none; b=f8pAwP3GMa3Uiw1v9HGtunnCYocmRtompQYrsKgHhvI0qJNeXmSJYaNfGvNgZ28qyq/CIKmoblVscY2a2rl7eow2bqe0Klho3kuAgDf4Egr59yw01MhEjPYKUDrDlYpn19lKdwRM8FGtEm/x/6zYH0yrr2LO3P4uJHPG0veo6F4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747860538; c=relaxed/simple; bh=NIe2Yj+2RnlxILb9wuK1MskpjvacdpCE0rjM8oanpyw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rL+q+vLhd0ttfwvzzyzVpereCu3db8JMBbYCOchFe+gqsnW/X5+2hEfY3iUn3wQVPH5JkIUZ+2xFFGRU40H8RguMu6tyV2H8rDQ9cPMjK/7eyjH0Ew1wmnqyPxTzHiAOBl6fdhFS0XkBOHnL7ftM+xI7Ge6uyxK5mbnVm0IeAg4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=XU85uqUm; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="XU85uqUm" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747860536; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YfYUdTNb5Gc7ulEphuHVddFPp9Ry0HXZjmcMzmLE0DM=; b=XU85uqUma8eNs79PAKDi+xy6PuesvAuW5sbt5BahfDmKwE4y697fRYOPAl/GP+3FFZ3T5n 9F8UPZEiz3HqHe8FO3IKK1lBYx4BTAmlxZMNAENnXD8zeG0fYCyD5eLxY1PzvpVAhdY6U7 326Lv7tYSeigw84h3U48Lq9knCYtagc= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-634-A5lh2k0lPK6iSSvRo02qvg-1; Wed, 21 May 2025 16:48:51 -0400 X-MC-Unique: A5lh2k0lPK6iSSvRo02qvg-1 X-Mimecast-MFC-AGG-ID: A5lh2k0lPK6iSSvRo02qvg_1747860528 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 92A671800368; Wed, 21 May 2025 20:48:48 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.80.100]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id F37131956066; Wed, 21 May 2025 20:48:43 +0000 (UTC) From: Lyude Paul To: dri-devel@lists.freedesktop.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org Cc: David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Sumit Semwal , =?UTF-8?q?Christian=20K=C3=B6nig?= , Daniel Almeida , Asahi Lina , Alyssa Rosenzweig , linux-media@vger.kernel.org (open list:DMA BUFFER SHARING FRAMEWORK:Keyword:\bdma_(?:buf|fence|resv)\b), linaro-mm-sig@lists.linaro.org (moderated list:DMA BUFFER SHARING FRAMEWORK:Keyword:\bdma_(?:buf|fence|resv)\b) Subject: [PATCH v2 12/12] rust: drm: gem: Add BaseObject::prime_export() Date: Wed, 21 May 2025 16:29:19 -0400 Message-ID: <20250521204654.1610607-13-lyude@redhat.com> In-Reply-To: <20250521204654.1610607-1-lyude@redhat.com> References: <20250521204654.1610607-1-lyude@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 Content-Type: text/plain; charset="utf-8" We just added an export() callback that GEM objects can implement, but without any way of actually exporting a DmaBuf. So let's add one by introducing bindings for drm_gem_prime_export(). Signed-off-by: Lyude Paul --- rust/kernel/drm/gem/mod.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs index ef697f323e52c..ee74b9bdb7a1f 100644 --- a/rust/kernel/drm/gem/mod.rs +++ b/rust/kernel/drm/gem/mod.rs @@ -225,6 +225,29 @@ fn lookup_handle(file: &drm::File, handle:= u32) -> Result Ok(unsafe { ARef::from_raw(obj.into()) }) } =20 + /// Export a [`DmaBuf`] for this GEM object using the DRM prime helper= library. + /// + /// `flags` should be a set of flags from [`fs::file::flags`](kernel::= fs::file::flags). + fn prime_export(&self, flags: u32) -> Result> { + // SAFETY: + // - `as_raw()` always returns a valid pointer to a `drm_gem_objec= t`. + // - `drm_gem_prime_export()` returns either an error pointer, or = a valid pointer to an + // initialized `dma_buf` on success. + let dma_ptr =3D from_err_ptr(unsafe { + bindings::drm_gem_prime_export(self.as_raw(), flags as _) + })?; + + // SAFETY: + // - We checked that dma_ptr is not an error, so it must point to = an initialized dma_buf + // - We used drm_gem_prime_export(), so `dma_ptr` will remain vali= d until a call to + // `drm_gem_prime_release()` which we don't call here. + let dma_buf =3D unsafe { dma_buf::DmaBuf::as_ref(dma_ptr) }; + + // INVARIANT: We used drm_gem_prime_export() to create this dma_bu= f, fulfilling the + // invariant that this dma_buf came from a GEM object of type `Sel= f`. + Ok(DmaBuf(dma_buf.into(), PhantomData)) + } + /// Creates an mmap offset to map the object from userspace. fn create_mmap_offset(&self) -> Result { // SAFETY: The arguments are valid per the type invariant. --=20 2.49.0