From nobody Sat Apr 4 00:07:14 2026 Received: from mail-pf1-f182.google.com (mail-pf1-f182.google.com [209.85.210.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B945A28642B for ; Sun, 22 Mar 2026 04:44:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774154650; cv=none; b=VELLUoSaDM1e2VhxK9Z59b8cPVsF44wpqxI6YKWxa7Y0e+fjwfhqjU9ZlhHWjYNwNUH3nrN2qkAFX1HdtLotwmPnlnnBDMccfNicZt3r3b7yp0bMQsKKzVb3Ll6+ETgihyhWAcyscp6aQAp/3H2A5QV/WuvJTAeN0a0FPN5wHmU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774154650; c=relaxed/simple; bh=iklrSmc2eFXh465rqi8tjQ5u4HrKVniv0dcuPp1EWXM=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=kIF6KN1X71b9tkoGPZSrClBSoy0NxhpYlMlE2X5prxe3InV6qweupdEAqu18vw8fgQY4RTYJx9wL7OIOMFdu2kEQtPMUVDGC/ZVb/UCMQd1YD/rYosDm4iXc3LxLZeHCy/pBYmPigkDAZd4vRpDcRRKw8+Zs6we6y1zcgK5ttOI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=XxU+RHUt; arc=none smtp.client-ip=209.85.210.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="XxU+RHUt" Received: by mail-pf1-f182.google.com with SMTP id d2e1a72fcca58-829b8b6c4d0so2682074b3a.0 for ; Sat, 21 Mar 2026 21:44:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1774154648; x=1774759448; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=qU8/bWS13MsftZvgahKfQGOcZwrz6izAI39Mi9cBNB4=; b=XxU+RHUtQbjZ3aK8bge26YL7rLubhr9f0rdTMo5w/t+Mo3GT4RXIO/QybqPGw9bC6c HfNvysqq+/0FkSJTJVqhit7Ipg2vbaSkM1Pq+2tO4E3Sj38xaDnyVmN3TBHM5+OLMpiP AUFaRU9IA2657TfIFpXI6/ykAVHWLqAN3p/1rG4GIy9yXIbxjHYvoKR+xJYUxQWWZkqC xar0lcLRz9aOzZ/mGt1WBBgflsNGTXEaGKUL4WM/CEuw0/MHm9ayEIZqlK7oAEK3Q7zt 04QnLq6jjyxYhbS6kPY0uVAYb4vf5GbLwNHn7/emWtEhavDEOFK6BhYHVRntaooIY791 59FQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774154648; x=1774759448; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=qU8/bWS13MsftZvgahKfQGOcZwrz6izAI39Mi9cBNB4=; b=BjLSXU9wdxm9jkTYfyUenNsiwicfueeDpx6K6yH39earHAxUrzWyom8NgXUumYSRfz 3cFFes0ZAPfQwPYbVDDl4m3I2VXaK/87gkVws/ssRDRMHYipOomxUNPDnze+0wQARrkY 0P/hAg5fcY7o10c4zQMHAQJi+CNYCFsh8EKl5z+IZt/yBEb6JywCZdZ7ftbLTyigNvVu zD56E9yEHLg4mI90PK9UDP/vW/LlECuRMOOl27F7G/Fiwpq+j35OHdcbOeb27B3VAKPD MU1sOnOG7lHX9yu94P+djIgn5dD5fDnvkvOfJDJaF6KaM0xfvC4sP+RZLTCFKobpQLh3 Di4g== X-Forwarded-Encrypted: i=1; AJvYcCUhkePEZCPit+Iwl0ZcJ29XqStEL7XCjxNKApyi8spfepmIsO6koaVA5npFw2gNZLoHBoThPImDQhZyw54=@vger.kernel.org X-Gm-Message-State: AOJu0YyWU2yOacpdANgCwo+3WuSJFcsXhppoCJvYfFL4FYQ49Gk09gdw 3WE0t51T0ivAm2CVB2j10UstKacIYFWS4QZE6uSpb1zc0bMJgOa9ndTc X-Gm-Gg: ATEYQzzhTY7vTBXz8BWW3paF41D7h5+CR29jYBKe0/avCRHEQWLK5Gmb0CXs8JAtaxp AkNGFPU0+XUagyUQ5CHqOprRSbwsIT6mgs5k90E9k4elDgtOXhC/aw72l2sV1Sf+1McudE8rL79 jSz4PTiYXh4+DT7ebS5j1iKI8f0ROChXh4WpfkAVXHphsdNeQqQgx4jvhRvaJd7/Jzmj6WVyDen 5hbdl8nNGNaAJ++KPAXyRKazYitEeeb3ohDEYfpkzxsotDCNwweCTDw8U/5WGnX6IXVIu2zyUWi tC3pjleemZ8lUXFxDmDLGYZHX437P+eZ0acqdmDKIZWjXohnia+B9eC4oZsOBoWqOYlctcIDbFK EwivuSF4/bVZ8dFEprVeLwt9rNPFOYCjEIV+ljNgevXsAMx8PHNiLXyFqyMAfA0jGZQ5SQ02zUs V+jCe8wYqXX0r01e1o2yS7xPvvdq9xVX9jQPrBqAQe1+br37leTt72CYNEH/k= X-Received: by 2002:a05:6a00:1f19:b0:824:a635:4181 with SMTP id d2e1a72fcca58-82a8c21100dmr6602460b3a.15.1774154647760; Sat, 21 Mar 2026 21:44:07 -0700 (PDT) Received: from albab.. ([114.130.187.48]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-82b04222f42sm6959559b3a.61.2026.03.21.21.44.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Mar 2026 21:44:07 -0700 (PDT) From: Albab Hasan To: Miguel Ojeda Cc: Albab Hasan , Boqun Feng , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] rust: workqueue: add SAFETY comments for Pin> impl blocks Date: Sun, 22 Mar 2026 10:43:37 +0600 Message-ID: <20260322044340.129985-1-albabhasan276@gmail.com> X-Mailer: git-send-email 2.43.0 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 Content-Type: text/plain; charset="utf-8" Replace the placeholder // SAFETY: TODO. comments with proper safety descriptions for the two unsafe impl blocks WorkItemPointer and RawWorkItem for Pin>. For WorkItemPointer the safety relies on __enqueue obtaining the work_struct from the Work field via T::raw_get_work and Work::new ensuring the correct function pointer is passed to init_work_with_key. the ID const generic bound ties the Work field offset to the correct WorkItemPointer implementation so run always receives the right work_struct. For RawWorkItem the work_struct pointer stays valid for the closure because it comes from a KBox allocation that is not dropped in __enqueue. when queue_work_on returns true the memory is intentionally leaked and only reclaimed in WorkItemPointer::run which is the function pointer stored in the work_struct. Also fix two inner SAFETY comments in WorkItemPointer::run that incorrectly referenced Arc::into_raw instead of KBox::into_raw. Suggested-by: Miguel Ojeda Link: https://github.com/Rust-for-Linux/linux/issues/351 Signed-off-by: Albab Hasan --- rust/kernel/workqueue.rs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/rust/kernel/workqueue.rs b/rust/kernel/workqueue.rs index 706e833e9702..769220b042d3 100644 --- a/rust/kernel/workqueue.rs +++ b/rust/kernel/workqueue.rs @@ -874,7 +874,15 @@ unsafe impl RawDelayedWorkItem f= or Arc { } =20 -// SAFETY: TODO. +// SAFETY: The `__enqueue` implementation in `RawWorkItem` uses a `work_st= ruct` initialized with +// the `run` method of this trait as the function pointer because: +// - `__enqueue` gets the `work_struct` from the `Work` field, using `T:= :raw_get_work`. +// - The only safe way to create a `Work` object is through `Work::new`. +// - `Work::new` makes sure that `T::Pointer::run` is passed to `init_wo= rk_with_key`. +// - Finally `Work` and `RawWorkItem` guarantee that the correct `Work` = field +// will be used because of the ID const generic bound. This makes sure= that `T::raw_get_work` +// uses the correct offset for the `Work` field, and `Work::new` picks= the correct +// implementation of `WorkItemPointer` for `Pin>`. unsafe impl WorkItemPointer for Pin> where T: WorkItem, @@ -883,9 +891,9 @@ unsafe impl WorkItemPointer for P= in> unsafe extern "C" fn run(ptr: *mut bindings::work_struct) { // The `__enqueue` method always uses a `work_struct` stored in a = `Work`. let ptr =3D ptr.cast::>(); - // SAFETY: This computes the pointer that `__enqueue` got from `Ar= c::into_raw`. + // SAFETY: This computes the pointer that `__enqueue` got from `KB= ox::into_raw`. let ptr =3D unsafe { T::work_container_of(ptr) }; - // SAFETY: This pointer comes from `Arc::into_raw` and we've been = given back ownership. + // SAFETY: This pointer comes from `KBox::into_raw` and we've been= given back ownership. let boxed =3D unsafe { KBox::from_raw(ptr) }; // SAFETY: The box was already pinned when it was enqueued. let pinned =3D unsafe { Pin::new_unchecked(boxed) }; @@ -894,7 +902,13 @@ unsafe impl WorkItemPointer for = Pin> } } =20 -// SAFETY: TODO. +// SAFETY: The `work_struct` raw pointer is guaranteed to be valid for the= duration of the call to +// the closure because we get it from a `KBox`, which guarantees that the = allocation is valid until +// the `KBox` is dropped, and we don't drop it in `__enqueue`. If `queue_w= ork_on` returns true, it +// is further guaranteed to be valid until a call to the function pointer = in `work_struct` because +// we leak the memory by not calling `KBox::from_raw` after `KBox::into_ra= w`, and only reclaim it +// in `WorkItemPointer::run`, which is what the function pointer in the `w= ork_struct` must be +// pointing to, according to the safety requirements of `WorkItemPointer`. unsafe impl RawWorkItem for Pin> where T: WorkItem, --=20 2.43.0