public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Alice Ryhl <aliceryhl@google.com>
To: Jason Hall <jason.kei.hall@gmail.com>
Cc: "Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Arve Hjønnevåg" <arve@android.com>,
	"Todd Kjos" <tkjos@google.com>,
	"Carlos Llamas" <cmllamas@google.com>,
	rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2] rust_binder: refactor context management to use KVVec
Date: Mon, 19 Jan 2026 10:11:37 +0000	[thread overview]
Message-ID: <aW4DWebqCg1c8Fgb@google.com> (raw)
In-Reply-To: <20260118142623.1188141-1-jason.kei.hall@gmail.com>

On Sun, Jan 18, 2026 at 07:26:23AM -0700, Jason Hall wrote:
> Replace the linked list management in context.rs with KVVec.
> This simplifies the ownership model by using standard
> Arc-based tracking and moves away from manual unsafe list removals.
> 
> The refactor improves memory safety by leveraging Rust's contiguous
> collection types while maintaining proper error propagation for
> allocation failures during process registration.
> 
> Suggested-by: Alice Ryhl <aliceryhl@google.com>
> Link: https://github.com/rust-for-linux/linux/issues/1215
> Signed-off-by: Jason Hall <jason.kei.hall@gmail.com>

> -    pub(crate) fn register_process(self: &Arc<Self>, proc: ListArc<Process>) {
> +    pub(crate) fn register_process(self: &Arc<Self>, proc: Arc<Process>) -> Result {
>          if !Arc::ptr_eq(self, &proc.ctx) {
>              pr_err!("Context::register_process called on the wrong context.");
> -            return;
> +            return Err(EINVAL);
>          }
> -        self.manager.lock().all_procs.push_back(proc);
> +        self.manager
> +            .lock()
> +            .all_procs
> +            .push(proc, GFP_KERNEL)
> +            .map_err(Error::from)

This can be simplified to:

self.manager
    .lock()
    .all_procs
    .push(proc, GFP_KERNEL)?;
Ok(())

>      }
>  
>      pub(crate) fn deregister_process(self: &Arc<Self>, proc: &Process) {
> @@ -108,8 +99,12 @@ pub(crate) fn deregister_process(self: &Arc<Self>, proc: &Process) {
>              pr_err!("Context::deregister_process called on the wrong context.");
>              return;
>          }
> -        // SAFETY: We just checked that this is the right list.
> -        unsafe { self.manager.lock().all_procs.remove(proc) };
> +        // Safe removal using retain
> +        self.manager.lock().all_procs.retain(|p| {
> +            let p1 = Arc::as_ptr(p);
> +            let p2 = proc as *const Process;
> +            p1 != p2
> +        });

Please use Arc::ptr_eq() for this comparison (in both places). You may
change deregister_process to take an &Arc<Process> as argument to make
this work.

Also, I think we should shrink the `all_procs` vector if it becomes too
much larger than the number of procs. Let's say ... after removing a
process, if the capacity() is less than half of the length and less than
128, then we shrink the capacity.

>      }
>  
>      pub(crate) fn set_manager_node(&self, node_ref: NodeRef) -> Result {
> @@ -158,13 +153,11 @@ pub(crate) fn for_each_proc<F>(&self, mut func: F)
>          }
>      }
>  
> -    pub(crate) fn get_all_procs(&self) -> Result<KVec<Arc<Process>>> {
> +    pub(crate) fn get_all_procs(&self) -> Result<KVVec<Arc<Process>>> {
>          let lock = self.manager.lock();
> -        let count = lock.all_procs.iter().count();
> -
> -        let mut procs = KVec::with_capacity(count, GFP_KERNEL)?;
> -        for proc in &lock.all_procs {
> -            procs.push(Arc::from(proc), GFP_KERNEL)?;
> +        let mut procs = KVVec::with_capacity(lock.all_procs.len(), GFP_KERNEL)?;
> +        for proc in lock.all_procs.iter() {
> +            procs.push(Arc::clone(proc), GFP_KERNEL)?;
>          }

Let's change get_procs_with_pid() too. Both to use KVVec, and also let's
have it iterate all_procs() directly.

> diff --git a/drivers/android/binder/process.rs b/drivers/android/binder/process.rs
> index 132055b4790f..c3676fc7785d 100644
> --- a/drivers/android/binder/process.rs
> +++ b/drivers/android/binder/process.rs
> @@ -513,7 +513,9 @@ fn new(ctx: Arc<Context>, cred: ARef<Credential>) -> Result<Arc<Self>> {
>          )?;
>  
>          let process = list_process.clone_arc();
> -        process.ctx.register_process(list_process);
> +        process
> +            .ctx
> +            .register_process(Arc::from(list_process.as_arc_borrow()))?;

You do not need to create a ListArc<Process> in the first place.

 impl Process {
     fn new(ctx: Arc<Context>, cred: ARef<Credential>) -> Result<Arc<Self>> {
         let current = kernel::current!();
-        let list_process = ListArc::pin_init::<Error>(
+        let process = Arc::pin_init::<Error>(
             try_pin_init!(Process {
                 ctx,
                 cred,
                 inner <- kernel::new_spinlock!(ProcessInner::new(), "Process::inner"),
                 pages <- ShrinkablePageRange::new(&super::BINDER_SHRINKER),
                 node_refs <- kernel::new_mutex!(ProcessNodeRefs::new(), "Process::node_refs"),
                 freeze_wait <- kernel::new_condvar!("Process::freeze_wait"),
                 task: current.group_leader().into(),
                 defer_work <- kernel::new_work!("Process::defer_work"),
                 links <- ListLinks::new(),
                 stats: BinderStats::new(),
             }),
             GFP_KERNEL,
         )?;
 
-        let process = list_process.clone_arc();
-        process
-            .ctx
-            .register_process(Arc::from(list_process.as_arc_borrow()))?;
+        process.ctx.register_process(process.clone())?;
 
         Ok(process)
     }

Alice

  reply	other threads:[~2026-01-19 10:11 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-18 14:26 [PATCH v2] rust_binder: refactor context management to use KVVec Jason Hall
2026-01-19 10:11 ` Alice Ryhl [this message]
2026-01-19 13:31 ` [PATCH v3] " Jason Hall
2026-01-20  7:55   ` Alice Ryhl

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aW4DWebqCg1c8Fgb@google.com \
    --to=aliceryhl@google.com \
    --cc=arve@android.com \
    --cc=cmllamas@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jason.kei.hall@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tkjos@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox