From nobody Sun Feb 8 10:22:03 2026 Received: from mail-dy1-f176.google.com (mail-dy1-f176.google.com [74.125.82.176]) (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 2114A335BC6 for ; Sun, 18 Jan 2026 14:26:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768746392; cv=none; b=q0CCufNwh03oX8QXnJFPoGGrTIvgQFwITsxQ9sJBtMpDmUpYh1vRtcb17/kUn02O6TtnTcAsP6kdO/mUS4ejLhcnzgS0llFFbTeKpoYV8WkW/K+jerS+V1C2eiAObaxsk4cKWg0hDX7dIhqNtB5ee79fYVrm+MTW97VqU+6s994= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768746392; c=relaxed/simple; bh=s0cwsEgG7g9n4Hg+hiJoeBEv+lAIY6fNgwF2jLJh4do=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=rmIWrYgG6vchWfwh9wdt7HZH+iZM72Mn+LzvF27Ue0k5wC7GuyK64y6l0XoeIF+td4eNoVCPeuO8unYkP1mRuIOfkN3I3zGyv6kWKn434gqrh4r8dXyE3TQXpJxtIOYU8ZWWmKfOVW4lDIVa+D4nhSabtIZPpJAEnU9UbHCJwOw= 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=ClQ0qAjU; arc=none smtp.client-ip=74.125.82.176 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="ClQ0qAjU" Received: by mail-dy1-f176.google.com with SMTP id 5a478bee46e88-2ae61424095so3605885eec.1 for ; Sun, 18 Jan 2026 06:26:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1768746389; x=1769351189; 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=l68fmGn3uGtJbeW4EuRWDFel44wfPBgfn/qQavBDiKU=; b=ClQ0qAjUAYpqoIXRHL0yyGPrZ5MXeusS7qchA0s7TFsq2XdcyPMlhCRyTIw9zFyHDv nfr74ieHkOJEv09Hmv8paxvHElYjPzPmX+4rgBjUHZOrEhGk1B/1laaOst/SbdhyDkgq jymFJz10+stVhkePR9pV/e+d2XllRB4c+dejcOuBWMl6a3EjjASLLrhVKevG4qJIcKrq 3HI1GaMWW/Ov73zRsiYlfJ7sDOKX0EpW16PajZ0otpOtTm3LYkiboego4ZX7Gj+7WEOK GOSqL7l4yC5LkWpBqbj0TTZGndS4+hzZpRlXypbhKo+Oan7qeQzGrxDuxZe69xMP3Vq0 8IDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768746389; x=1769351189; 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=l68fmGn3uGtJbeW4EuRWDFel44wfPBgfn/qQavBDiKU=; b=vCOuJJ6bzAP7T2QoD5LAQp+Nn/lafkps6jNluIn5RgafvSO3U2Y4GDEg+9SBp6E4k4 kk86GdG2gU5yw8b6eNb8Eam5Y+kp00a3E/tEzcEtt4pjpjcsjiVrGX2M0+kME0HeAfHR 0HW//JZCAbyLCHenLemjj1YuRNTUDLNBPRH25C6NhtgHH7yjmZLAlM2GvK3Q9lU5LbJk a+hH2mhGfHjvtc1j47viujbFPFrYc3SRnzxYSNgv51lTPPUYjdeY5HnSTCFUXml0S4qm iIfECCRgZf5bktLvgMTj+m5S8BtxC7rYPuQl3gIakrTAx9oYHrh84ybIxQU1PPeWePYX 1Vhw== X-Forwarded-Encrypted: i=1; AJvYcCUqdSrrXeqZMy+8Fj1uO8RlvVxNn+ulRGqHWVaY8IyAh8sfvI2u388TeDkO7vsXuGO+JonGVh8drHp6rlk=@vger.kernel.org X-Gm-Message-State: AOJu0YyAu6noIcQTDpjVscTDueZa7cWs/aLY4YIKzGNyxmp1ISpKnVEV y4paEbZMjnfTj9bCzqe2t1T132fcG5ElCGeV1HitrUo5G9jMoh5G8IsX X-Gm-Gg: AY/fxX4rXqhDrBpXzM3sojE55dhkv8LWGQ4Q1dhCVkQlaQDZA/cAH1CqZh8jokN18Le qrTdmZdjscgYMb5821Wyy3PzgG+vOVugCZfT7tOlcPYcVcT036q8VuybnKi9L0coN/Gukps4nK5 q/iMC91yeABpn2qBbCRnfbDEw8+GBI4oeIi7j6jcIx7aTVJ5poq8Jh007FQn1wDgv/ByNO9XW1i w1gNXLW7+or0oaTPFSmg2qGWmakTXr3mMVgQC2dG8LBSm1SnLrdL0uUqD1ymDrjsF37MTeqq2be R7TJLO+wWhQHRUlClzQxBvjmBJxnvAsFEw+NM9DO9wCv2j2V624Yrax6CGxc6GF1or2gd85FdvQ q4v2Nb6yUfUk/GiMdSbhCprHqVlQFTgj1udy3/n+/85tenmN65nRVrLMocSoYaRCx9Ae9ThZTOZ 9NFaggJfrl74W7tOZkyEkX9DZy4pC/wkX4Y+4smFZy1bh43WIZuNLPSv/zzayiY3z1upRKY++fb A== X-Received: by 2002:a05:7300:cc14:b0:2ae:53a5:8ed4 with SMTP id 5a478bee46e88-2b6b4ea9443mr5241246eec.30.1768746388028; Sun, 18 Jan 2026 06:26:28 -0800 (PST) Received: from jason-hall-A520-B.. ([2600:8800:41a0:8000:46de:79e9:ba96:f42a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2b6b34c11c4sm9428742eec.1.2026.01.18.06.26.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Jan 2026 06:26:27 -0800 (PST) From: Jason Hall To: Greg Kroah-Hartman Cc: Alice Ryhl , =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= , Todd Kjos , Carlos Llamas , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Jason Hall Subject: [PATCH v2] rust_binder: refactor context management to use KVVec Date: Sun, 18 Jan 2026 07:26:23 -0700 Message-ID: <20260118142623.1188141-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 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 Link: https://github.com/rust-for-linux/linux/issues/1215 Signed-off-by: Jason Hall --- v2: - Used real name in Signed-off-by. - Updated subject prefix to 'rust_binder:' and removed 'rust-next'. - Changed return types from KVec to KVVec as request. - Added cc: rust-for-linux@vger.kernel.org to email. - Note: Kept manual loops for cloning because try_clone/from_iter helpers for KVVec are not currently available / I couldn't get it to work. --- drivers/android/binder/context.rs | 77 ++++++++++++++----------------- drivers/android/binder/process.rs | 4 +- 2 files changed, 38 insertions(+), 43 deletions(-) diff --git a/drivers/android/binder/context.rs b/drivers/android/binder/con= text.rs index 3d135ec03ca7..b3adab830b51 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>> { +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 KVVec::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 { @@ -158,13 +153,11 @@ pub(crate) fn for_each_proc(&self, mut func: F) } } =20 - pub(crate) fn get_all_procs(&self) -> Result>> { + 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 KVVec::with_capacity(lock.all_procs.len(), GFP_K= ERNEL)?; + 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