From nobody Sat Feb 7 19:04:21 2026 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 1E758202C48 for ; Tue, 13 May 2025 22:11:07 +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=1747174269; cv=none; b=r//cM9H4QSuDT5IHYkzWbbJ6/e4sEk9Bs9vyv5H/wTwK/EQhHlcRtclkuNbidIZDB54Xbk3L9Lk0yDXsnfugT9nzehXu7MaYhVtD3QY8PoHTkgrWJqjIQ593C/956/lZZM5a9UzRatjVpku8JB3jMYXxJTuGt8UbyHAcXvaIov0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747174269; c=relaxed/simple; bh=KoVg+RCs4hMlFuoabocT3S/EpmV31xnUshELhfpKYDk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VKkjz/JH7hYTGIm9R+BxxWQbWj/HnEg33cMLr0YhvCaZ0mM8xcXLx8f4E/Dtbz2SIg1PwSU/m5bwQ4NFXoVYIOTeUXv+7Hrh02Xm7yt2/tQBeTn0WdyGShECDSKG8htud7bxdKv2iClzagR+UPMH+eFZGNwpsAh6wk8R2s0isVg= 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=TCoz4ubg; 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="TCoz4ubg" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747174267; 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=DCw2wvd2m1wTO/RjJyxO6cpVaBvDfLJZ2984Y/kSd2U=; b=TCoz4ubg9WIWLnQw40lEriJkk2IKDuBKRz2ptZp0bbwhYPMEYN6GHg2+VkE3Lq3ioAl66s 6wlEEqFeYpLoK7JtTRAkH2Npu5kE9QMRYBdLASmr0AgcPZVbgYRGfsUK88z16aayjmjr5z 5/T+/aIJXa/bzFJRlDGfWMlGJ6Q1tzY= 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-310-wm0OVJk3O6makUvGSG_Vyg-1; Tue, 13 May 2025 18:11:03 -0400 X-MC-Unique: wm0OVJk3O6makUvGSG_Vyg-1 X-Mimecast-MFC-AGG-ID: wm0OVJk3O6makUvGSG_Vyg_1747174261 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 6859A195DE0B; Tue, 13 May 2025 22:11:00 +0000 (UTC) Received: from chopper.lyude.net (unknown [10.22.64.99]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 577821940E95; Tue, 13 May 2025 22:10:55 +0000 (UTC) From: Lyude Paul To: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org Cc: Daniel Almeida , Danilo Krummrich , 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 , Asahi Lina , Alyssa Rosenzweig Subject: [PATCH v2 1/4] rust: drm: gem: Use NonNull for Object::dev Date: Tue, 13 May 2025 18:09:54 -0400 Message-ID: <20250513221046.903358-2-lyude@redhat.com> In-Reply-To: <20250513221046.903358-1-lyude@redhat.com> References: <20250513221046.903358-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.17 Content-Type: text/plain; charset="utf-8" There is usually not much of a reason to use a raw pointer in a data struct, so move this to NonNull instead. Signed-off-by: Lyude Paul Reviewed-by: Daniel Almeida Reviewed-by: Danilo Krummrich --- rust/kernel/drm/gem/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs index 0cafa4a424206..df8f9fdae5c22 100644 --- a/rust/kernel/drm/gem/mod.rs +++ b/rust/kernel/drm/gem/mod.rs @@ -177,7 +177,7 @@ impl BaseObject for T where Self: crate::types::Alwa= ysRefCounted + IntoGEMObj #[pin_data] pub struct Object { obj: Opaque, - dev: *const drm::Device, + dev: NonNull>, #[pin] data: T, } @@ -212,7 +212,7 @@ pub fn new(dev: &drm::Device, size: usize) -= > Result> { data <- T::new(dev, size), // INVARIANT: The drm subsystem guarantees that the `struc= t drm_device` will live // as long as the GEM object lives. - dev, + dev: dev.into(), }), GFP_KERNEL, )?; @@ -237,7 +237,7 @@ pub fn new(dev: &drm::Device, size: usize) -= > Result> { pub fn dev(&self) -> &drm::Device { // SAFETY: The DRM subsystem guarantees that the `struct drm_devic= e` will live as long as // the GEM object lives, hence the pointer must be valid. - unsafe { &*self.dev } + unsafe { self.dev.as_ref() } } =20 fn as_raw(&self) -> *mut bindings::drm_gem_object { --=20 2.49.0 From nobody Sat Feb 7 19:04:21 2026 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 C059D2066CF for ; Tue, 13 May 2025 22:11:19 +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=1747174281; cv=none; b=ivZBiVbNsLGZK6/cC4XbM/+KkHKmWj5EVzLq1HJF76fRWmZ0rrQ7HHEoO5IVN/+IcHdUrD3/vbcvKUiTM6ikts0xbQjV3RILDdtPmCKzmeJdrrG7KzjyjyD/J8gICWwGBV+LU1fPdghgD1gnYKzu9xHQLrBxMh9bsIMkEFoAPXM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747174281; c=relaxed/simple; bh=7d0VgSPJROTSMaQPGs5A4pTzXg/ZW8CCULSCOL8oGRs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=h8SZtnbUEBTwG2qlWYvKqSSpu71238U5v0YEzCcgsV5W+kPKY906R9rhUKzYu/DGAAe8/dtpkvUIL1/3G2uIOKVWd3FTfadiRp5l0ATULLFTzrDYP3zPsSLG1ehHAgYPJwdAFXnUV9TkGi6RhlvFHg3QWj+8plGv6gExUDNiz7k= 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=GFEDFjgE; 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="GFEDFjgE" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747174278; 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=Tt1JSePFPFuckdQ49k5xhTN6H2hYpcBzjeDUG0vewRk=; b=GFEDFjgEU2lT4RrYJWRRj5FqIKrKAjgYzhqSo/k/+fatfFl/CSZxJw02DOsNdJ1YvrKBG8 s4//LVeBZOwxO4ROl9s8ziL2LaXdo3e7M1q4HBUpegXcCHLL3Ti7fd3Pa2Xvno1hNX1BZH nIwFSfjjJG3wJOABiKVHXFFc0SJpRok= 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-218-p7kry4B1MlGfHFKlsC4WMg-1; Tue, 13 May 2025 18:11:15 -0400 X-MC-Unique: p7kry4B1MlGfHFKlsC4WMg-1 X-Mimecast-MFC-AGG-ID: p7kry4B1MlGfHFKlsC4WMg_1747174269 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 82A9E1800374; Tue, 13 May 2025 22:11:08 +0000 (UTC) Received: from chopper.lyude.net (unknown [10.22.64.99]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 8100C1944A82; Tue, 13 May 2025 22:11:03 +0000 (UTC) From: Lyude Paul To: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org Cc: Daniel Almeida , 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 , Asahi Lina , Alyssa Rosenzweig Subject: [PATCH v2 2/4] rust: drm: gem: Refactor IntoGEMObject::from_gem_obj() to as_ref() Date: Tue, 13 May 2025 18:09:55 -0400 Message-ID: <20250513221046.903358-3-lyude@redhat.com> In-Reply-To: <20250513221046.903358-1-lyude@redhat.com> References: <20250513221046.903358-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.17 Content-Type: text/plain; charset="utf-8" There's a few issues with this function, mainly: * This function -probably- should have been unsafe from the start. Pointers are not always necessarily valid, but you want a function that does field-projection for a pointer that can travel outside of the original struct to be unsafe, at least if I understand properly. * *mut Self is not terribly useful in this context, the majority of uses of from_gem_obj() grab a *mut Self and then immediately convert it into a &'a Self. It also goes against the ffi conventions we've set in the rest of the kernel thus far. * from_gem_obj() also doesn't follow the naming conventions in the rest of the DRM bindings at the moment, as_ref() would be a better name. So, let's: * Make from_gem_obj() unsafe * Convert it to return &'a Self * Rename it to as_ref() * Update all call locations Signed-off-by: Lyude Paul Reviewed-by: Daniel Almeida --- V2: * Apply Danilo's comments in lookup_handle() * Add safety comment from Daniel Signed-off-by: Lyude Paul --- rust/kernel/drm/gem/mod.rs | 69 ++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 26 deletions(-) diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs index df8f9fdae5c22..1ea1f15d8313c 100644 --- a/rust/kernel/drm/gem/mod.rs +++ b/rust/kernel/drm/gem/mod.rs @@ -45,8 +45,14 @@ pub trait IntoGEMObject: Sized + super::private::Sealed { #[allow(clippy::wrong_self_convention)] fn into_gem_obj(&self) -> &Opaque; =20 - /// Converts a pointer to a `struct drm_gem_object` into a pointer to = `Self`. - fn from_gem_obj(obj: *mut bindings::drm_gem_object) -> *mut Self; + /// Converts a pointer to a `struct drm_gem_object` into a reference t= o `Self`. + /// + /// # Safety + /// + /// - `self_ptr` must be a valid pointer to `Self`. + /// - The caller promises that holding the immutable reference returne= d by this function does + /// not violate rust's data aliasing rules and remains valid through= out the lifetime of `'a`. + unsafe fn as_ref<'a>(self_ptr: *mut bindings::drm_gem_object) -> &'a S= elf; } =20 /// Trait which must be implemented by drivers using base GEM objects. @@ -63,14 +69,13 @@ extern "C" fn open_callback, U: = BaseObject>( let file =3D unsafe { drm::File::<<::Driver as drm::Driver>::File>::= as_ref(raw_file) }; - let obj =3D - <<::Driver as drm::Driver>::Object as IntoGEMO= bject>::from_gem_obj( - raw_obj, - ); - - // SAFETY: `from_gem_obj()` returns a valid pointer as long as the typ= e is correct and the - // `raw_obj` we got is valid. - match T::open(unsafe { &*obj }, file) { + // SAFETY: `open_callback` is specified in the AllocOps structure for = `Object`, ensuring that + // `raw_obj` is indeed contained within a `Object`. + let obj =3D unsafe { + <<::Driver as drm::Driver>::Object as IntoGEMO= bject>::as_ref(raw_obj) + }; + + match T::open(obj, file) { Err(e) =3D> e.to_errno(), Ok(()) =3D> 0, } @@ -84,14 +89,13 @@ extern "C" fn close_callback, U:= BaseObject>( let file =3D unsafe { drm::File::<<::Driver as drm::Driver>::File>::= as_ref(raw_file) }; - let obj =3D - <<::Driver as drm::Driver>::Object as IntoGEMO= bject>::from_gem_obj( - raw_obj, - ); - - // SAFETY: `from_gem_obj()` returns a valid pointer as long as the typ= e is correct and the - // `raw_obj` we got is valid. - T::close(unsafe { &*obj }, file); + // SAFETY: `close_callback` is specified in the AllocOps structure for= `Object`, ensuring + // that `raw_obj` is indeed contained within a `Object`. + let obj =3D unsafe { + <<::Driver as drm::Driver>::Object as IntoGEMO= bject>::as_ref(raw_obj) + }; + + T::close(obj, file); } =20 impl IntoGEMObject for Object { @@ -101,9 +105,10 @@ fn into_gem_obj(&self) -> &Opaque { &self.obj } =20 - fn from_gem_obj(obj: *mut bindings::drm_gem_object) -> *mut Self { - // SAFETY: All of our objects are Object. - unsafe { crate::container_of!(obj, Object, obj).cast_mut() } + unsafe fn as_ref<'a>(self_ptr: *mut bindings::drm_gem_object) -> &'a S= elf { + // SAFETY: `obj` is guaranteed to be in an `Object` via the saf= ety contract of this + // function + unsafe { &*crate::container_of!(self_ptr, Object, obj) } } } =20 @@ -144,11 +149,23 @@ fn lookup_handle( ) -> Result> { // SAFETY: The arguments are all valid per the type invariants. let ptr =3D unsafe { bindings::drm_gem_object_lookup(file.as_raw()= .cast(), handle) }; - let ptr =3D ::from_gem_obj(ptr); - let ptr =3D NonNull::new(ptr).ok_or(ENOENT)?; - - // SAFETY: We take ownership of the reference of `drm_gem_object_l= ookup()`. - Ok(unsafe { ARef::from_raw(ptr) }) + if ptr.is_null() { + return Err(ENOENT); + } + + // SAFETY: + // - A `drm::Driver` can only have a single `File` implementation. + // - `file` uses the same `drm::Driver` as `Self`. + // - Therefore, we're guaranteed that `ptr` must be a gem object e= mbedded within `Self`. + // - And we check if the pointer is null befoe calling as_ref(), e= nsuring that `ptr` is a + // valid pointer to an initialized `Self`. + let obj =3D unsafe { Self::as_ref(ptr) }; + + // SAFETY: + // - We take ownership of the reference of `drm_gem_object_lookup(= )`. + // - Our `NonNull` comes from an immutable reference, thus ensurin= g it is a valid pointer to + // `Self`. + Ok(unsafe { ARef::from_raw(obj.into()) }) } =20 /// Creates an mmap offset to map the object from userspace. --=20 2.49.0 From nobody Sat Feb 7 19:04:21 2026 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 005E120C009 for ; Tue, 13 May 2025 22:11:22 +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=1747174284; cv=none; b=hEQjhph4HCruEcr9POsjxBE3mF0d7AUoEtTJ5F4XWBECU3Ha81OCXhY/SSkMfJhbm0U80ZctlM43fdxZqYJHx0WKYanA/PgARYM9pep/KOayBvqLAgi2uVbWtVM7vb2LgF8T2eo4w6kTwHKd3LEZpOTN1hPLYPj3MZD7BdGoBxE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747174284; c=relaxed/simple; bh=snAJJ4dqpLVI5y1ozRwgddYi9+s23TmxoUqv5KcTbrw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ILP4JWqECV/esp/+B4y/PKr/fpRwG87SNK46axeK+G1wlLRNi85Rkh3DHEj3tjW6WHI6jCnWtyFbTfniOWhA+SKQ32B/gy42qH76QP9wjTLZNvZr3jucqCM1A0xe6XAbtbCmgqseJKh4a0KuCu6cqGn7bXvTQjKoe/veXY7I4xs= 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=ba/vdOEP; 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="ba/vdOEP" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747174281; 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=+eRdN+ZheJAEz/HIzsmMzXqUM9+/iVZmHsdLdFswD3U=; b=ba/vdOEPJBd8xTy+LrBp+h2luo+yf5JjYnOZf2+wwik2k/b9U0TKwcon4+/hmWHhQXS2b5 qrHpxRoH2SuJW4hXu2qvp8jgsA9UZzQEC3ELqsntHSzYCm1bjz8L3ToPANAtZUWKmu1fUK l8XZreV2Gw9SN/TqK8jBNPACyxHoRtY= 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-647-lmH3wHABP0iRzkoMnM7q2w-1; Tue, 13 May 2025 18:11:19 -0400 X-MC-Unique: lmH3wHABP0iRzkoMnM7q2w-1 X-Mimecast-MFC-AGG-ID: lmH3wHABP0iRzkoMnM7q2w_1747174277 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 354891955BF2; Tue, 13 May 2025 22:11:16 +0000 (UTC) Received: from chopper.lyude.net (unknown [10.22.64.99]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id C52021944A82; Tue, 13 May 2025 22:11:11 +0000 (UTC) From: Lyude Paul To: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org Cc: Daniel Almeida , 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 , Alyssa Rosenzweig , Asahi Lina Subject: [PATCH v2 3/4] rust: drm: gem: s/into_gem_obj()/as_raw()/ Date: Tue, 13 May 2025 18:09:56 -0400 Message-ID: <20250513221046.903358-4-lyude@redhat.com> In-Reply-To: <20250513221046.903358-1-lyude@redhat.com> References: <20250513221046.903358-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.17 Content-Type: text/plain; charset="utf-8" There's a few changes here: * The rename, of course (this should also let us drop the clippy annotation here) * Return *mut bindings::drm_gem_object instead of &Opaque - the latter doesn't really have any benefit and just results in conversion from the rust type to the C type having to be more verbose than necessary. Signed-off-by: Lyude Paul Reviewed-by: Daniel Almeida Reviewed-by: Danilo Krummrich --- V2: Rename to as_raw() Signed-off-by: Lyude Paul --- rust/kernel/drm/gem/mod.rs | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs index 1ea1f15d8313c..fa293c08f431d 100644 --- a/rust/kernel/drm/gem/mod.rs +++ b/rust/kernel/drm/gem/mod.rs @@ -12,7 +12,7 @@ prelude::*, types::{ARef, Opaque}, }; -use core::{mem, ops::Deref, ptr, ptr::NonNull}; +use core::{mem, ops::Deref, ptr::NonNull}; =20 /// GEM object functions, which must be implemented by drivers. pub trait BaseDriverObject: Sync + Send + Sized { @@ -42,8 +42,7 @@ pub trait IntoGEMObject: Sized + super::private::Sealed { =20 /// Returns a reference to the raw `drm_gem_object` structure, which m= ust be valid as long as /// this owning object is valid. - #[allow(clippy::wrong_self_convention)] - fn into_gem_obj(&self) -> &Opaque; + fn as_raw(&self) -> *mut bindings::drm_gem_object; =20 /// Converts a pointer to a `struct drm_gem_object` into a reference t= o `Self`. /// @@ -101,8 +100,8 @@ extern "C" fn close_callback, U:= BaseObject>( impl IntoGEMObject for Object { type Driver =3D T::Driver; =20 - fn into_gem_obj(&self) -> &Opaque { - &self.obj + fn as_raw(&self) -> *mut bindings::drm_gem_object { + self.obj.get() } =20 unsafe fn as_ref<'a>(self_ptr: *mut bindings::drm_gem_object) -> &'a S= elf { @@ -121,7 +120,7 @@ pub trait BaseObject fn size(&self) -> usize { // SAFETY: `self.into_gem_obj()` is guaranteed to be a pointer to = a valid `struct // drm_gem_object`. - unsafe { (*self.into_gem_obj().get()).size } + unsafe { (*self.as_raw()).size } } =20 /// Creates a new handle for the object associated with a given `File` @@ -133,11 +132,7 @@ fn create_handle( let mut handle: u32 =3D 0; // SAFETY: The arguments are all valid per the type invariants. to_result(unsafe { - bindings::drm_gem_handle_create( - file.as_raw().cast(), - self.into_gem_obj().get(), - &mut handle, - ) + bindings::drm_gem_handle_create(file.as_raw().cast(), self.as_= raw(), &mut handle) })?; Ok(handle) } @@ -171,14 +166,10 @@ fn lookup_handle( /// 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. - to_result(unsafe { bindings::drm_gem_create_mmap_offset(self.into_= gem_obj().get()) })?; + to_result(unsafe { bindings::drm_gem_create_mmap_offset(self.as_ra= w()) })?; =20 // SAFETY: The arguments are valid per the type invariant. - Ok(unsafe { - bindings::drm_vma_node_offset_addr(ptr::addr_of_mut!( - (*self.into_gem_obj().get()).vma_node - )) - }) + Ok(unsafe { bindings::drm_vma_node_offset_addr(&raw mut (*self.as_= raw()).vma_node) }) } } =20 --=20 2.49.0 From nobody Sat Feb 7 19:04:21 2026 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 6D72E21129C for ; Tue, 13 May 2025 22:11:31 +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=1747174293; cv=none; b=Qfe3NijcqDo1YoI/yhMb4hcIQ5oejPFjUI6Ls1zSy0qs8NuJ+w1vJD2x/3tN4zZ0ysePuG1cuThkl+g8rQK5haMjdleRzkj+Ho7ztM/bZD8DBaqmr4uB4Z39t7F583rZE1QOItNoh4os2InARBadRGZmitxg65k7MJuToHuaGZA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747174293; c=relaxed/simple; bh=U1MawUGWBcgYAEhGFc1+n/mR3HcYKhPFm9YsxAJy/+c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PJoCaoOzrNI0s9ezGQRLTjVDcaqcXekZM8X5z5NLcNgAcNJGCoLBE+LyHjh8ryIS4UT7msy4FRGHsj/lywetJ1eDks2M3QXgYStRL5iSaakv836LLRbPjqhBU+4uMH8LEp+VzqQ3sbNJ73Lk8rSn6i39aOcsn/7isKnc2iyNWu4= 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=CXkNVFyy; 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="CXkNVFyy" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1747174290; 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=qYpgcS7RnRGZH3+H9PW9GmynVyhw2nSeHj3h6xR1Dao=; b=CXkNVFyyUzl2dAe8OcB8ZgYu7enSyl98mwWG3W2ST3qto1x6CmGysIIHAvvDRELWg9zBTq rYpuD0fBaRtakdIkD9e2fFV7nCFbK/H/057D6dPtUwC+ZHcZGA4oZIkwsdKLfQUITnG+mm ZjtgcEH5wNyNLDusSiXawNnV8j6m/kk= 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-15-KpYSB-q-Md-OvwAxl0nexQ-1; Tue, 13 May 2025 18:11:26 -0400 X-MC-Unique: KpYSB-q-Md-OvwAxl0nexQ-1 X-Mimecast-MFC-AGG-ID: KpYSB-q-Md-OvwAxl0nexQ_1747174283 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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 9ABA7180036F; Tue, 13 May 2025 22:11:23 +0000 (UTC) Received: from chopper.lyude.net (unknown [10.22.64.99]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 3FDA61944A82; Tue, 13 May 2025 22:11:19 +0000 (UTC) From: Lyude Paul To: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org Cc: Danilo Krummrich , Daniel Almeida , 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 , Asahi Lina , Alyssa Rosenzweig Subject: [PATCH v2 4/4] rust: drm: gem: Implement AlwaysRefCounted for all gem objects automatically Date: Tue, 13 May 2025 18:09:57 -0400 Message-ID: <20250513221046.903358-5-lyude@redhat.com> In-Reply-To: <20250513221046.903358-1-lyude@redhat.com> References: <20250513221046.903358-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.17 Content-Type: text/plain; charset="utf-8" Currently we are requiring AlwaysRefCounted in most trait bounds for gem objects, and implementing it by hand for our only current type of gem object. However, all gem objects use the same functions for reference counting - and all gem objects support reference counting. We're planning on adding support for shmem gem objects, let's move this around a bit by instead making IntoGEMObject require AlwaysRefCounted as a trait bound, and then provide a blanket AlwaysRefCounted implementation for any object that implements IntoGEMObject so all gem object types can use the same AlwaysRefCounted implementation. This also makes things less verbose by making the AlwaysRefCounted trait bound implicit for any IntoGEMObject bound. Signed-off-by: Lyude Paul Reviewed-by: Danilo Krummrich Reviewed-by: Daniel Almeida --- rust/kernel/drm/gem/mod.rs | 47 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs index fa293c08f431d..e920c7a7edb21 100644 --- a/rust/kernel/drm/gem/mod.rs +++ b/rust/kernel/drm/gem/mod.rs @@ -10,7 +10,7 @@ drm::driver::{AllocImpl, AllocOps}, error::{to_result, Result}, prelude::*, - types::{ARef, Opaque}, + types::{ARef, AlwaysRefCounted, Opaque}, }; use core::{mem, ops::Deref, ptr::NonNull}; =20 @@ -36,7 +36,7 @@ fn close( } =20 /// Trait that represents a GEM object subtype -pub trait IntoGEMObject: Sized + super::private::Sealed { +pub trait IntoGEMObject: Sized + super::private::Sealed + AlwaysRefCounted= { /// Owning driver for this type type Driver: drm::Driver; =20 @@ -54,6 +54,26 @@ pub trait IntoGEMObject: Sized + super::private::Sealed { unsafe fn as_ref<'a>(self_ptr: *mut bindings::drm_gem_object) -> &'a S= elf; } =20 +// SAFETY: All gem objects are refcounted. +unsafe impl AlwaysRefCounted for T { + fn inc_ref(&self) { + // SAFETY: The existence of a shared reference guarantees that the= refcount is non-zero. + unsafe { bindings::drm_gem_object_get(self.as_raw()) }; + } + + unsafe fn dec_ref(obj: NonNull) { + // SAFETY: We either hold the only refcount on `obj`, or one of ma= ny - meaning that no one + // else could possibly hold a mutable reference to `obj` and thus = this immutable reference + // is safe. + let obj =3D unsafe { obj.as_ref() }.as_raw(); + + // SAFETY: + // - The safety requirements guarantee that the refcount is non-ze= ro. + // - We hold no references to `obj` now, making it safe for us to = potentially deallocate it. + unsafe { bindings::drm_gem_object_put(obj) }; + } +} + /// Trait which must be implemented by drivers using base GEM objects. pub trait DriverObject: BaseDriverObject> { /// Parent `Driver` for this object. @@ -112,10 +132,7 @@ unsafe fn as_ref<'a>(self_ptr: *mut bindings::drm_gem_= object) -> &'a Self { } =20 /// Base operations shared by all GEM object classes -pub trait BaseObject -where - Self: crate::types::AlwaysRefCounted + IntoGEMObject, -{ +pub trait BaseObject: IntoGEMObject { /// Returns the size of the object in bytes. fn size(&self) -> usize { // SAFETY: `self.into_gem_obj()` is guaranteed to be a pointer to = a valid `struct @@ -173,7 +190,7 @@ fn create_mmap_offset(&self) -> Result { } } =20 -impl BaseObject for T where Self: crate::types::AlwaysRefCounted + Into= GEMObject {} +impl BaseObject for T {} =20 /// A base GEM object. /// @@ -267,22 +284,6 @@ extern "C" fn free_callback(obj: *mut bindings::drm_ge= m_object) { } } =20 -// SAFETY: Instances of `Object` are always reference-counted. -unsafe impl crate::types::AlwaysRefCounted for Object { - fn inc_ref(&self) { - // SAFETY: The existence of a shared reference guarantees that the= refcount is non-zero. - unsafe { bindings::drm_gem_object_get(self.as_raw()) }; - } - - unsafe fn dec_ref(obj: NonNull) { - // SAFETY: `obj` is a valid pointer to an `Object`. - let obj =3D unsafe { obj.as_ref() }; - - // SAFETY: The safety requirements guarantee that the refcount is = non-zero. - unsafe { bindings::drm_gem_object_put(obj.as_raw()) } - } -} - impl super::private::Sealed for Object {} =20 impl Deref for Object { --=20 2.49.0