Received: by 2002:a05:6358:3188:b0:123:57c1:9b43 with SMTP id q8csp4528291rwd; Sun, 11 Jun 2023 09:12:05 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ4hRQfLveIMNh+Qo9WVs3z4zfsfgKJCOMZ9NYjAfq06G+pwSI6dKv/LCGVmybmfYAXxbrCq X-Received: by 2002:a05:6a20:8f04:b0:110:9b0b:71ab with SMTP id b4-20020a056a208f0400b001109b0b71abmr8988442pzk.40.1686499924895; Sun, 11 Jun 2023 09:12:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686499924; cv=none; d=google.com; s=arc-20160816; b=lqmfKvp1oDrlFRw1FZd+HfqDVLwAnS9JloyaYnqTARcYXdiKhYlwyuKQfiOL+8uitw aoiZCOni5QLqqJWy2kfRfgphwAa731fRK1Exk0PJ4/MLkUK4Ij0fjbb5iTJd9rXmAd+c 7Pqkx0gidx6Xsmu8B0U0gF78O/dKLsdDMvWK59mJQCvzwCCjy+1iDA8+SuprxxeT+J/N CY3Rx/USvR1uHmW4+5fzW2sC8qjUSau9HovDDTyi82UA09o7N+XZbQxe5actknzxIFvo UAQXchl8Z7f1iHecEHumlWXvLwZrIJ4b4rreqm3Qsp8dksLs8oPfYaz190bkjyHt8HhN HCTA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :feedback-id:references:in-reply-to:message-id:subject:cc:from:to :dkim-signature:date; bh=kYAUFYLzaiAX52hQfJ1MUOd0KMtIuNz3QI77YeCuRe4=; b=YYrd2hbFSNXAkUZy/zy4KHhdL/49DyePnjvT7MyQJVD8kFmZ7CvKijAGB+qD2bDkzj vDldDd2HP88l2eaIL63U6ApffCF+HNojrEuac6RfXEAHL5nVaAioai1W5x3w8j83p9V+ vAunxhTSCqAiLYsb87lpXZv+w1nQyK3vOTeGDe6c+5f6x1pt/9/jzfFI2O/DjfUiwPSh fRjC50qHs9qCbf9vafuzTjJgfFdIVTbCOOE9IPip8+EmL+zrv0Mcorq1tKZj3XshtAub lZhnn/bPPtnAq/Rs5oPO6CY9e/dFybp3vpQ9MHLixNXTqh6tFNqpn2F8FYwTuFmLWTZn h7CQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@proton.me header.s=protonmail header.b=Df1dBfWS; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=proton.me Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id d10-20020a63734a000000b00544b88dda2csi5463959pgn.661.2023.06.11.09.11.52; Sun, 11 Jun 2023 09:12:04 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@proton.me header.s=protonmail header.b=Df1dBfWS; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=proton.me Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233819AbjFKQB1 (ORCPT + 99 others); Sun, 11 Jun 2023 12:01:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33536 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233781AbjFKQBW (ORCPT ); Sun, 11 Jun 2023 12:01:22 -0400 Received: from mail-4322.protonmail.ch (mail-4322.protonmail.ch [185.70.43.22]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 63F66DA for ; Sun, 11 Jun 2023 09:01:18 -0700 (PDT) Date: Sun, 11 Jun 2023 16:01:05 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=proton.me; s=protonmail; t=1686499276; x=1686758476; bh=kYAUFYLzaiAX52hQfJ1MUOd0KMtIuNz3QI77YeCuRe4=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=Df1dBfWS+x56HZNpJC1DD90F2+NBfpRlehzNABiikAp5kvYzFP67yUtDPdVXQW0rw e0axP3VrTTCwZoGEKOwGjCmUR/99oF/RenObRZEob935GlsGPsQnPvxyqB39Mw00fT eGmUUCzHxd88VB8tbkyLDfNxweoCFLzicxsfjItwSlEZlUscDJ5/pjlPUTJ3WqQx54 n8vZ4nOlzViOhWac7cxOteuxnguSBzRh7JRlAeAYaKnZfoFl3y4/eBTxa4LwW7jh+T W82aYRLp7DjjAhj0bCW7RGoxwAdM8HO7m6Z9G5m0EQYqgQxNYW8ADqKB5pun0tGCav psKcGCwgoOcyw== To: Alice Ryhl From: Benno Lossin Cc: rust-for-linux@vger.kernel.org, Miguel Ojeda , Wedson Almeida Filho , Tejun Heo , Lai Jiangshan , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?Q?Bj=C3=B6rn_Roy_Baron?= , linux-kernel@vger.kernel.org, patches@lists.linux.dev Subject: Re: [PATCH v2 6/8] rust: workqueue: implement `WorkItemPointer` for pointer types Message-ID: In-Reply-To: <20230601134946.3887870-7-aliceryhl@google.com> References: <20230601134946.3887870-1-aliceryhl@google.com> <20230601134946.3887870-7-aliceryhl@google.com> Feedback-ID: 71780778:user:proton MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-2.7 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 01.06.23 15:49, Alice Ryhl wrote: > This implements the `WorkItemPointer` trait for the pointer types that > you are likely to use the workqueue with. The `Arc` type is for > reference counted objects, and the `Pin>` type is for objects > where the caller has exclusive ownership of the object. >=20 > Co-developed-by: Gary Guo > Signed-off-by: Gary Guo > Signed-off-by: Alice Ryhl I have a small nit below. Reviewed-by: Benno Lossin > --- > rust/kernel/workqueue.rs | 97 +++++++++++++++++++++++++++++++++++++++- > 1 file changed, 96 insertions(+), 1 deletion(-) >=20 > diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs > index dbf0aab29a85..f06a2f036d8b 100644 > --- a/rust/kernel/workqueue.rs > +++ b/rust/kernel/workqueue.rs > @@ -28,8 +28,10 @@ > //! > //! C header: [`include/linux/workqueue.h`](../../../../include/linux/w= orkqueue.h) >=20 > -use crate::{bindings, prelude::*, types::Opaque}; > +use crate::{bindings, prelude::*, sync::Arc, types::Opaque}; > +use alloc::boxed::Box; > use core::marker::{PhantomData, PhantomPinned}; > +use core::pin::Pin; >=20 > /// A kernel work queue. > /// > @@ -323,6 +325,99 @@ unsafe fn raw_get_work(ptr: *mut Self) -> *mut $crat= e::workqueue::Work<$work_typ > )*}; > } >=20 > +unsafe impl WorkItemPointer for Arc > +where > + T: WorkItem, > + T: HasWork, > +{ > + unsafe extern "C" fn run(ptr: *mut bindings::work_struct) { > + // SAFETY: The `__enqueue` method always uses a `work_struct` st= ored in a `Work`. > + let ptr =3D ptr as *mut Work; > + // SAFETY: This computes the pointer that `__enqueue` got from `= Arc::into_raw`. > + let ptr =3D unsafe { T::work_container_of(ptr) }; > + // SAFETY: This pointer comes from `Arc::into_raw` and we've bee= n given back ownership. > + let arc =3D unsafe { Arc::from_raw(ptr) }; > + > + T::run(arc) > + } > +} > + > +unsafe impl RawWorkItem for Arc > +where > + T: WorkItem, > + T: HasWork, > +{ > + type EnqueueOutput =3D Result<(), Self>; > + > + unsafe fn __enqueue(self, queue_work_on: F) -> Self::EnqueueOutpu= t > + where > + F: FnOnce(*mut bindings::work_struct) -> bool, > + { > + // Casting between const and mut is not a problem as long as the= pointer is a raw pointer. > + let ptr =3D Arc::into_raw(self) as *mut T; I personally would prefer `cast_mut()` here. --=20 Cheers, Benno > + > + // SAFETY: Pointers into an `Arc` point at a valid value. > + let work_ptr =3D unsafe { T::raw_get_work(ptr) }; > + // SAFETY: `raw_get_work` returns a pointer to a valid value. > + let work_ptr =3D unsafe { Work::raw_get(work_ptr) }; > + > + if queue_work_on(work_ptr) { > + Ok(()) > + } else { > + // SAFETY: The work queue has not taken ownership of the poi= nter. > + Err(unsafe { Arc::from_raw(ptr) }) > + } > + } > +} > + > +unsafe impl WorkItemPointer for Pin> > +where > + T: WorkItem, > + T: HasWork, > +{ > + unsafe extern "C" fn run(ptr: *mut bindings::work_struct) { > + // SAFETY: The `__enqueue` method always uses a `work_struct` st= ored in a `Work`. > + let ptr =3D ptr as *mut Work; > + // SAFETY: This computes the pointer that `__enqueue` got from `= Arc::into_raw`. > + let ptr =3D unsafe { T::work_container_of(ptr) }; > + // SAFETY: This pointer comes from `Arc::into_raw` and we've bee= n given back ownership. > + let boxed =3D unsafe { Box::from_raw(ptr) }; > + // SAFETY: The box was already pinned when it was enqueued. > + let pinned =3D unsafe { Pin::new_unchecked(boxed) }; > + > + T::run(pinned) > + } > +} > + > +unsafe impl RawWorkItem for Pin> > +where > + T: WorkItem, > + T: HasWork, > +{ > + type EnqueueOutput =3D (); > + > + unsafe fn __enqueue(self, queue_work_on: F) -> Self::EnqueueOutpu= t > + where > + F: FnOnce(*mut bindings::work_struct) -> bool, > + { > + // SAFETY: We're not going to move `self` or any of its fields, = so its okay to temporarily > + // remove the `Pin` wrapper. > + let boxed =3D unsafe { Pin::into_inner_unchecked(self) }; > + let ptr =3D Box::into_raw(boxed); > + > + // SAFETY: Pointers into a `Box` point at a valid value. > + let work_ptr =3D unsafe { T::raw_get_work(ptr) }; > + // SAFETY: `raw_get_work` returns a pointer to a valid value. > + let work_ptr =3D unsafe { Work::raw_get(work_ptr) }; > + > + if !queue_work_on(work_ptr) { > + // SAFETY: This method requires exclusive ownership of the b= ox, so it cannot be in a > + // workqueue. > + unsafe { ::core::hint::unreachable_unchecked() } > + } > + } > +} > + > /// Returns the system work queue (`system_wq`). > /// > /// It is the one used by `schedule[_delayed]_work[_on]()`. Multi-CPU m= ulti-threaded. There are > -- > 2.41.0.rc0.172.g3f132b7071-goog >=20