From nobody Sun Feb 8 05:30:16 2026 Received: from mail-dy1-f174.google.com (mail-dy1-f174.google.com [74.125.82.174]) (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 BB5D91F4CBB for ; Sat, 17 Jan 2026 16:23:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768666989; cv=none; b=eWPhvJcJDuQjI+qnCo5nJIZ/Ts5LL57QdOQGEyU5aqrYRxCNy9eTrmaXiAZHziD4G3wLG+wEgsGjtRCvnvTwxZKH/aHzYRXQVYibeWhUhBMjHiyUXGzVLHytR9HBZKZasS1lnoiDcTLrQ74iP3OsEAGLJfTaHUfQI1lDJmcqQto= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768666989; c=relaxed/simple; bh=EC36Gi/Jc5XaCuHbWuXLu5LlDgqDhlugX1l8rO5Utpo=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=TXQ0Xzp418SITxPmbHpm4wOI6O5tXF42kpR8ZQu5FF/nRUYYLDLe0XENE9BmdNNP/1FvcuBcSTtP1fS8/wmNnO9dLYP1IUgUyngDSsiA/b53IaUfY4cf+bdxP2u7TomgXMWSnJixczFEkE9IlTbk/fWgAXI7qnHYmBhc87vMggI= 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=kKlSfyL8; arc=none smtp.client-ip=74.125.82.174 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="kKlSfyL8" Received: by mail-dy1-f174.google.com with SMTP id 5a478bee46e88-2ae38f81be1so3757619eec.0 for ; Sat, 17 Jan 2026 08:23:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768666987; x=1769271787; 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=exfO0g4RfbUJsv5m7l2Vm+b3WtGl2kH9j0lxZZq/Nac=; b=kKlSfyL8hHXRwPU34lW4NpH92exp1PnduiGo2kfg/Dq/8tbU8H6VlmizU7MAdSNiHq 6kxSGhB2b2C/iNlpjUDuiLASCntgbD1Y/e8nYwFVKDUK8T2xlGpDxKLEwW2p9Sgi82Bd v5ohWVmkNOJpKaXlc4K4n2hvU/R9JITIH6MxNvMGKMuvyf/I2qhCA7+vygsVkJh1Tunh NzQnJmENPaE4g94O/QZxiyTc8en+3fGkdDrsIkQkTMGrbxlNecF7J8HPgEt9WjhtQA1y 0X5fNas6iUJZKIc/XETjLnYS7fC9qcNqTBRXRPspztuR1+dSXqFgxlSiyNMzI2UKYh/7 aBRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768666987; x=1769271787; 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=exfO0g4RfbUJsv5m7l2Vm+b3WtGl2kH9j0lxZZq/Nac=; b=p6xDaqOp2cNlAAqAhYgaDMFIWxlRV01cklw5QpsB3I/WEA1C5XW1z+m8yFhwQ3Zp/H OOh/2WztDKi7A7KtznNHzrLv53Sz01jVZsCMFTSAjb5H4LaWh6s0wH90Sg9jGf3gUX5v hNM/DZi2xHzQp5YWu+g2VZGWvbKnxRjc0W71hQkpeex+zfDiHBFe+6FJd0POOqmk3YbF wQStATjMQcxegNIYQBgZmw4tZf2skk97vCg8omlm9g9TsOvhOoGudx/FZgtK8md2QY/b aeHQ+j74DGyU+M+YVGia9JlaT3gY8UHtP98LGT7pCrqU8rCukOSwpE5KwOi2xUwIMCi5 63TQ== X-Forwarded-Encrypted: i=1; AJvYcCVdCKNkZqhNGLlvtyjH3WsR2pUcfCr57dEidurlu0h9PkGH8fJktVCFw44dOw615n4m+kjyELjlJbWaF/4=@vger.kernel.org X-Gm-Message-State: AOJu0Yy6KMq1BjHqMI+Dr4kB1OLdNYSIm/X3XY2vMl0/3dsOOOiEDa88 G8h0KeafCdLSSHy9aSZR6gfv8wE+k26L2TfNbRKVKe6tedRtqa02klrq X-Gm-Gg: AY/fxX73XmnzgHZShKV6+AwtfTfdQegM4JVMOS0o/HdSe/PZCeR4ZHj8cQ5cmpa1m6/ oOQd96VqKDLoXucG10s/rYPEWXZ85SAobSO+E8dnuhdr/WkEmG8D+zcae9a2WvjlgFmBQ6rsrwP gpnc0EomE6Yny4hnwtT90fzsWgpzlBwLpskh1wwx10OICh8bWuJweMUyfRdFCSg9v0a9X00tRIZ nhwsAB+9AbBVgU+c2sLUmj0c3MpR9qw0YGgxBvXcodzUhLNniHgCJVa6gjtrnHtuQM3JhBMwsQu JoSHo83PWC2F2qD/XWSlCwQOssYYudo2b3n6Zqvo7JJGKatwEEtkmlYpylUDVqj5bHaM+Zjoev6 SOfXxnEugTQFYZXIFMkmr53r1ADV9Jauvi+R7HhXYbA5QUbZ/vpNyXqmQf0MfF2fIBri/dZZRC+ XAyePFlZJ2iYfULlIjv6Sv0I1UpTeQw7V2mIKKF072QrZLqPiNe/GAs47vOhGKmd8= X-Received: by 2002:a05:7301:1124:b0:2ae:56dc:eb21 with SMTP id 5a478bee46e88-2b6b4e8b378mr4155970eec.23.1768666986287; Sat, 17 Jan 2026 08:23:06 -0800 (PST) Received: from jason-hall-A520-B.. ([2600:8800:41a0:8000:419e:40b2:6190:81b4]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2b6b36564ffsm6271582eec.28.2026.01.17.08.23.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 17 Jan 2026 08:23:05 -0800 (PST) From: jkhall81 To: Greg Kroah-Hartman Cc: Alice Ryhl , =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= , Todd Kjos , Carlos Llamas , linux-kernel@vger.kernel.org, jkhall81 Subject: [PATCH rust-next] rust: binder: refactor context management to use KVVec Date: Sat, 17 Jan 2026 09:22:42 -0700 Message-ID: <20260117162242.950194-1-jason.kei.hall@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 intrusive linked list management in context.rs with KVVec. This modernization 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 Link: https://github.com/rust-for-linux/linux/issues/1215 Signed-off-by: jkhall81 --- drivers/android/binder/context.rs | 73 ++++++++++++++----------------- drivers/android/binder/process.rs | 4 +- 2 files changed, 36 insertions(+), 41 deletions(-) diff --git a/drivers/android/binder/context.rs b/drivers/android/binder/con= text.rs index 3d135ec03ca7..83fa8a16662b 100644 --- a/drivers/android/binder/context.rs +++ b/drivers/android/binder/context.rs @@ -3,8 +3,8 @@ // Copyright (C) 2025 Google LLC. =20 use kernel::{ - error::Error, - list::{List, ListArc, ListLinks}, + alloc::kvec::{KVVec, KVec}, + error::code::*, prelude::*, security, str::{CStr, CString}, @@ -17,22 +17,19 @@ kernel::sync::global_lock! { // SAFETY: We call `init` in the module initializer, so it's initializ= ed before first use. pub(crate) unsafe(uninit) static CONTEXTS: Mutex =3D Cont= extList { - list: List::new(), + contexts: KVVec::new(), }; } =20 pub(crate) struct ContextList { - list: List, + contexts: KVVec>, } =20 pub(crate) fn get_all_contexts() -> Result>> { let lock =3D CONTEXTS.lock(); - - let count =3D lock.list.iter().count(); - - let mut ctxs =3D KVec::with_capacity(count, GFP_KERNEL)?; - for ctx in &lock.list { - ctxs.push(Arc::from(ctx), GFP_KERNEL)?; + let mut ctxs =3D KVec::with_capacity(lock.contexts.len(), GFP_KERNEL)?; + for ctx in lock.contexts.iter() { + ctxs.push(ctx.clone(), GFP_KERNEL)?; } Ok(ctxs) } @@ -42,7 +39,7 @@ pub(crate) fn get_all_contexts() -> Result>> { struct Manager { node: Option, uid: Option, - all_procs: List, + all_procs: KVVec>, } =20 /// There is one context per binder file (/dev/binder, /dev/hwbinder, etc) @@ -51,28 +48,16 @@ pub(crate) struct Context { #[pin] manager: Mutex, pub(crate) name: CString, - #[pin] - links: ListLinks, -} - -kernel::list::impl_list_arc_safe! { - impl ListArcSafe<0> for Context { untracked; } -} -kernel::list::impl_list_item! { - impl ListItem<0> for Context { - using ListLinks { self.links }; - } } =20 impl Context { pub(crate) fn new(name: &CStr) -> Result> { let name =3D CString::try_from(name)?; - let list_ctx =3D ListArc::pin_init::( + let ctx =3D Arc::pin_init( try_pin_init!(Context { name, - links <- ListLinks::new(), manager <- kernel::new_mutex!(Manager { - all_procs: List::new(), + all_procs: KVVec::new(), node: None, uid: None, }, "Context::manager"), @@ -80,8 +65,7 @@ pub(crate) fn new(name: &CStr) -> Result> { GFP_KERNEL, )?; =20 - let ctx =3D list_ctx.clone_arc(); - CONTEXTS.lock().list.push_back(list_ctx); + CONTEXTS.lock().contexts.push(ctx.clone(), GFP_KERNEL)?; =20 Ok(ctx) } @@ -90,17 +74,24 @@ pub(crate) fn new(name: &CStr) -> Result> { /// /// No-op if called twice. pub(crate) fn deregister(&self) { - // SAFETY: We never add the context to any other linked list than = this one, so it is either - // in this list, or not in any list. - unsafe { CONTEXTS.lock().list.remove(self) }; + // Safe removal using retain + CONTEXTS.lock().contexts.retain(|c| { + let p1 =3D Arc::as_ptr(c); + let p2 =3D self as *const Context; + p1 !=3D p2 + }); } =20 - pub(crate) fn register_process(self: &Arc, proc: ListArc) { + pub(crate) fn register_process(self: &Arc, proc: Arc) -= > 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) } =20 pub(crate) fn deregister_process(self: &Arc, proc: &Process) { @@ -108,8 +99,12 @@ pub(crate) fn deregister_process(self: &Arc, proc= : &Process) { pr_err!("Context::deregister_process called on the wrong conte= xt."); 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 =3D Arc::as_ptr(p); + let p2 =3D proc as *const Process; + p1 !=3D p2 + }); } =20 pub(crate) fn set_manager_node(&self, node_ref: NodeRef) -> Result { @@ -160,11 +155,9 @@ pub(crate) fn for_each_proc(&self, mut func: F) =20 pub(crate) fn get_all_procs(&self) -> Result>> { let lock =3D self.manager.lock(); - let count =3D lock.all_procs.iter().count(); - - let mut procs =3D KVec::with_capacity(count, GFP_KERNEL)?; - for proc in &lock.all_procs { - procs.push(Arc::from(proc), GFP_KERNEL)?; + let mut procs =3D KVec::with_capacity(lock.all_procs.len(), GFP_KE= RNEL)?; + for proc in lock.all_procs.iter() { + procs.push(Arc::clone(proc), GFP_KERNEL)?; } Ok(procs) } diff --git a/drivers/android/binder/process.rs b/drivers/android/binder/pro= cess.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, cred: ARef) -> Re= sult> { )?; =20 let process =3D list_process.clone_arc(); - process.ctx.register_process(list_process); + process + .ctx + .register_process(Arc::from(list_process.as_arc_borrow()))?; =20 Ok(process) } --=20 2.43.0