diff --git a/drivers/staging/android/ashmem_range.rs b/drivers/staging/android/ashmem_range.rs index 669a7e02e64e..94bfcb252940 100644 --- a/drivers/staging/android/ashmem_range.rs +++ b/drivers/staging/android/ashmem_range.rs @@ -5,8 +5,12 @@ //! Keeps track of unpinned ranges in an ashmem file. use crate::{ - ashmem_shrinker::{CountObjects, ScanObjects, ShrinkControl, Shrinker}, + ashmem_shrinker::{ + self, CountObjects, ScanObjects, ShrinkControl, Shrinker, ShrinkerBuilder, + ShrinkerRegistration, + }, shmem::ShmemFile, + AshmemModule, }; use core::{ mem::MaybeUninit, @@ -14,6 +18,8 @@ use core::{ sync::atomic::{AtomicUsize, Ordering}, }; use kernel::{ + alloc::AllocError, + c_str, list::{List, ListArc, ListLinks}, page::PAGE_SIZE, prelude::*, @@ -440,6 +446,26 @@ impl Shrinker for super::AshmemModule { } } +/// Make line below shorter. +type AshmemShrinkerType = Option>; + +kernel::sync::global_lock! { + // SAFETY: We call `init` as the very first thing in the initialization of this module, so + // there are no calls to `lock` before `init` is called. + pub(crate) unsafe(uninit) static ASHMEM_SHRINKER: Mutex = None; +} + +pub(crate) fn register_shrinker() -> Result<(), AllocError> { + let mut lock = ASHMEM_SHRINKER.lock(); + if lock.is_none() { + let mut shrinker = ShrinkerBuilder::new(c_str!("android-ashmem"))?; + shrinker.set_seeks(4 * ashmem_shrinker::DEFAULT_SEEKS); + + *lock = Some(shrinker.register(())); + } + Ok(()) +} + #[cfg(test)] fn range_test() -> Result { fn get_random(max: usize) -> usize { diff --git a/drivers/staging/android/ashmem_rust.rs b/drivers/staging/android/ashmem_rust.rs index ae96ff09a0b5..e5e0ce283735 100644 --- a/drivers/staging/android/ashmem_rust.rs +++ b/drivers/staging/android/ashmem_rust.rs @@ -42,7 +42,6 @@ const PROT_WRITE: usize = bindings::PROT_WRITE as usize; const PROT_MASK: usize = PROT_EXEC | PROT_READ | PROT_WRITE; mod ashmem_shrinker; -use ashmem_shrinker::{ShrinkerBuilder, ShrinkerRegistration}; mod ashmem_range; use ashmem_range::{Area, AshmemGuard, NewRange, ASHMEM_MUTEX, LRU_COUNT}; @@ -79,7 +78,6 @@ module! { struct AshmemModule { _misc: Pin>>, - _shrinker: ShrinkerRegistration, } impl kernel::Module for AshmemModule { @@ -88,11 +86,12 @@ impl kernel::Module for AshmemModule { unsafe { shmem::SHMEM_FOPS_ONCE.init() }; // SAFETY: Called once since this is the module initializer. unsafe { ASHMEM_MUTEX.init() }; + // SAFETY: Called once since this is the module initializer. + unsafe { ashmem_range::ASHMEM_SHRINKER.init() }; pr_info!("Using Rust implementation."); - let mut shrinker = ShrinkerBuilder::new(c_str!("android-ashmem"))?; - shrinker.set_seeks(4 * ashmem_shrinker::DEFAULT_SEEKS); + ashmem_range::register_shrinker()?; Ok(Self { _misc: Box::pin_init( @@ -101,7 +100,6 @@ impl kernel::Module for AshmemModule { }), GFP_KERNEL, )?, - _shrinker: shrinker.register(()), }) } }