From nobody Thu Apr 2 23:55:46 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 38A6A1FF1B4; Mon, 16 Feb 2026 14:10:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771251026; cv=none; b=cE6/AlU3zNuZ+ZYCGxdJSTzrHiEkzDAPlnTFII4vxaR5M3k/fSU51I8oSS7edRd6X9uJsGnlgBbcQ9JpwUCXKHRpB4nEQhWp+GioHT+mrlnF6y+Bxxku66N9Nohcy5cI6QeppqzJRNe8uYmLafRzfCA9ARyCk48XUls14jyLxao= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771251026; c=relaxed/simple; bh=AgpLkytILqp5XFalX4tUy0u26qDtL1NchHt6BYuns1U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Jtd+0YqUJD0L0IIpUPcaDJEL+HGJelDqq1CcDAQCadFZ07McMphcI1qY96lCnQpwT98qzvp0NKtNp1mcH0uXNp/9CcdQ4dwAqS/loGvH37lOQwud7AleVYRFm18pTPdFyNsFAKfaioKwkhO4x86tSiJVGmaAJxWZMLWy0O0x50g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZphKK1PP; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ZphKK1PP" Received: by smtp.kernel.org (Postfix) with ESMTPS id EE76EC19424; Mon, 16 Feb 2026 14:10:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1771251026; bh=AgpLkytILqp5XFalX4tUy0u26qDtL1NchHt6BYuns1U=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=ZphKK1PPXaR4ZdGx+3ArDTQnoyw/i5DVAQLH07/AhAkEGOj31fC0Gd0F9ENSI7cvx eSFnAej0hrWtD+np1AmIVkMh3vmO5ocTBPRajYQkDCWFN7oaepx/c3QkgahIX5ebZE SGv6nopKYxV6D5Ik8UyW+edu01j5oZbxBF42EokS39yt50ryDdtraWKT+edwLa2W71 Zy6m6bSRwJCY+KJN2w8PMP0aCNbZeqgI/Yt3txtQ2gu5PcgKzDAbqiRpMNiPb9mNfp VNwm5Esxwr2b9dstzOhmIPlIa4zo0KXDhFuRU4OFnKx8Im/wNd8rD03zk94oP7EMhk Fig92u37rt9ng== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id D65FBE81A28; Mon, 16 Feb 2026 14:10:25 +0000 (UTC) From: Shivam Kalra via B4 Relay Date: Mon, 16 Feb 2026 19:39:55 +0530 Subject: [PATCH v6 1/3] rust: kvec: implement shrink_to for KVVec Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-binder-shrink-vec-v3-v6-1-ece8e8593e53@zohomail.in> References: <20260216-binder-shrink-vec-v3-v6-0-ece8e8593e53@zohomail.in> In-Reply-To: <20260216-binder-shrink-vec-v3-v6-0-ece8e8593e53@zohomail.in> To: Danilo Krummrich , Lorenzo Stoakes , Vlastimil Babka , "Liam R. Howlett" , Uladzislau Rezki , Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Greg Kroah-Hartman , =?utf-8?q?Arve_Hj=C3=B8nnev=C3=A5g?= , Todd Kjos , Christian Brauner , Carlos Llamas Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Shivam Kalra X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1771251023; l=6422; i=shivamkalra98@zohomail.in; s=20260212; h=from:subject:message-id; bh=exX1F9hesuRNjkscJh7+rzWsyVNj6Wy6hrwe5bFtXRg=; b=dgYJE8hakwJKUIQqIzke6Ye+foWFwLy7Lmu9YdmDb35sknYxlMEd62PSKuOVeeVkoSSz8kxwY 4pK5vxB/Ns5DlrEMZrM43RjFc4jgzmcUkaW3e3ODGAycFjdStBR2ZlV X-Developer-Key: i=shivamkalra98@zohomail.in; a=ed25519; pk=9Q+S1LD/xjbjL7bEaLIlwRADBwU/6LJq7lYm8LFrkQE= X-Endpoint-Received: by B4 Relay for shivamkalra98@zohomail.in/20260212 with auth_id=633 X-Original-From: Shivam Kalra Reply-To: shivamkalra98@zohomail.in From: Shivam Kalra Implement shrink_to method specifically for `KVVec` (i.e., `Vec`). `shrink_to` reduces the vector's capacity to a specified minimum. For kmalloc-backed allocations, the method delegates to realloc(), letting the allocator decide whether shrinking is worthwhile. For vmalloc-backed allocations (detected via is_vmalloc_addr), shrinking only occurs if at least one page of memory can be freed, using an explicit alloc+copy+free since vrealloc does not yet support in-place shrinking. A TODO note marks this for future replacement with a generic shrink_to for all allocators that uses A::realloc() once the underlying allocators properly support shrinking via realloc. Suggested-by: Alice Ryhl Suggested-by: Danilo Krummrich Reviewed-by: Alice Ryhl Acked-by: Danilo Krummrich Signed-off-by: Shivam Kalra --- rust/kernel/alloc/kvec.rs | 114 ++++++++++++++++++++++++++++++++++++++++++= +++- 1 file changed, 113 insertions(+), 1 deletion(-) diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs index ac8d6f763ae81..e7bc439538e49 100644 --- a/rust/kernel/alloc/kvec.rs +++ b/rust/kernel/alloc/kvec.rs @@ -9,7 +9,10 @@ }; use crate::{ fmt, - page::AsPageIter, // + page::{ + AsPageIter, + PAGE_SIZE, // + }, }; use core::{ borrow::{Borrow, BorrowMut}, @@ -734,6 +737,115 @@ pub fn retain(&mut self, mut f: impl FnMut(&mut T) ->= bool) { self.truncate(num_kept); } } +// TODO: This is a temporary KVVec-specific implementation. It should be r= eplaced with a generic +// `shrink_to()` for `impl Vec` that uses `A::reall= oc()` once the +// underlying allocators properly support shrinking via realloc. +impl Vec { + /// Shrinks the capacity of the vector with a lower bound. + /// + /// The capacity will remain at least as large as both the length and = the supplied value. + /// If the current capacity is less than the lower limit, this is a no= -op. + /// + /// For `kmalloc` allocations, this delegates to `realloc()`, which de= cides whether + /// shrinking is worthwhile. For `vmalloc` allocations, shrinking only= occurs if the + /// operation would free at least one page of memory, and performs a d= eep copy since + /// `vrealloc` does not yet support in-place shrinking. + /// + /// # Examples + /// + /// ``` + /// // Allocate enough capacity to span multiple pages. + /// let elements_per_page =3D kernel::page::PAGE_SIZE / core::mem::siz= e_of::(); + /// let mut v =3D KVVec::with_capacity(elements_per_page * 4, GFP_KERN= EL)?; + /// v.push(1, GFP_KERNEL)?; + /// v.push(2, GFP_KERNEL)?; + /// + /// v.shrink_to(0, GFP_KERNEL)?; + /// # Ok::<(), Error>(()) + /// ``` + pub fn shrink_to(&mut self, min_capacity: usize, flags: Flags) -> Resu= lt<(), AllocError> { + let target_cap =3D core::cmp::max(self.len(), min_capacity); + + if self.capacity() <=3D target_cap { + return Ok(()); + } + + if Self::is_zst() { + return Ok(()); + } + + // For kmalloc allocations, delegate to realloc() and let the allo= cator decide + // whether shrinking is worthwhile. + // + // SAFETY: `self.ptr` points to a valid `KVmalloc` allocation. + if !unsafe { bindings::is_vmalloc_addr(self.ptr.as_ptr().cast()) }= { + let new_layout =3D ArrayLayout::::new(target_cap).map_err(|= _| AllocError)?; + + // SAFETY: + // - `self.ptr` is valid and was previously allocated with `KV= malloc`. + // - `self.layout` matches the `ArrayLayout` of the preceding = allocation. + let ptr =3D unsafe { + KVmalloc::realloc( + Some(self.ptr.cast()), + new_layout.into(), + self.layout.into(), + flags, + NumaNode::NO_NODE, + )? + }; + + self.ptr =3D ptr.cast(); + self.layout =3D new_layout; + return Ok(()); + } + + // Only shrink if we would free at least one page. + let current_size =3D self.capacity() * core::mem::size_of::(); + let target_size =3D target_cap * core::mem::size_of::(); + let current_pages =3D current_size.div_ceil(PAGE_SIZE); + let target_pages =3D target_size.div_ceil(PAGE_SIZE); + + if current_pages <=3D target_pages { + return Ok(()); + } + + if target_cap =3D=3D 0 { + if !self.layout.is_empty() { + // SAFETY: + // - `self.ptr` was previously allocated with `KVmalloc`. + // - `self.layout` matches the `ArrayLayout` of the preced= ing allocation. + unsafe { KVmalloc::free(self.ptr.cast(), self.layout.into(= )) }; + } + self.ptr =3D NonNull::dangling(); + self.layout =3D ArrayLayout::empty(); + return Ok(()); + } + + // SAFETY: `target_cap <=3D self.capacity()` and original capacity= was valid. + let new_layout =3D unsafe { ArrayLayout::::new_unchecked(target= _cap) }; + + let new_ptr =3D KVmalloc::alloc(new_layout.into(), flags, NumaNode= ::NO_NODE)?; + + // SAFETY: + // - `self.as_ptr()` is valid for reads of `self.len()` elements o= f `T`. + // - `new_ptr` is valid for writes of at least `target_cap >=3D se= lf.len()` elements. + // - The two allocations do not overlap since `new_ptr` is freshly= allocated. + // - Both pointers are properly aligned for `T`. + unsafe { + ptr::copy_nonoverlapping(self.as_ptr(), new_ptr.as_ptr().cast:= :(), self.len()) + }; + + // SAFETY: + // - `self.ptr` was previously allocated with `KVmalloc`. + // - `self.layout` matches the `ArrayLayout` of the preceding allo= cation. + unsafe { KVmalloc::free(self.ptr.cast(), self.layout.into()) }; + + self.ptr =3D new_ptr.cast::(); + self.layout =3D new_layout; + + Ok(()) + } +} =20 impl Vec { /// Extend the vector by `n` clones of `value`. --=20 2.43.0 From nobody Thu Apr 2 23:55:46 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 38ACD265CA6; Mon, 16 Feb 2026 14:10:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771251026; cv=none; b=sKVmoNKb7p3kfc7h8U9shgbFt2ALGzxBHD9vEVKKfiRhww6czD28pLGS3OQK5gqFah2Ft/b0v6xQ4/tNg1CsNn23yGoZSFXAfmFxk41LyuohIa7Fs/jNOGLsieW8ANGr5tEuTuz6lTdLJQJW2VY9T5X4aS6UPMhN/R73CP2XRXo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771251026; c=relaxed/simple; bh=vHYRkFkvW8Pz4rcNGydFyXZ0N8Tg8sV3J3F01TYdiOk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=haJC3ZOh8lDBOGQoieb/wX1uSnlXR6qaNNBzky29EWp4oE/1s6vE2oPzubrZ2cK3OU5Xlw3g1mdT53fWfmtQ5VHM0DUbch2sw9jOZyuRljMSsMn27AgicWNXmsSBStFg3HLNpZshUcsHILycDm0RYm77XBSwucUBcIZAk6WuTy4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=CwO9eA5S; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="CwO9eA5S" Received: by smtp.kernel.org (Postfix) with ESMTPS id 08561C2BCAF; Mon, 16 Feb 2026 14:10:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1771251026; bh=vHYRkFkvW8Pz4rcNGydFyXZ0N8Tg8sV3J3F01TYdiOk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=CwO9eA5SOE/acS+Qj5mWU0T2yqeJF6oJRPQNRjhcjhCEPPzdp2EPH3Wr+SrRF2ZZ1 i9YvL2tvzq5YY16aRn4mEnm0zdm+0wwX8Vo2inw05hCg+WXla8xW+KQncDVTDoF7d9 wSBSGHObsb+HT0e+zMWjTTNbUSZjV4npvHS6ZqYXPGnTcpC0zpnn/fZqq4xCtVUbWA mGE2y6UORExKhMgVIASB0GfxeCKzRrqITowYwAOIYzUTLpD0rJp1gADUN16uD6GUv3 mNzywabtcAdT2VszdJWadq76jl98nksqWIaE3G6WP8qdkxTlCKZXx2RFJ2ws9zCzhn hCc4PvKtfEDJQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id F09C2E81A29; Mon, 16 Feb 2026 14:10:25 +0000 (UTC) From: Shivam Kalra via B4 Relay Date: Mon, 16 Feb 2026 19:39:56 +0530 Subject: [PATCH v6 2/3] rust: alloc: add KUnit tests for KVVec shrink_to Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-binder-shrink-vec-v3-v6-2-ece8e8593e53@zohomail.in> References: <20260216-binder-shrink-vec-v3-v6-0-ece8e8593e53@zohomail.in> In-Reply-To: <20260216-binder-shrink-vec-v3-v6-0-ece8e8593e53@zohomail.in> To: Danilo Krummrich , Lorenzo Stoakes , Vlastimil Babka , "Liam R. Howlett" , Uladzislau Rezki , Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Greg Kroah-Hartman , =?utf-8?q?Arve_Hj=C3=B8nnev=C3=A5g?= , Todd Kjos , Christian Brauner , Carlos Llamas Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Shivam Kalra X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1771251023; l=4392; i=shivamkalra98@zohomail.in; s=20260212; h=from:subject:message-id; bh=2yjjFzKFJiIABUmHBwniBs7X17u+zlrGDX69Rd2mee4=; b=4B/+UE094N6Ev8RZfcW5pUCLgo9qywLj+dRf1EV0eLBXb14bdk7WE6MCepfDBCO24f40jSGVn M1Z0OF06Rb1AIZWwypz+s7o8+9GO9Dw3V914lMW83QPt9XXSl4+a/QE X-Developer-Key: i=shivamkalra98@zohomail.in; a=ed25519; pk=9Q+S1LD/xjbjL7bEaLIlwRADBwU/6LJq7lYm8LFrkQE= X-Endpoint-Received: by B4 Relay for shivamkalra98@zohomail.in/20260212 with auth_id=633 X-Original-From: Shivam Kalra Reply-To: shivamkalra98@zohomail.in From: Shivam Kalra Add comprehensive KUnit tests for the shrink_to method for KVVec. The tests verify: - Basic shrinking from multiple pages to fewer pages with data integrity preservation - Empty vector shrinking to zero capacity - No-op behavior when shrinking to a larger capacity than current - Respect for min_capacity parameter when larger than vector length These tests ensure that the shrinking logic correctly identifies when memory can be reclaimed (by freeing at least one page) and that data integrity is maintained throughout shrink operations. Reviewed-by: Alice Ryhl Acked-by: Danilo Krummrich Signed-off-by: Shivam Kalra --- rust/kernel/alloc/kvec.rs | 102 ++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 102 insertions(+) diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs index e7bc439538e4..6438385e4322 100644 --- a/rust/kernel/alloc/kvec.rs +++ b/rust/kernel/alloc/kvec.rs @@ -1510,4 +1510,106 @@ fn add(value: &mut [bool]) { func.push_within_capacity(false).unwrap(); } } + + #[test] + fn test_kvvec_shrink_to() { + use crate::page::PAGE_SIZE; + + // Create a vector with capacity spanning multiple pages. + let mut v =3D KVVec::::with_capacity(PAGE_SIZE * 4, GFP_KERNEL= ).unwrap(); + + // Add a few elements. + v.push(1, GFP_KERNEL).unwrap(); + v.push(2, GFP_KERNEL).unwrap(); + v.push(3, GFP_KERNEL).unwrap(); + + let initial_capacity =3D v.capacity(); + assert!(initial_capacity >=3D PAGE_SIZE * 4); + + // Shrink to a capacity that would free at least one page. + v.shrink_to(PAGE_SIZE, GFP_KERNEL).unwrap(); + + // Capacity should have been reduced. + assert!(v.capacity() < initial_capacity); + assert!(v.capacity() >=3D PAGE_SIZE); + + // Elements should be preserved. + assert_eq!(v.len(), 3); + assert_eq!(v[0], 1); + assert_eq!(v[1], 2); + assert_eq!(v[2], 3); + + // Shrink to zero (should shrink to len). + v.shrink_to(0, GFP_KERNEL).unwrap(); + + // Capacity should be at least the length. + assert!(v.capacity() >=3D v.len()); + + // Elements should still be preserved. + assert_eq!(v.len(), 3); + assert_eq!(v[0], 1); + assert_eq!(v[1], 2); + assert_eq!(v[2], 3); + } + + #[test] + fn test_kvvec_shrink_to_empty() { + use crate::page::PAGE_SIZE; + + // Create a vector with large capacity but no elements. + let mut v =3D KVVec::::with_capacity(PAGE_SIZE * 4, GFP_KERNEL= ).unwrap(); + + assert!(v.is_empty()); + + // Shrink empty vector to zero. + v.shrink_to(0, GFP_KERNEL).unwrap(); + + // Should have freed the allocation. + assert_eq!(v.capacity(), 0); + assert!(v.is_empty()); + } + + #[test] + fn test_kvvec_shrink_to_no_op() { + use crate::page::PAGE_SIZE; + + // Create a small vector. + let mut v =3D KVVec::::with_capacity(PAGE_SIZE, GFP_KERNEL).un= wrap(); + v.push(1, GFP_KERNEL).unwrap(); + + let capacity_before =3D v.capacity(); + + // Try to shrink to a capacity larger than current - should be no-= op. + v.shrink_to(capacity_before + 100, GFP_KERNEL).unwrap(); + + assert_eq!(v.capacity(), capacity_before); + assert_eq!(v.len(), 1); + assert_eq!(v[0], 1); + } + + #[test] + fn test_kvvec_shrink_to_respects_min_capacity() { + use crate::page::PAGE_SIZE; + + // Create a vector with large capacity. + let mut v =3D KVVec::::with_capacity(PAGE_SIZE * 4, GFP_KERNEL= ).unwrap(); + + // Add some elements. + for i in 0..10u8 { + v.push(i, GFP_KERNEL).unwrap(); + } + + // Shrink to a min_capacity larger than length. + let min_cap =3D PAGE_SIZE * 2; + v.shrink_to(min_cap, GFP_KERNEL).unwrap(); + + // Capacity should be at least min_capacity. + assert!(v.capacity() >=3D min_cap); + + // All elements preserved. + assert_eq!(v.len(), 10); + for i in 0..10u8 { + assert_eq!(v[i as usize], i); + } + } } --=20 2.43.0 From nobody Thu Apr 2 23:55:46 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7979D30F551; Mon, 16 Feb 2026 14:10:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771251026; cv=none; b=G+L6vq1sA8PuLZWUwHxRO+i1954Iby4ZFh5EmjvUJTGJGwepmcCGxSLYPJFz/H4KBgWvJGolivoomWzx65FrXYFxMUHW+VpvWljQg5Zle/7jnti0eoSYw+FVSKyF2f0yQ4GjdftUaemsuQ8/ZtTcCFTdwGd9lfWP+7Byp7r3VnE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771251026; c=relaxed/simple; bh=rfVAM/ZHzx5qdWkfO8blN25XFekil5Ja5oqXZc5O6F8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CdkHGIyaoXRmIOLQHtHpV58MlFfrPjXkcFnFC3WOGDMldhf9swDNs2WNrc4gF5XANx+NLU0SMYIYlnY810wFwL2TV2GdjmHJjrR4r6X0ojmtQ7vBTAGYoq5otHqNxJ2DGiYOmdreFcnfR0r9oRXjkHBNIrz0T+1k1aclMBEe2us= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qENupr8n; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="qENupr8n" Received: by smtp.kernel.org (Postfix) with ESMTPS id 4AC78C19423; Mon, 16 Feb 2026 14:10:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1771251026; bh=rfVAM/ZHzx5qdWkfO8blN25XFekil5Ja5oqXZc5O6F8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=qENupr8nkkXpgGimRWCfkHsxQVjYTtGsON6Bv+ZMH9SpUtaWxpSKrSrNev9zJ1joj QuCtemlYigPhaM8kdMls3Tj+m7GiF05MGwmIpCBU1yM0bb1/2qMlU6VV2IRQWQRBBm d1iI8VPCsoSTx6mLEhLDK006k1g+Q9XTJmq/8d2uwhBC6mOwekMrZHo6UaEyIw/ENt N+l1PDYhUzBdBf912s0ZbYW3EZXCXN/5+okVAA/w5SU+1f2T2mvuaS/1/0Zx/ZDLoB 4Jz9z+hQk4RpWuItYzWKggNKOHZOlrmIL8YLgcOAsa0xyK3KaUi1w1ezcDa3TS/NUR GeoresLqEIc+Q== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3AB82E81A29; Mon, 16 Feb 2026 14:10:26 +0000 (UTC) From: Shivam Kalra via B4 Relay Date: Mon, 16 Feb 2026 19:39:57 +0530 Subject: [PATCH v6 3/3] rust_binder: shrink all_procs when deregistering processes Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-binder-shrink-vec-v3-v6-3-ece8e8593e53@zohomail.in> References: <20260216-binder-shrink-vec-v3-v6-0-ece8e8593e53@zohomail.in> In-Reply-To: <20260216-binder-shrink-vec-v3-v6-0-ece8e8593e53@zohomail.in> To: Danilo Krummrich , Lorenzo Stoakes , Vlastimil Babka , "Liam R. Howlett" , Uladzislau Rezki , Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Greg Kroah-Hartman , =?utf-8?q?Arve_Hj=C3=B8nnev=C3=A5g?= , Todd Kjos , Christian Brauner , Carlos Llamas Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Shivam Kalra X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1771251023; l=2098; i=shivamkalra98@zohomail.in; s=20260212; h=from:subject:message-id; bh=mnNtqRuXw+GbWwUNizt695eJI0LDj0bQ9V6oPxS8Ca8=; b=KUC991Pcb5s8ApAhRfN2CtCmZ8JCK0Is6X3B6+q+41igluWkXepMKJ45h5JRYeQzj2X/MfaXg W2EfiYUdYp9C2dRyOxEmgaHhOqB/YLKhv4+8ci7NA2x8565gvf00rxD X-Developer-Key: i=shivamkalra98@zohomail.in; a=ed25519; pk=9Q+S1LD/xjbjL7bEaLIlwRADBwU/6LJq7lYm8LFrkQE= X-Endpoint-Received: by B4 Relay for shivamkalra98@zohomail.in/20260212 with auth_id=633 X-Original-From: Shivam Kalra Reply-To: shivamkalra98@zohomail.in From: Shivam Kalra When a process is deregistered from the binder context, the all_procs vector may have significant unused capacity. Add logic to shrink the vector using a conservative strategy that prevents shrink-then-regrow oscillation. The shrinking strategy triggers when length drops below 1/4 of capacity, and shrinks to twice the current length rather than to the exact length. This provides hysteresis to avoid repeated reallocations when the process count fluctuates. The shrink operation uses GFP_KERNEL and is allowed to fail gracefully since it is purely an optimization. The vector remains valid and functional even if shrinking fails. Suggested-by: Alice Ryhl Reviewed-by: Alice Ryhl Signed-off-by: Shivam Kalra --- drivers/android/binder/context.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/android/binder/context.rs b/drivers/android/binder/con= text.rs index 9cf437c025a20..ddddb66b35571 100644 --- a/drivers/android/binder/context.rs +++ b/drivers/android/binder/context.rs @@ -94,6 +94,17 @@ pub(crate) fn deregister_process(self: &Arc, proc:= &Arc) { } let mut manager =3D self.manager.lock(); manager.all_procs.retain(|p| !Arc::ptr_eq(p, proc)); + + // Shrink the vector if it has significant unused capacity to avoi= d memory waste, + // but use a conservative strategy to prevent shrink-then-regrow o= scillation. + // Only shrink when length drops below 1/4 of capacity, and shrink= to twice the length. + let len =3D manager.all_procs.len(); + let cap =3D manager.all_procs.capacity(); + if len < cap / 4 { + // Shrink to twice the current length. Ignore allocation failu= res since this + // is just an optimization; the vector remains valid even if s= hrinking fails. + let _ =3D manager.all_procs.shrink_to(len * 2, GFP_KERNEL); + } } =20 pub(crate) fn set_manager_node(&self, node_ref: NodeRef) -> Result { --=20 2.43.0