Message ID | 20240205-b4-rbtree-v1-1-995e3eee38c0@google.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel+bounces-52949-ouuuleilei=gmail.com@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:168b:b0:106:860b:bbdd with SMTP id ma11csp979325dyb; Mon, 5 Feb 2024 08:15:33 -0800 (PST) X-Google-Smtp-Source: AGHT+IEQmQ0LHSYNLpy4rC0vnQm/yGmnbeT8VxLpY4tVNR9aNJpDOeHSb4ysv8qvcioE8UKGyYCS X-Received: by 2002:a05:6a20:d80a:b0:19e:3172:b8ac with SMTP id iv10-20020a056a20d80a00b0019e3172b8acmr16260784pzb.22.1707149733087; Mon, 05 Feb 2024 08:15:33 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707149733; cv=pass; d=google.com; s=arc-20160816; b=xOjcURBR62i9SZ0pFLAf6356o4X0rKe0IzYZsm4aqUSYt66X5TB+Yj44uY3EE8zrvT VdgZ91rGtqnKUwkLeKYuBrWDgJ6q8Bm283wIbmCDtaay9PU2roQdNYzMLhmEmHiUyrRX cJDz6tjESuPahx1xipIk4cICAfBpo/jES5+1cmWycpc0tZrs7J+9SrJJXudd+nRmmi/x 8CDxJHciXkLoGj4U3k+ZA3xrS5c6tFXIPIiBj3i3iECh+2GPRhqFC3p+qFfdrtvzmg7n MUmbZxWaoO/zbe23QeQ5nW/tmbhotHaf1qrd2i7aKy7qnDzTS0tZm2johdY0XIfkBC3j k/6A== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:from:subject:message-id:references:mime-version :list-unsubscribe:list-subscribe:list-id:precedence:in-reply-to:date :dkim-signature; bh=KixoytXQDGjoXAfvxRuyy14dtLsh1IkvCMs1kLMTxgU=; fh=G8sm5CI7MOuoGQ2RFpPCGIxhqDmlzRtAgm1uJLtGOrw=; b=dyWhr8CoAp46/ocgqD3q/1GNDrOk3M+YQc7hNGiKCDfOOplo07lVR21O08bH+uVxpS lniyQP0v5SSXOc/oUrQWP6eolVr5VzOqm0tmtFGS0Ngm24r5p+fQe4PwFOHZHIF7zCZW 5NAsuXnwyKcrl+9fQvKdr0IFz6NNNWI2887jcORSs7kZBWS20HHesgKQjuAnDlsMOJ3U bc/zA5fFzY4frCr/tWIspyVoq/TDQ+iSGtXK2DJNznyXkI37bvgj3qhdDjsgP76NgthI ZfSzJn4h90wy1Re5IUaAiF1/X6l9fOWv7evDSFlP4EYO+Ss7w+N4mLe5PUVuqYp8pGU7 ctAg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=wPZ8etjv; arc=pass (i=1 spf=pass spfdomain=flex--mattgilbride.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-52949-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-52949-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com X-Forwarded-Encrypted: i=1; AJvYcCUsh8brYVvU7/9GcSXZun26/9ENHdiLCqcJRoL9SV3N8j6cN0pgGOZ11P8w8l/w0IPdfDbNuY4MqTr7i0o39s+vRU7DIA== Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id y189-20020a62cec6000000b006e0539ac831si631pfg.362.2024.02.05.08.15.32 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Feb 2024 08:15:33 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-52949-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=wPZ8etjv; arc=pass (i=1 spf=pass spfdomain=flex--mattgilbride.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-52949-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-52949-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 6A302B22715 for <ouuuleilei@gmail.com>; Mon, 5 Feb 2024 15:50:52 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8236A44C9D; Mon, 5 Feb 2024 15:50:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="wPZ8etjv" Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.201]) (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 6BB8E3FB21 for <linux-kernel@vger.kernel.org>; Mon, 5 Feb 2024 15:50:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707148208; cv=none; b=CFTY0AUb2R924kFv5XCQgvlwCAd/mZsvwdumeIcxcpyLQFPz2alzYAoPmJ0QvVOTSASC5riJ6/pzUe5MpfLyR8R00lV5yG7poIOaDZYlPvOupY7Jm1erRLCyUWz9Hfy05XMPDdawyCUW/hkz2HKWFi1vuFe4o72ZUTEizudBz0M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707148208; c=relaxed/simple; bh=FR4T3Qjs2jKRsHMGwYv7pMd/5Tm8HyvFjH7AWhAgulg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=iKCg1bv/ONpfwCYJp3k6BvipMQS/RlWey77rlBqYdeLVLM5w/XUpHvJ3CqtJY6Vx0sS9fLBYzDtjN5ByZDvjGVdGzWNXcqDIY0tyRvRIdrPi8Em6t3UgA5brDB2TQTIRti89zstw7s9IRWp91dQwebaxRza4+zsCrIGibyIi/es= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--mattgilbride.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=wPZ8etjv; arc=none smtp.client-ip=209.85.128.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--mattgilbride.bounces.google.com Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-60404b12af2so72290047b3.2 for <linux-kernel@vger.kernel.org>; Mon, 05 Feb 2024 07:50:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1707148205; x=1707753005; darn=vger.kernel.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=KixoytXQDGjoXAfvxRuyy14dtLsh1IkvCMs1kLMTxgU=; b=wPZ8etjvu/a0We6zybD5oAoPX7szcBceYVUEtMiWa3ZZrix76d58rDCkj7FojQPqdH ZmXPORLgWNqQWFWzdBV107HrPBpy1c6A1q5DQ1u9JNkVQwCuQlpScUulMKP6VyCuleJ0 6dHcmeSwZEVGPfGT1D7jS+IB6RZrt6f2h2cLrGku+leR467FVVGe3vT213AA6N5XcWS0 pa8RGs4idtdY2QEOyZyWoZilowaWZL+zqoh0ulBe0R8jHu1HKxVCoH2NOEQvKFHhkPDw aAPL5DKsWpmAz2R3dU4gHLZrV25PVdlMnaztzFDVtmXUN4/Ns7TRSNikrsJ0LIWWPr90 3TWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707148205; x=1707753005; 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=KixoytXQDGjoXAfvxRuyy14dtLsh1IkvCMs1kLMTxgU=; b=fOOPwbgeGvGWL4kLY8doMMtNFB2Bi8mO5sVD6zyjEvdL28Hqs3RjrtUmbM2ahe4Owj 6WAdEWShO+Gkr9jElqWUb8cwBz6Xln3kVbIve9RQGnRc/uA/EUxLuyd8aeZbVk3WT14m rCSGR+XDyQT1Vy7Zlp6J31XiuEk2dyfkO0YbsCtVH6dyXO0YhpmYScDcfurxhMzSMj8W S6gCS1rzhnOnxNGFXpahmw1s7JBWE9rtc8OvBV7jmNkoy7nEVfQ0zR8IoXw4e2kDFezM PPjQVFw0NtF5lG1uaq2LbS9czH/iiAQUqiavDfrf0YLbKC+S49Vp05T82Koo07yVXCOV GYIg== X-Gm-Message-State: AOJu0Yw1FCp9vF4QTpuA982GtKa15cOndTtlgxe48DOo3rAreUp4yrqf smaLGZ8gKIfktT9r8cYrVOf83yaX/jc7m2VMYaYjhfzfbLHI3zNENtU0TcaBK3c6hP8u64Je3Wl tJ/+w+622p4Qn0p9FUIkpPmvEKA== X-Received: from mattgilbride.c.googlers.com ([fda3:e722:ac3:cc00:2b:7d90:c0a8:2ac5]) (user=mattgilbride job=sendgmr) by 2002:a05:6902:138f:b0:dc6:dd74:de68 with SMTP id x15-20020a056902138f00b00dc6dd74de68mr440165ybu.12.1707148205361; Mon, 05 Feb 2024 07:50:05 -0800 (PST) Date: Mon, 05 Feb 2024 15:50:01 +0000 In-Reply-To: <20240205-b4-rbtree-v1-0-995e3eee38c0@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: <linux-kernel.vger.kernel.org> List-Subscribe: <mailto:linux-kernel+subscribe@vger.kernel.org> List-Unsubscribe: <mailto:linux-kernel+unsubscribe@vger.kernel.org> Mime-Version: 1.0 References: <20240205-b4-rbtree-v1-0-995e3eee38c0@google.com> X-Mailer: b4 0.12.3 Message-ID: <20240205-b4-rbtree-v1-1-995e3eee38c0@google.com> Subject: [PATCH 1/6] rust: add `container_of!` macro From: mattgilbride@google.com To: Miguel Ojeda <ojeda@kernel.org>, Alex Gaynor <alex.gaynor@gmail.com>, Wedson Almeida Filho <wedsonaf@gmail.com>, Boqun Feng <boqun.feng@gmail.com>, Gary Guo <gary@garyguo.net>, " =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= " <bjorn3_gh@protonmail.com>, Benno Lossin <benno.lossin@proton.me>, Andreas Hindborg <a.hindborg@samsung.com>, Alice Ryhl <aliceryhl@google.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, " =?utf-8?q?Arve_Hj=C3=B8n?= =?utf-8?q?nev=C3=A5g?= " <arve@android.com>, Todd Kjos <tkjos@android.com>, Martijn Coenen <maco@android.com>, Joel Fernandes <joel@joelfernandes.org>, Carlos Llamas <cmllamas@google.com>, Suren Baghdasaryan <surenb@google.com>, Christian Brauner <brauner@kernel.org> Cc: Rob Landley <rob@landley.net>, Davidlohr Bueso <dave@stgolabs.net>, Michel Lespinasse <michel@lespinasse.org>, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Matt Gilbride <mattgilbride@google.com> Content-Type: text/plain; charset="utf-8" X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790076238817423946 X-GMAIL-MSGID: 1790076238817423946 |
Series |
Red-black tree abstraction needed by Rust Binder
|
|
Commit Message
Matt Gilbride
Feb. 5, 2024, 3:50 p.m. UTC
From: Wedson Almeida Filho <wedsonaf@gmail.com> This macro is used to obtain a pointer to an entire struct when given a pointer to a field in that struct. Signed-off-by: Wedson Almeida Filho <wedsonaf@gmail.com> Signed-off-by: Matt Gilbride <mattgilbride@google.com> --- rust/kernel/lib.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
Comments
On Mon, Feb 5, 2024 at 4:50 PM <mattgilbride@google.com> wrote: > > From: Wedson Almeida Filho <wedsonaf@gmail.com> > > This macro is used to obtain a pointer to an entire struct > when given a pointer to a field in that struct. > > Signed-off-by: Wedson Almeida Filho <wedsonaf@gmail.com> > Signed-off-by: Matt Gilbride <mattgilbride@google.com> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Tested-by: Alice Ryhl <aliceryhl@google.com>
On Mon, Feb 5, 2024 at 9:50 AM <mattgilbride@google.com> wrote: > > From: Wedson Almeida Filho <wedsonaf@gmail.com> > > This macro is used to obtain a pointer to an entire struct > when given a pointer to a field in that struct. > > Signed-off-by: Wedson Almeida Filho <wedsonaf@gmail.com> > Signed-off-by: Matt Gilbride <mattgilbride@google.com> > --- > rust/kernel/lib.rs | 32 ++++++++++++++++++++++++++++++++ > 1 file changed, 32 insertions(+) > > diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs > index 7ac39874aeac..c7963efd1318 100644 > --- a/rust/kernel/lib.rs > +++ b/rust/kernel/lib.rs > @@ -102,3 +102,35 @@ fn panic(info: &core::panic::PanicInfo<'_>) -> ! { > // SAFETY: FFI call. > unsafe { bindings::BUG() }; > } > + > +/// Produces a pointer to an object from a pointer to one of its fields. It is in the examples but a note would be good to make it obvious: /// /// This macro must be called from within an `unsafe { }` block. > +/// # Safety > +/// > +/// The pointer passed to this macro, and the pointer returned by this macro, must both be in > +/// bounds of the same allocation. > +/// > +/// # Examples > +/// > +/// ``` > +/// # use kernel::container_of; > +/// struct Test { > +/// a: u64, > +/// b: u32, > +/// } > +/// > +/// let test = Test { a: 10, b: 20 }; > +/// let b_ptr = &test.b; > +/// // SAFETY: The pointer points at the `b` field of a `Test`, so the resulting pointer will be > +/// // in-bounds of the same allocation as `b_ptr`. > +/// let test_alias = unsafe { container_of!(b_ptr, Test, b) }; > +/// assert!(core::ptr::eq(&test, test_alias)); > +/// ``` > +#[macro_export] > +macro_rules! container_of { > + ($ptr:expr, $type:ty, $($f:tt)*) => {{ > + let ptr = $ptr as *const _ as *const u8; > + let offset: usize = ::core::mem::offset_of!($type, $($f)*); `offset_of` will be stable in 1.77 BUT only for a single field [1]. I don't know if there are other blockers in the kernel already, but if this could be changed to call `offset_of!` recursively then it will work with the stable version. We might want an `offset_of_many!(a, b, c)` macro somewhere if there are other places that need this nesting. [1]: https://github.com/rust-lang/rust/pull/118799 > + ptr.sub(offset) as *const $type Instead of casting to and from `u8`, you should be able to use `byte_sub` > + }} > +} - Trevor
On Sat, Feb 10, 2024 at 9:05 AM Trevor Gross <tmgross@umich.edu> wrote: > > On Mon, Feb 5, 2024 at 9:50 AM <mattgilbride@google.com> wrote: > > +macro_rules! container_of { > > + ($ptr:expr, $type:ty, $($f:tt)*) => {{ > > + let ptr = $ptr as *const _ as *const u8; > > + let offset: usize = ::core::mem::offset_of!($type, $($f)*); > > `offset_of` will be stable in 1.77 BUT only for a single field [1]. I > don't know if there are other blockers in the kernel already, but if > this could be changed to call `offset_of!` recursively then it will > work with the stable version. > > We might want an `offset_of_many!(a, b, c)` macro somewhere if there > are other places that need this nesting. > > [1]: https://github.com/rust-lang/rust/pull/118799 Rust Binder *does* need that in one place. Creating a nested offset_of! is kind of tricky, because you have to fail to compile when you're following a pointer with the Deref trait. I haven't figured out how to do that yet. > > + ptr.sub(offset) as *const $type > > Instead of casting to and from `u8`, you should be able to use `byte_sub` Casting to and from u8 also has the side-effect of making it not work when the target type is !Sized. Not allowing this might be desirable. Alice
diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 7ac39874aeac..c7963efd1318 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -102,3 +102,35 @@ fn panic(info: &core::panic::PanicInfo<'_>) -> ! { // SAFETY: FFI call. unsafe { bindings::BUG() }; } + +/// Produces a pointer to an object from a pointer to one of its fields. +/// +/// # Safety +/// +/// The pointer passed to this macro, and the pointer returned by this macro, must both be in +/// bounds of the same allocation. +/// +/// # Examples +/// +/// ``` +/// # use kernel::container_of; +/// struct Test { +/// a: u64, +/// b: u32, +/// } +/// +/// let test = Test { a: 10, b: 20 }; +/// let b_ptr = &test.b; +/// // SAFETY: The pointer points at the `b` field of a `Test`, so the resulting pointer will be +/// // in-bounds of the same allocation as `b_ptr`. +/// let test_alias = unsafe { container_of!(b_ptr, Test, b) }; +/// assert!(core::ptr::eq(&test, test_alias)); +/// ``` +#[macro_export] +macro_rules! container_of { + ($ptr:expr, $type:ty, $($f:tt)*) => {{ + let ptr = $ptr as *const _ as *const u8; + let offset: usize = ::core::mem::offset_of!($type, $($f)*); + ptr.sub(offset) as *const $type + }} +}