From a7c066a30e0b2c878c9b52db1a6832a543baf07b Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Fri, 13 Jun 2025 11:29:25 +0000 Subject: [PATCH] ANDROID: rust_binder: access lru list through private data When changing Rust Binder to use the new alloc_shrinker(), the layout was changed so that lru_list is no longer stored next to the shrinker object, but some shrinker callbacks were not updated to reflect that. Thus, access the lru list through the shrinker's private data pointer, instead of using a container_of operation. Bug: 424727800 Change-Id: Iac09b2d81e555c3554101231de701dfa79b0e644 Signed-off-by: Alice Ryhl --- drivers/android/binder/page_range.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/android/binder/page_range.rs b/drivers/android/binder/page_range.rs index 75d9f48e3c66..02ba111e01d2 100644 --- a/drivers/android/binder/page_range.rs +++ b/drivers/android/binder/page_range.rs @@ -93,6 +93,7 @@ impl Shrinker { unsafe { ptr::addr_of_mut!((*shrinker).count_objects).write(Some(rust_shrink_count)); ptr::addr_of_mut!((*shrinker).scan_objects).write(Some(rust_shrink_scan)); + ptr::addr_of_mut!((*shrinker).private_data).write(self.list_lru.get().cast()); } // SAFETY: The new shrinker has been fully initialized, so we can register it. @@ -655,11 +656,10 @@ unsafe extern "C" fn rust_shrink_count( shrink: *mut bindings::shrinker, _sc: *mut bindings::shrink_control, ) -> c_ulong { - // SAFETY: This method is only used with the `Shrinker` type, and the cast is valid since - // `shrinker` is the first field of a #[repr(C)] struct. - let shrinker = unsafe { &*shrink.cast::() }; + // SAFETY: We can access our own private data. + let list_lru = unsafe { (*shrink).private_data.cast::() }; // SAFETY: Accessing the lru list is okay. Just an FFI call. - unsafe { bindings::list_lru_count(shrinker.list_lru.get()) } + unsafe { bindings::list_lru_count(list_lru) } } #[no_mangle] @@ -667,9 +667,8 @@ unsafe extern "C" fn rust_shrink_scan( shrink: *mut bindings::shrinker, sc: *mut bindings::shrink_control, ) -> c_ulong { - // SAFETY: This method is only used with the `Shrinker` type, and the cast is valid since - // `shrinker` is the first field of a #[repr(C)] struct. - let shrinker = unsafe { &*shrink.cast::() }; + // SAFETY: We can access our own private data. + let list_lru = unsafe { (*shrink).private_data.cast::() }; // SAFETY: Caller guarantees that it is safe to read this field. let nr_to_scan = unsafe { (*sc).nr_to_scan }; // SAFETY: Accessing the lru list is okay. Just an FFI call. @@ -684,7 +683,7 @@ unsafe extern "C" fn rust_shrink_scan( } bindings::list_lru_walk( - shrinker.list_lru.get(), + list_lru, Some(rust_shrink_free_page_wrap), ptr::null_mut(), nr_to_scan,