From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BF0BCFD0057 for ; Sun, 1 Mar 2026 12:06:46 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D75B110E134; Sun, 1 Mar 2026 12:06:45 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="NqklyLxB"; dkim-atps=neutral Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) by gabe.freedesktop.org (Postfix) with ESMTPS id F322010E134 for ; Sun, 1 Mar 2026 12:06:44 +0000 (UTC) Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-4837b7903f3so45612205e9.2 for ; Sun, 01 Mar 2026 04:06:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1772366803; x=1772971603; darn=lists.freedesktop.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=+NLDKguPnGJnQnFRD4unNG+va9+3jiMJbYExTIJsz8s=; b=NqklyLxB7xivXM3TrTIniF0T0d5UwgXfXJRak0YNkXrOmDQ9V7j4myt7dLdqPJO5IS 8g42eutunLafu4O81vpvlpr5ZmdWvMdHopo3NSCzOYE8OCk3ROQQ4+RAmZhsnME9SBq6 qYfTWh1XbePEhyp9jy50WbSfyOmmE+l55UDx9k570JUPyK9e7UK4Rebzu4fo/Xxe7rOU JVcJ5aqEeoKDhMGIw3Fq7EPzmDmt8wZesRfHC52Mv4EEM5EbK5a7c3skxgT5OdkpKh+6 7qJSR94QxfxuQRTSohrQB+DfPZ95N8TnaGxrJEGmQS+bZlovQ9W6IxhGnh1RGrhTL3Qy Tu7A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772366803; x=1772971603; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=+NLDKguPnGJnQnFRD4unNG+va9+3jiMJbYExTIJsz8s=; b=iR1kByYefD7mpieE418nCzMjw9a6xff3zlzHpaM0TazHoW0ZKtFgdaBZocLMmkCinF YtB0jqSLTqzeAgQ6l7YAKb/delNArO1Y758xyUJqq673217nAXSRVzjgzgLZcliOXVbx BexoTcuclNJpjZXfN9w6m6k359zMHxHGkMD3Mc7XUCxQrAKr0YX6lthtRFc2RL7hhMCe d3bHbwveTRZqgZ2bi2Tq6ninWMTS9oMyN++bzYGXzlI4XHvDfaoANjjuoTMO6A8uKxS2 WY3ITARMabhxmr5S8BxfnE69Ahjla51x1SrpIme2bvQgserb05mdnP0bhPqaXwQud9oY bFaA== X-Forwarded-Encrypted: i=1; AJvYcCWQ6eoCm5ct1Sdbx1eGoL5QlBHHwRYrOc+xLqJxLIvZpBOPVoK+hw2RykLqUrWqcT5p58HeupHi7Xg=@lists.freedesktop.org X-Gm-Message-State: AOJu0YxT1c7lxoF61nGjwI4vxbbtGAmAROnYVpCD3DAX0QSE+1Uc6tTh eL9q6PTfSB5cmtH+TY3QU0o1pT7apsNmCAqonXhh9xjOVdiW0LrC0FIFzRUkRYvMq5oSTCkMfZX PpGjY/c9XVB6q0XLLAw== X-Received: from wmby4.prod.google.com ([2002:a05:600c:c044:b0:482:dff5:2424]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:348a:b0:483:c12b:fe4b with SMTP id 5b1f17b1804b1-483c9bc19e9mr146027225e9.9.1772366803234; Sun, 01 Mar 2026 04:06:43 -0800 (PST) Date: Sun, 1 Mar 2026 12:06:42 +0000 In-Reply-To: Mime-Version: 1.0 References: <20260204-aref-workitem-v2-0-bec25b012d2a@collabora.com> <20260204-aref-workitem-v2-2-bec25b012d2a@collabora.com> Message-ID: Subject: Re: [PATCH v2 2/4] rust: drm: dispatch work items to the private data From: Alice Ryhl To: Danilo Krummrich Cc: Daniel Almeida , Miguel Ojeda , Boqun Feng , Gary Guo , "=?utf-8?B?QmrDtnJu?= Roy Baron" , Benno Lossin , Andreas Hindborg , Trevor Gross , David Airlie , Simona Vetter , Tejun Heo , Lai Jiangshan , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org Content-Type: text/plain; charset="utf-8" X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" On Sat, Feb 28, 2026 at 07:40:26PM +0100, Danilo Krummrich wrote: > On Wed Feb 4, 2026 at 9:40 PM CET, Daniel Almeida wrote: > > This implementation dispatches any work enqueued on ARef> to > > its driver-provided handler. It does so by building upon the newly-added > > ARef support in workqueue.rs in order to call into the driver > > implementations for work_container_of and raw_get_work. > > > > This is notably important for work items that need access to the drm > > device, as it was not possible to enqueue work on a ARef> > > previously without failing the orphan rule. > > > > The current implementation needs T::Data to live inline with drm::Device in > > order for work_container_of to function. This restriction is already > > captured by the trait bounds. Drivers that need to share their ownership of > > T::Data may trivially get around this: > > > > // Lives inline in drm::Device > > struct DataWrapper { > > work: ..., > > // Heap-allocated, shared ownership. > > data: Arc, > > } > > IIUC, this is how it's supposed to be used: > > #[pin_data] > struct MyData { > #[pin] > work: Work>, > value: u32, > } > > impl_has_work! { > impl HasWork> for MyData { self.work } > } > > impl WorkItem for MyData { > type Pointer = ARef>; > > fn run(dev: ARef>) { > dev_info!(dev, "value = {}\n", dev.value); > } > } > > The reason the WorkItem is implemented for MyData, rather than > drm::Device (which would be a bit more straight forward) is the orphan > rule, I assume. This characterizes it as a workaround for the orphan rule. I don't think that's fair. Implementing WorkItem for MyDriver directly is the idiomatic way to do it, in my opinion. > Now, the whole purpose of this is that a driver can implement WorkItem for > MyData without needing an additional struct (and allocation), such as: > > #[pin_data] > struct MyWork { > #[pin] > work: Work, > dev: drm::Device, > } > > How is this supposed to be done when you want multiple different implementations > of WorkItem that have a drm::Device as payload? > > Fall back to various struct MyWork? Add in an "artificial" type state for MyData > with some phantom data, so you can implement HasWork for MyData, > MyData, etc.? You cannot configure the code that is executed on a per-call basis because the code called by a work item is a function pointer stored inside the `struct work_struct`. And it can't be changed after initialization of the field. So either you must store that info in a separate field. This is what Binder does, see drivers/android/binder/process.rs for an example. impl workqueue::WorkItem for Process { type Pointer = Arc; fn run(me: Arc) { let defer; { let mut inner = me.inner.lock(); defer = inner.defer_work; inner.defer_work = 0; } if defer & PROC_DEFER_FLUSH != 0 { me.deferred_flush(); } if defer & PROC_DEFER_RELEASE != 0 { me.deferred_release(); } } } Or you must have multiple different fields of type Work, each with a different function pointer stored inside it. Note that this is a general workqueue API thing. It's not specific to ARef<_> or drm::Device<_> based work items, but applies to all users of the workqueue API. Alice