From mboxrd@z Thu Jan 1 00:00:00 1970 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 A24B62C1597 for ; Fri, 29 Aug 2025 22:42: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=1756507329; cv=none; b=kjei/wDqhkXTAE7cW4Z54kYychEo1UJaKIt0Sah0Dml/Bbw+pqOheCVaq0JHXyWRqHRtxzx4vNLRZ75LCxh9APWZK9bkpQoglNzhSM9miXcsdmCALFDfcZh/vkwtxI5jNlptj1kGBk8qjzvyDZkCdv31NMwhkTDraGZx88VbGSc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756507329; c=relaxed/simple; bh=mUwK/xsFfwuzsq3kyWVjdRlk2pq182o2/gqikyETILc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=apnXIjIXFmpdD6lvLF2e1+DI2OmnUlhuhaVW8WVOUW4ufJJQh3XHWM/bSWWlqds52fbxdrnJlLzXKDLe9Xmvgjd8862uMHrzQknnto4Inir/JPnWwgGpRnr1lYtoIz8bc99w25w020b1s2BT5Vds7e04+yWrUo9UNK2l2eraeR4= 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=OVJTP2XK; 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="OVJTP2XK" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1756507326; 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=cr7Z5SnqFnSoE6cxmV2l32qPVo05acQnlSmqa8BLLuw=; b=OVJTP2XKam3cZ9KXX6aBLDm4+gl2YPQUq0wYFfegQDgLHmEJoym4beVOUVGjQXblotVlFN FR/gENn1nyS9meEt/3dpC0WQkSJmlZtQZoxwAkAmsEgZ2hTiOCJEZo4l/L3cBHHsrost8R 7sgbSihThTQzjceYGtXMj0UcGli30C8= 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-114-IJgjwKlTMvOBSB8COVyeAw-1; Fri, 29 Aug 2025 18:42:02 -0400 X-MC-Unique: IJgjwKlTMvOBSB8COVyeAw-1 X-Mimecast-MFC-AGG-ID: IJgjwKlTMvOBSB8COVyeAw_1756507319 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (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 19F231800451; Fri, 29 Aug 2025 22:41:59 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.80.78]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id A091518003FC; Fri, 29 Aug 2025 22:41:54 +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 , nouveau@lists.freedesktop.org (open list:DRM DRIVER FOR NVIDIA GPUS [RUST]) Subject: [PATCH v3 04/14] rust: drm: gem: Support driver-private GEM object types Date: Fri, 29 Aug 2025 18:35:19 -0400 Message-ID: <20250829224116.477990-5-lyude@redhat.com> In-Reply-To: <20250829224116.477990-1-lyude@redhat.com> References: <20250829224116.477990-1-lyude@redhat.com> Precedence: bulk X-Mailing-List: rust-for-linux@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 One of the original intents with the gem bindings was that drivers could specify additional gem implementations, in order to enable for driver private gem objects. This wasn't really possible however, as up until now our GEM bindings have always assumed that the only GEM object we would run into was driver::Driver::Object - meaning that implementing another GEM object type would result in all of the BaseDriverObject callbacks assuming the wrong type. This is a pretty easy fix though, all we need to do is specify a BaseDriverObject in driver::Driver instead of an AllocImpl, and then add an associated type for AllocImpl in BaseDriverObject. That way each BaseDriverObject has its own AllocImpl allowing it to know which type to provide in BaseDriverObject callbacks, and driver::Driver can simply go through the BaseDriverObject to its AllocImpl type in order to get access to ALLOC_OPS. So, let's do this and update Nova for these changes. Signed-off-by: Lyude Paul --- V4: * Update trait bounds. This looks gnarlier then it is: Self: AllocImpl, <-- Get the driver for this GEM object D: drm::Driver, <-- Get the driver's Object, File impl F: drm::file::DriverFile, O: BaseDriverObject, <-- Make sure we're the driver's main GEM object impl. (don't worry, the compiler can always figure out what D, F, O are) * Also, rename the commit. I realized I should be clearer about what this does so people can stop me if this isn't what was meant by private gem object implementations :). Signed-off-by: Lyude Paul --- drivers/gpu/drm/nova/driver.rs | 8 ++++++-- drivers/gpu/drm/nova/gem.rs | 1 + rust/kernel/drm/device.rs | 17 ++++++++++------- rust/kernel/drm/driver.rs | 2 +- rust/kernel/drm/gem/mod.rs | 21 +++++++++++++-------- 5 files changed, 31 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/nova/driver.rs b/drivers/gpu/drm/nova/driver.rs index 91b7380f83ab4..4c252426056c5 100644 --- a/drivers/gpu/drm/nova/driver.rs +++ b/drivers/gpu/drm/nova/driver.rs @@ -1,7 +1,11 @@ // SPDX-License-Identifier: GPL-2.0 use kernel::{ - auxiliary, c_str, device::Core, drm, drm::gem, drm::ioctl, prelude::*, sync::aref::ARef, + auxiliary, c_str, + device::Core, + drm::{self, gem, ioctl}, + prelude::*, + types::ARef, }; use crate::file::File; @@ -59,7 +63,7 @@ fn probe(adev: &auxiliary::Device, _info: &Self::IdInfo) -> Result; + type Object = NovaObject; const INFO: drm::DriverInfo = INFO; diff --git a/drivers/gpu/drm/nova/gem.rs b/drivers/gpu/drm/nova/gem.rs index 2760ba4f3450b..10e3053f1a246 100644 --- a/drivers/gpu/drm/nova/gem.rs +++ b/drivers/gpu/drm/nova/gem.rs @@ -18,6 +18,7 @@ pub(crate) struct NovaObject {} impl gem::DriverObject for NovaObject { type Driver = NovaDriver; + type Object = gem::Object; fn new(_dev: &NovaDevice, _size: usize) -> impl PinInit { try_pin_init!(NovaObject {}) diff --git a/rust/kernel/drm/device.rs b/rust/kernel/drm/device.rs index 3bb7c83966cf2..16cf6cb53d9a7 100644 --- a/rust/kernel/drm/device.rs +++ b/rust/kernel/drm/device.rs @@ -60,6 +60,9 @@ pub struct Device { data: T::Data, } +/// A type alias for referring to the [`AllocImpl`] implementation for a DRM driver. +type DriverAllocImpl = <::Object as drm::gem::DriverObject>::Object; + impl Device { const VTABLE: bindings::drm_driver = drm_legacy_fields! { load: None, @@ -70,13 +73,13 @@ impl Device { master_set: None, master_drop: None, debugfs_init: None, - gem_create_object: T::Object::ALLOC_OPS.gem_create_object, - prime_handle_to_fd: T::Object::ALLOC_OPS.prime_handle_to_fd, - prime_fd_to_handle: T::Object::ALLOC_OPS.prime_fd_to_handle, - gem_prime_import: T::Object::ALLOC_OPS.gem_prime_import, - gem_prime_import_sg_table: T::Object::ALLOC_OPS.gem_prime_import_sg_table, - dumb_create: T::Object::ALLOC_OPS.dumb_create, - dumb_map_offset: T::Object::ALLOC_OPS.dumb_map_offset, + gem_create_object: DriverAllocImpl::::ALLOC_OPS.gem_create_object, + prime_handle_to_fd: DriverAllocImpl::::ALLOC_OPS.prime_handle_to_fd, + prime_fd_to_handle: DriverAllocImpl::::ALLOC_OPS.prime_fd_to_handle, + gem_prime_import: DriverAllocImpl::::ALLOC_OPS.gem_prime_import, + gem_prime_import_sg_table: DriverAllocImpl::::ALLOC_OPS.gem_prime_import_sg_table, + dumb_create: DriverAllocImpl::::ALLOC_OPS.dumb_create, + dumb_map_offset: DriverAllocImpl::::ALLOC_OPS.dumb_map_offset, show_fdinfo: None, fbdev_probe: None, diff --git a/rust/kernel/drm/driver.rs b/rust/kernel/drm/driver.rs index dae0f4d1bbe3c..2500a61f45a6a 100644 --- a/rust/kernel/drm/driver.rs +++ b/rust/kernel/drm/driver.rs @@ -103,7 +103,7 @@ pub trait Driver { type Data: Sync + Send; /// The type used to manage memory for this driver. - type Object: AllocImpl; + type Object: drm::gem::DriverObject; /// The type used to represent a DRM File (client) type File: drm::file::DriverFile; diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs index b27b9fbf28bbb..ec36cd9ea69ed 100644 --- a/rust/kernel/drm/gem/mod.rs +++ b/rust/kernel/drm/gem/mod.rs @@ -26,16 +26,19 @@ pub trait DriverObject: Sync + Send + Sized { /// Parent `Driver` for this object. type Driver: drm::Driver; + /// The GEM object type that will be passed to various callbacks. + type Object: AllocImpl; + /// Create a new driver data object for a GEM object of a given size. fn new(dev: &drm::Device, size: usize) -> impl PinInit; /// Open a new handle to an existing object, associated with a File. - fn open(_obj: &::Object, _file: &DriverFile) -> Result { + fn open(_obj: &Self::Object, _file: &DriverFile) -> Result { Ok(()) } /// Close a handle to an existing object, associated with a File. - fn close(_obj: &::Object, _file: &DriverFile) {} + fn close(_obj: &Self::Object, _file: &DriverFile) {} } /// Trait that represents a GEM object subtype @@ -83,7 +86,7 @@ extern "C" fn open_callback( // SAFETY: `open_callback` is specified in the AllocOps structure for `DriverObject`, // ensuring that `raw_obj` is contained within a `DriverObject` - let obj = unsafe { <::Object as IntoGEMObject>::from_raw(raw_obj) }; + let obj = unsafe { T::Object::from_raw(raw_obj) }; match T::open(obj, file) { Err(e) => e.to_errno(), @@ -100,7 +103,7 @@ extern "C" fn close_callback( // SAFETY: `close_callback` is specified in the AllocOps structure for `Object`, ensuring // that `raw_obj` is indeed contained within a `Object`. - let obj = unsafe { <::Object as IntoGEMObject>::from_raw(raw_obj) }; + let obj = unsafe { T::Object::from_raw(raw_obj) }; T::close(obj, file); } @@ -127,11 +130,12 @@ fn size(&self) -> usize { /// Creates a new handle for the object associated with a given `File` /// (or returns an existing one). - fn create_handle(&self, file: &drm::File) -> Result + fn create_handle(&self, file: &drm::File) -> Result where Self: AllocImpl, - D: drm::Driver, + D: drm::Driver, F: drm::file::DriverFile, + O: DriverObject, { let mut handle: u32 = 0; // SAFETY: The arguments are all valid per the type invariants. @@ -142,11 +146,12 @@ fn create_handle(&self, file: &drm::File) -> Result } /// Looks up an object by its handle for a given `File`. - fn lookup_handle(file: &drm::File, handle: u32) -> Result> + fn lookup_handle(file: &drm::File, handle: u32) -> Result> where Self: AllocImpl, - D: drm::Driver, + D: drm::Driver, F: drm::file::DriverFile, + O: DriverObject, { // SAFETY: The arguments are all valid per the type invariants. let ptr = unsafe { bindings::drm_gem_object_lookup(file.as_raw().cast(), handle) }; -- 2.50.0