Skip to content

Commit

Permalink
Finishes minimal zone_ctor implementation (#1255)
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon authored Jan 22, 2025
1 parent b824e9e commit 5aef053
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 10 deletions.
10 changes: 8 additions & 2 deletions kernel/src/lock/gutex/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
pub use self::guard::*;

use super::MTX_UNOWNED;
use crate::context::{current_thread, BorrowedArc};
use alloc::rc::Rc;
Expand All @@ -6,8 +8,6 @@ use core::cell::UnsafeCell;
use core::marker::PhantomData;
use core::sync::atomic::{AtomicUsize, Ordering};

pub use self::guard::*;

mod guard;

/// A mutex that grant exclusive access to a group of members.
Expand Down Expand Up @@ -96,6 +96,12 @@ impl GutexGroup {
})
}

/// # Context safety
/// This function does not require a CPU context if [`Default`] implementation on `T` does not.
pub fn spawn_default<T: Default>(self: Arc<Self>) -> Gutex<T> {
self.spawn(T::default())
}

/// # Context safety
/// This function does not require a CPU context.
pub fn spawn<T>(self: Arc<Self>, value: T) -> Gutex<T> {
Expand Down
15 changes: 13 additions & 2 deletions kernel/src/uma/keg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ use core::cmp::{max, min};
use core::num::NonZero;

/// Implementation of `uma_keg` structure.
pub struct UmaKeg {}
pub struct UmaKeg {
size: NonZero<usize>, // uk_size
flags: UmaFlags, // uk_flags
}

impl UmaKeg {
/// `align` is the actual alignment **minus** one, which mean if you want each item to be 8
Expand Down Expand Up @@ -150,6 +153,14 @@ impl UmaKeg {

// TODO: Add uk_zones.
// TODO: Add uma_kegs.
Self {}
Self { size, flags }
}

pub fn size(&self) -> NonZero<usize> {
self.size
}

pub fn flags(&self) -> UmaFlags {
self.flags
}
}
2 changes: 2 additions & 0 deletions kernel/src/uma/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ pub enum UmaFlags {
Secondary = 0x200,
/// `UMA_ZONE_REFCNT`.
RefCnt = 0x400,
/// `UMA_ZONE_MAXBUCKET`.
MaxBucket = 0x800,
/// `UMA_ZONE_CACHESPREAD`.
CacheSpread = 0x1000,
/// `UMA_ZONE_VTOSLAB`.
Expand Down
43 changes: 37 additions & 6 deletions kernel/src/uma/zone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use super::bucket::UmaBucket;
use super::keg::UmaKeg;
use super::UmaFlags;
use crate::context::{current_thread, CpuLocal};
use crate::lock::Gutex;
use crate::lock::{Gutex, GutexGroup};
use alloc::collections::VecDeque;
use alloc::string::String;
use core::cell::RefCell;
Expand Down Expand Up @@ -30,29 +30,60 @@ impl UmaZone {
/// |---------|--------|
/// |PS4 11.00|0x13D490|
pub(super) fn new(
_: impl Into<String>,
name: impl Into<String>,
keg: Option<UmaKeg>,
size: NonZero<usize>,
align: Option<usize>,
flags: UmaFlags,
) -> Self {
if flags.has(UmaFlags::Secondary) {
let name = name.into();
let keg = if flags.has(UmaFlags::Secondary) {
todo!()
} else {
// We use a different approach here to make it idiomatic to Rust. On Orbis it will
// construct a keg here if it is passed from the caller. If not it will allocate a new
// keg from masterzone_k.
keg.unwrap_or_else(|| UmaKeg::new(size, align.unwrap_or(Self::ALIGN_CACHE), flags));
keg.unwrap_or_else(|| UmaKeg::new(size, align.unwrap_or(Self::ALIGN_CACHE), flags))
};

todo!()
if !keg.flags().has(UmaFlags::Internal) {
if !keg.flags().has(UmaFlags::MaxBucket) {
// TODO: Get uz_count.
}

match name.as_str() {
"mbuf_packet" => todo!(),
"mbuf_cluster_pack" => todo!(),
"mbuf_jumbo_page" => todo!(),
"mbuf" => todo!(),
"mbuf_cluster" => todo!(),
_ => (),
}
}

// Construct uma_zone.
let gg = GutexGroup::new();

Self {
size: keg.size(),
caches: CpuLocal::new(|_| RefCell::default()),
full_buckets: gg.clone().spawn_default(),
free_buckets: gg.clone().spawn_default(),
alloc_count: gg.clone().spawn_default(),
free_count: gg.spawn_default(),
}
}

pub fn size(&self) -> NonZero<usize> {
self.size
}

/// See `uma_zalloc_arg` on the PS4 for a reference.
/// See `uma_zalloc_arg` on the Orbis for a reference.
///
/// # Reference offsets
/// | Version | Offset |
/// |---------|--------|
/// |PS4 11.00|0x13E750|
pub fn alloc(&self) -> *mut u8 {
// Our implementation imply M_WAITOK and M_ZERO.
let td = current_thread();
Expand Down

0 comments on commit 5aef053

Please sign in to comment.