From nobody Thu Apr 2 23:57:12 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 D52A02853E0; Sat, 14 Feb 2026 20:35:31 +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=1771101331; cv=none; b=oEUmaYkn6f3FbROkE9zfUgftVgP/ldnKek5ksWY8fkiWoyTXWo08zMbqhrBpaqVBd43OkKOTwqNSCbs+ETpDZDOVxXyJzw37yXrORqCTfRTTrNYMj9f0s9PoYLDBOBqR+jiUK5pNRsevbfCcBopqE9YS9+YtURIXiBbHEYG/xyw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771101331; c=relaxed/simple; bh=DFzFq2+l6oRFWjsx6kkw3fVOrQ6Yd/TVaImOm3VVMtQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lLwP1epMGo9OwPxPU1MLm71u5v1fYqyY7hn9G2W+T2oUvJ3ZpOD486LD4FETdFns90kF9WXzOQAZ/XxiZ9Hh+mW4D37DkaFC9YIzmDc8mJwkOID2KIMoevc45jt8CJFjypD6gZhJ0WnGyFgOFoyZckYa9sUS0DnLblviAbKqjJM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KQl7cH0S; 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="KQl7cH0S" Received: by smtp.kernel.org (Postfix) with ESMTPS id 9012DC2BC9E; Sat, 14 Feb 2026 20:35:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1771101331; bh=DFzFq2+l6oRFWjsx6kkw3fVOrQ6Yd/TVaImOm3VVMtQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=KQl7cH0SB/n4JZSOTLEnFFeKYXXl6ZX4/ZQLSLpZFx2BIJFwgxTwhaZ6HJCq02HMI UDNeJdePJgx8HJYF6wBQI8q2u7c3VtyrWJG5f0e6j90JEvI8UXcqIGpDvrYWvoVEj6 ssHmTXbeEFgdClPIrSVhC+CN6Lqx3sXrKwm+W72qvZlN8Qof5hbkz6NaSeWH89oODS AD8LSQEnNaPknhhbG4H8tcxlSsXIElnSt21/RIEfmNrAft1EGx4yvwLDjOXo+HThmW jH8HXOAs6f7L0YhmPaxPoAV6o8n7SicYfDPx+Ce5/xL2CssZMMTql/X+ijy4lnDAZg wJO/EKb0nJj7w== 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 740A9EF5852; Sat, 14 Feb 2026 20:35:31 +0000 (UTC) From: Shivam Kalra via B4 Relay Date: Sun, 15 Feb 2026 02:05:21 +0530 Subject: [PATCH v5 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: <20260215-binder-shrink-vec-v3-v5-1-6e5e56d69766@zohomail.in> References: <20260215-binder-shrink-vec-v3-v5-0-6e5e56d69766@zohomail.in> In-Reply-To: <20260215-binder-shrink-vec-v3-v5-0-6e5e56d69766@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=1771101329; l=6328; i=shivamkalra98@zohomail.in; s=20260212; h=from:subject:message-id; bh=CNOdoVAKpifopKTG32k814tiFCi7KrBOMJnN4YVcgbY=; b=GLSleGN3AXLN7xb5N1298AIm4FNbkCx5fItdmTZ37q2ADEkF3stkblHXUXuPqVubnCZnySQYX fM8bo6AzHmHB7CZYCAKluJHmJR8YvlBC8PTIm92AvR8/gezbghtnZAD 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 Signed-off-by: Shivam Kalra Acked-by: Danilo Krummrich Reviewed-by: Alice Ryhl --- 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:57:12 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 D51EC9475; Sat, 14 Feb 2026 20:35:31 +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=1771101331; cv=none; b=m6XquddpRUto+seWwNTYv2R/iZu9Fmw2O/8QxvpyWX5ofIlObKmYNbhQzRM3C97goTucfnQfx88lnXzbXtPV3DpXRT6S+s8Wyni4xfkCiVr6bZDznPCXCPU/ujCd4BBFtO7Dd6sWxSgt50UJ6LY6ikBpuGuLv+1VhitNH6qspjY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771101331; c=relaxed/simple; bh=/8fDyia8o4qhEDArjQTMsRJrB31sRONRocRZfe8Q2RU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=OL4+LUDIyTXy8i7nG9TbqCsUvxZux/rDm9gtuIbEOdRGq5uURwg0iDHoFEQsS3mBJiYx63Gx+JdscX/4xQGs70H9nIVajBTTQ6f297qhjlsSNJTQHCu/nccT7q6f+xAqe502sPvJDuIx/kh7JIv8QdPZfnPgYZ8Wg2Rcj9V72L0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Yh4ASD9k; 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="Yh4ASD9k" Received: by smtp.kernel.org (Postfix) with ESMTPS id A6B13C2BCAF; Sat, 14 Feb 2026 20:35:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1771101331; bh=/8fDyia8o4qhEDArjQTMsRJrB31sRONRocRZfe8Q2RU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=Yh4ASD9kUi9VF6F28fnTp5GH/7bqPAcdm8xCcx7o3uIWg/q+6LtKaIPiufomMrPIJ ancvsx8yPK/lN88zwUI6h8x8kVLqKko+EZkCPVczh9N9yw0cVUzu9mCC+rDnJ9hrrj iFJgSw7a3T4uPNWAlbP52HiEK0B6MSV+nUWMlLV9uqBVnMUGiEnQoQgKy2IImecZWC L+554CAErd4M1zeA3RCqoUZqo+wpiuioo90FLyStFk2IIY4kgfg/iKuDKJwpgVMwuu pyxhKXEMETqvCOrqFZoulwyJrae9ijj+w2fkAjswQo7cEJCle8bGzKQ/25PAYmGos5 bsXaJypxaWwyw== 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 96B9EEF5855; Sat, 14 Feb 2026 20:35:31 +0000 (UTC) From: Shivam Kalra via B4 Relay Date: Sun, 15 Feb 2026 02:05:22 +0530 Subject: [PATCH v5 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: <20260215-binder-shrink-vec-v3-v5-2-6e5e56d69766@zohomail.in> References: <20260215-binder-shrink-vec-v3-v5-0-6e5e56d69766@zohomail.in> In-Reply-To: <20260215-binder-shrink-vec-v3-v5-0-6e5e56d69766@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=1771101329; l=4784; i=shivamkalra98@zohomail.in; s=20260212; h=from:subject:message-id; bh=DATHu82lPNoM1l+7bA4EkUbEsD7D8aJFixyhUVHLl+w=; b=1igZ3RJ30avx6gsaCtc5fSESgdKyN0Kd/3WAKUxy6Pd2MuHdk7PD4m3MgLrZNjn0T/dfpZUXl Wxw0f1UjofjDcB88oIPndAxqk9a/eNmydSemRcxN97BTxQ1rL7DGNSV 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. Signed-off-by: Shivam Kalra Acked-by: Danilo Krummrich Reviewed-by: Alice Ryhl --- rust/kernel/alloc/kvec.rs | 112 ++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 112 insertions(+) diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs index e7bc439538e4..0d5d69296a9f 100644 --- a/rust/kernel/alloc/kvec.rs +++ b/rust/kernel/alloc/kvec.rs @@ -1510,4 +1510,116 @@ fn add(value: &mut [bool]) { func.push_within_capacity(false).unwrap(); } } + + #[test] + fn test_kvvec_shrink_to() { + use crate::page::PAGE_SIZE; + + // Calculate elements per page for u32. + let elements_per_page =3D PAGE_SIZE / core::mem::size_of::(); + + // Create a vector with capacity spanning multiple pages. + let mut v =3D KVVec::::with_capacity(elements_per_page * 4, G= FP_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 elements_per_page * 4); + + // Shrink to a capacity that would free at least one page. + v.shrink_to(elements_per_page, GFP_KERNEL).unwrap(); + + // Capacity should have been reduced. + assert!(v.capacity() < initial_capacity); + assert!(v.capacity() >=3D elements_per_page); + + // 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; + + let elements_per_page =3D PAGE_SIZE / core::mem::size_of::(); + + // Create a vector with large capacity but no elements. + let mut v =3D KVVec::::with_capacity(elements_per_page * 4, G= FP_KERNEL).unwrap(); + + assert!(v.is_empty()); + let initial_capacity =3D v.capacity(); + + // Shrink empty vector to zero. + v.shrink_to(0, GFP_KERNEL).unwrap(); + + // Should have freed the allocation. + assert!(v.capacity() < initial_capacity); + assert!(v.is_empty()); + } + + #[test] + fn test_kvvec_shrink_to_no_op() { + use crate::page::PAGE_SIZE; + + let elements_per_page =3D PAGE_SIZE / core::mem::size_of::(); + + // Create a small vector. + let mut v =3D KVVec::::with_capacity(elements_per_page, GFP_K= ERNEL).unwrap(); + 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; + + let elements_per_page =3D PAGE_SIZE / core::mem::size_of::(); + + // Create a vector with large capacity. + let mut v =3D KVVec::::with_capacity(elements_per_page * 4, G= FP_KERNEL).unwrap(); + + // Add some elements. + for i in 0..10 { + v.push(i, GFP_KERNEL).unwrap(); + } + + // Shrink to a min_capacity larger than length. + let min_cap =3D elements_per_page * 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..10 { + assert_eq!(v[i as usize], i); + } + } } --=20 2.43.0 From nobody Thu Apr 2 23:57:12 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 E783E28CF5F; Sat, 14 Feb 2026 20:35:31 +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=1771101332; cv=none; b=lwHyO2yOLSiwMl/6qslIj7iRwv8jyIlI9fi9kj4PtFovz6L6iC7js8mnRiDg2tSNTq3izI478Fsvm4cEVYbdjOG4NhsI1Aeh3ILQX6RfD52/vY2K2SIi7jvmUczFfZcVo1pEjNp1SyOxWUpM8Kr0HX91k+VJS5u2YwH9Bo9h1IE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771101332; c=relaxed/simple; bh=7rTjjHmVbvTMCZ+dJlkHV6ttiO6Ve3s67Dplq47uUDw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tz7+7QMbsKfxpkA6l6oO8FpanXZ0bOnlQMeR0huNBdUUts2qJSyuB4RtBhkPqI/0pE53EZn8rncEdjYWl1Sj3tqa80TkdsdW3emV6lqJPULgNvmsJVYC7QcC+2Yw7V2LWTZ0sDI1ObYB959Kf9sM5H5ltn/MWIPqaGeU7AWLsAs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dAj5hNIp; 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="dAj5hNIp" Received: by smtp.kernel.org (Postfix) with ESMTPS id C0631C4AF0B; Sat, 14 Feb 2026 20:35:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1771101331; bh=7rTjjHmVbvTMCZ+dJlkHV6ttiO6Ve3s67Dplq47uUDw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:Reply-To:From; b=dAj5hNIpKVkkfjC6+fUeDkr61GbesFldapQABZuhy5zBmUckf8ReOmA5ZyJOxu3+b 3ba+Itw3Dy0du1vrVZiaK1hX/c/myjF/0SXNiLiDGcMuXnmW5B1LclL15XAVpC1G80 /394/qRIR3fcEbTzHDvmtJWcUmO9l3jtcEjWP1SPO7/MRiwY5AMEwCKi/KcjwTWP3b NBJVn5RATFvRMSwGQ86A9XkJ06iPWIKRupnswmXV4g9wZ26F63xIjf7ZR0xQLryiVE mhx6XP5+48TaY35R7a8DwIsKsvEtwlC/FXzuWEPAr5wf/qeZmhZdcdOT207C7pDpG8 aLnZEav22qqxg== 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 B1984EF584C; Sat, 14 Feb 2026 20:35:31 +0000 (UTC) From: Shivam Kalra via B4 Relay Date: Sun, 15 Feb 2026 02:05:23 +0530 Subject: [PATCH v5 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: <20260215-binder-shrink-vec-v3-v5-3-6e5e56d69766@zohomail.in> References: <20260215-binder-shrink-vec-v3-v5-0-6e5e56d69766@zohomail.in> In-Reply-To: <20260215-binder-shrink-vec-v3-v5-0-6e5e56d69766@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=1771101329; l=2050; i=shivamkalra98@zohomail.in; s=20260212; h=from:subject:message-id; bh=7FV6uKzz4TJqB7MKxHeO755/zc8FAEv6EPYTU8loKcE=; b=4//76mOxNdGg1G1UwGPMDljOwlmA6xOOV7+xCKJGo6mFMRYT7XcNYU5aCd8YSQWi8P83nsliy xNL9aU4Df7KA4ngR+N2CbkeGPBnxfM4uoTqtxSKoC+uYxqXdVQDfEOi 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 Signed-off-by: Shivam Kalra Acked-by: Danilo Krummrich Reviewed-by: Alice Ryhl --- 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