Skip to content

Commit 30edc7f

Browse files
committed
rust: mem_cache: introduce MemCache
This is just the basics of `kmem_cache` to be used in file systems for inodes. All dead-code annotations will be removed in the next commit. Signed-off-by: Wedson Almeida Filho <walmeida@microsoft.com>
1 parent 54a61be commit 30edc7f

4 files changed

Lines changed: 65 additions & 0 deletions

File tree

rust/bindings/bindings_helper.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,6 @@
1717
const size_t BINDINGS_ARCH_SLAB_MINALIGN = ARCH_SLAB_MINALIGN;
1818
const gfp_t BINDINGS_GFP_KERNEL = GFP_KERNEL;
1919
const gfp_t BINDINGS___GFP_ZERO = __GFP_ZERO;
20+
21+
const slab_flags_t BINDINGS_SLAB_RECLAIM_ACCOUNT = SLAB_RECLAIM_ACCOUNT;
22+
const slab_flags_t BINDINGS_SLAB_MEM_SPREAD = SLAB_MEM_SPREAD;

rust/bindings/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,6 @@ pub use bindings_raw::*;
5151

5252
pub const GFP_KERNEL: gfp_t = BINDINGS_GFP_KERNEL;
5353
pub const __GFP_ZERO: gfp_t = BINDINGS___GFP_ZERO;
54+
55+
pub const SLAB_RECLAIM_ACCOUNT: slab_flags_t = BINDINGS_SLAB_RECLAIM_ACCOUNT;
56+
pub const SLAB_MEM_SPREAD: slab_flags_t = BINDINGS_SLAB_MEM_SPREAD;

rust/kernel/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub mod init;
3838
pub mod ioctl;
3939
#[cfg(CONFIG_KUNIT)]
4040
pub mod kunit;
41+
pub mod mem_cache;
4142
pub mod prelude;
4243
pub mod print;
4344
mod static_assert;

rust/kernel/mem_cache.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
//! Kernel memory caches (kmem_cache).
4+
//!
5+
//! C headers: [`include/linux/slab.h`](../../include/linux/slab.h)
6+
7+
use crate::error::{code::*, Result};
8+
use crate::{bindings, str::CStr};
9+
use core::ptr;
10+
11+
/// A kernel memory cache.
12+
///
13+
/// This isn't ready to be made public yet because it only provides functionality useful for the
14+
/// allocation of inodes in file systems.
15+
pub(crate) struct MemCache {
16+
ptr: ptr::NonNull<bindings::kmem_cache>,
17+
}
18+
19+
impl MemCache {
20+
#[allow(dead_code)]
21+
pub(crate) fn try_new<T>(
22+
name: &'static CStr,
23+
init: Option<unsafe extern "C" fn(*mut core::ffi::c_void)>,
24+
) -> Result<Self> {
25+
// SAFETY: `name` is static, so always valid.
26+
let ptr = ptr::NonNull::new(unsafe {
27+
bindings::kmem_cache_create(
28+
name.as_char_ptr(),
29+
core::mem::size_of::<T>().try_into()?,
30+
core::mem::align_of::<T>().try_into()?,
31+
bindings::SLAB_RECLAIM_ACCOUNT | bindings::SLAB_MEM_SPREAD | bindings::SLAB_ACCOUNT,
32+
init,
33+
)
34+
})
35+
.ok_or(ENOMEM)?;
36+
37+
Ok(Self { ptr })
38+
}
39+
40+
#[allow(dead_code)]
41+
pub(crate) fn ptr(c: &Option<Self>) -> *mut bindings::kmem_cache {
42+
match c {
43+
Some(m) => m.ptr.as_ptr(),
44+
None => ptr::null_mut(),
45+
}
46+
}
47+
}
48+
49+
impl Drop for MemCache {
50+
fn drop(&mut self) {
51+
// SAFETY: Just an FFI call with no additional safety requirements.
52+
unsafe { bindings::rcu_barrier() };
53+
54+
// SAFETY: `ptr` was previously returned by successful call to `kmem_cache_create`, so it's
55+
// ok to destroy it here.
56+
unsafe { bindings::kmem_cache_destroy(self.ptr.as_ptr()) };
57+
}
58+
}

0 commit comments

Comments
 (0)