Skip to content
Draft
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
d897f9a
rust: rros: add 'CONFIG_RROS_SPINLOCK'
Caspian443 Nov 8, 2024
aa2df1d
rust: rros: change some 'CONFIG_RROS' to 'CONFIG_RROS_SPINLOCK'
Caspian443 Nov 8, 2024
3c18d74
change spinlock initialization in memory_rros.rs
Caspian443 Nov 8, 2024
27d9d77
change spinlock initialization for RROS_CONTROL_FACTORY in control.rs
Caspian443 Nov 9, 2024
78397e2
change spinlock initialization for RROS_OBSERVABLE_FACTORY in observa…
Caspian443 Nov 9, 2024
ce619a1
change spinlock initialization for RROS_POLL_FACTORY in poll.rs
Caspian443 Nov 9, 2024
9e1871f
change spinlock initialization for RrosPollGroup's waiter_list in pol…
Caspian443 Nov 9, 2024
b9728a4
change spinlock initialization for RrosPollHead's watchpoints in poll.rs
Caspian443 Nov 10, 2024
220446e
change spinlock initialization for RrosSubscriber's subscriptions in …
Caspian443 Nov 10, 2024
d6369f7
change spinlock initialization for RROS_THREAD_FACTORY in thread.rs
Caspian443 Nov 10, 2024
37a4295
Replace init_static_sync with the new spinlock initialization method.
Caspian443 Nov 10, 2024
aaff261
rust: rros: Refactor the method for accessing data within the lock
Caspian443 Nov 10, 2024
e68dfdb
change spinlock initialization
Caspian443 Nov 23, 2024
384acdf
reorganize statements for module imports
Caspian443 Nov 23, 2024
47abfa2
wrap SpinLock with Pin and Box
Caspian443 Nov 23, 2024
8e2e824
add some necessary api
Caspian443 Nov 23, 2024
fcfe82e
wrap global variable with Oncecell
Caspian443 Nov 23, 2024
4884575
adjust class_create
Caspian443 Nov 25, 2024
d6005dd
rust: class: rm `rust_helper_class_create`
shannmu Dec 5, 2024
b2921b7
rust: time_types: mv time_types from uapi to kernel, fix compile error
shannmu Dec 6, 2024
63377a2
Merge pull request #1 from shannmu/pr-66
Caspian443 Dec 6, 2024
8154918
fix dead lock in spinlock's unlock
Caspian443 Dec 6, 2024
85bac65
add a missing parameter.
Caspian443 Dec 6, 2024
b27d418
delete unlock
Caspian443 Dec 6, 2024
ec59aa3
impl unsafe operation for spinlock
Caspian443 Dec 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions arch/arm64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1481,6 +1481,7 @@ config CC_HAVE_SHADOW_CALL_STACK

source "kernel/Kconfig.dovetail"
source "kernel/Kconfig.rros"
source "kernel/Kconfig.rros_spinlock"

config PARAVIRT
bool "Enable paravirtualization code"
Expand Down
9 changes: 9 additions & 0 deletions kernel/Kconfig.rros_spinlock
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
config RROS_SPINLOCK
bool "Enable RROS Spinlock"
depends on RROS
help
Enable spinlock functionality for RROS. This option provides a
specialized spinlock mechanism designed for the Rust Real-time Core.

Note: This option is experimental and should only be enabled if
you understand the implications on system performance.
51 changes: 28 additions & 23 deletions kernel/rros/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,38 @@ use kernel::{
prelude::*,
str::CStr,
sync::SpinLock,
new_spinlock,
};

pub const CONFIG_RROS_NR_CONTROL: usize = 0;

pub static mut RROS_CONTROL_FACTORY: SpinLock<RrosFactory> = unsafe {
SpinLock::new(RrosFactory {
name: CStr::from_bytes_with_nul_unchecked("control\0".as_bytes()),
nrdev: CONFIG_RROS_NR_CONTROL,
build: None,
dispose: None,
attrs: None,
flags: crate::factory::RrosFactoryType::SINGLE,
inside: Some(RrosFactoryInside {
type_: DeviceType::new(),
class: None,
cdev: None,
device: None,
sub_rdev: None,
kuid: None,
kgid: None,
minor_map: None,
index: None,
name_hash: None,
hash_lock: None,
register: None,
}),
})
pub static mut RROS_CONTROL_FACTORY: Pin<Box<SpinLock<RrosFactory>>> = unsafe {
Box::pin_init(
new_spinlock!(
RrosFactory {
name: CStr::from_bytes_with_nul_unchecked("control\0".as_bytes()),
nrdev: CONFIG_RROS_NR_CONTROL,
build: None,
dispose: None,
attrs: None,
flags: crate::factory::RrosFactoryType::SINGLE,
inside: Some(RrosFactoryInside {
type_: DeviceType::new(),
class: None,
cdev: None,
device: None,
sub_rdev: None,
kuid: None,
kgid: None,
minor_map: None,
index: None,
name_hash: None,
hash_lock: None,
register: None,
}),
}
)
).unwrap()
};

pub struct ControlOps;
Expand Down
8 changes: 5 additions & 3 deletions kernel/rros/observable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use kernel::{
prelude::*,
premmpt::running_inband,
rbtree::RBTree,
spinlock_init,
new_spinlock,
str::CStr,
sync::{HardSpinlock, Lock, SpinLock},
task,
Expand Down Expand Up @@ -954,8 +954,9 @@ pub fn observable_factory_dispose(_ele: RrosElement) {
pr_debug!("[observable] observable_factory_dispose");
}

pub static mut RROS_OBSERVABLE_FACTORY: SpinLock<factory::RrosFactory> = unsafe {
SpinLock::new(RrosFactory {
pub static mut RROS_OBSERVABLE_FACTORY: Pin<Box<SpinLock<factory::RrosFactory>>> = unsafe {
Box::pin_init(
new_spinlock!(RrosFactory {
name: CStr::from_bytes_with_nul_unchecked("observable\0".as_bytes()),
nrdev: CONFIG_RROS_NR_OBSERVABLE + CONFIG_RROS_NR_THREADS,
build: Some(observable_factory_build),
Expand All @@ -977,4 +978,5 @@ pub static mut RROS_OBSERVABLE_FACTORY: SpinLock<factory::RrosFactory> = unsafe
register: None,
}),
})
).unwrap()
};
72 changes: 37 additions & 35 deletions kernel/rros/poll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use kernel::{
ktime::{self, timespec64_to_ktime, Timespec64},
linked_list::{GetLinks, Links, List},
prelude::*,
rbtree, spinlock_init,
rbtree, new_spinlock,
str::CStr,
sync::Lock,
sync::SpinLock,
Expand All @@ -67,7 +67,7 @@ pub const RROS_POLIOC_WAIT: u32 = kernel::ioctl::_IOWR::<(i64, i64, i64)>(RROS_P
pub struct RrosPollGroup {
pub item_index: rbtree::RBTree<u32, Arc<RrosPollItem>>,
pub item_list: List<Arc<RrosPollItem>>,
pub waiter_list: SpinLock<List<Arc<RrosPollWaiter>>>,
pub waiter_list: Pin<Box<SpinLock<List<Arc<RrosPollWaiter>>>>>,
pub rfile: RrosFile,
// pub item_lock: mutex::RrosKMutex,
pub nr_items: i32,
Expand All @@ -79,7 +79,7 @@ impl RrosPollGroup {
Self {
item_index: rbtree::RBTree::new(),
item_list: List::new(),
waiter_list: unsafe { SpinLock::new(List::new()) },
waiter_list: Box::pin_init(new_spinlock!(List::new(),"RrosPollGroup::waiter_list")),
rfile: RrosFile::new(),
// item_lock: mutex::RrosKMutex::new(),
nr_items: 0,
Expand All @@ -88,8 +88,8 @@ impl RrosPollGroup {
}

pub fn init(&mut self) {
let pinned = unsafe { Pin::new_unchecked(&mut self.waiter_list) };
spinlock_init!(pinned, "RrosPollGroup::waiter_list");
// let pinned = unsafe { Pin::new_unchecked(&mut self.waiter_list) };
// spinlock_init!(pinned, "RrosPollGroup::waiter_list");
//FIXME: init kmutex fail
// rros_init_kmutex(&mut item_lock as *mut RrosKMutex);
}
Expand Down Expand Up @@ -155,22 +155,22 @@ impl RrosPollWaiter {
}

pub struct RrosPollHead {
pub watchpoints: SpinLock<list_head>,
pub watchpoints: Pin<Box<SpinLock<list_head>>>,
}

impl RrosPollHead {
pub fn new() -> Self {
Self {
watchpoints: unsafe { SpinLock::new(list_head::default()) },
watchpoints: Box::pin_init(new_spinlock!(list_head::default(),"RrosPollHead")).unwrap() ,
}
}

pub fn init(&mut self) {
init_list_head!(self.watchpoints.locked_data().get());
spinlock_init!(
unsafe { Pin::new_unchecked(&mut self.watchpoints) },
"RrosPollHead"
);
// spinlock_init!(
// unsafe { Pin::new_unchecked(&mut self.watchpoints) },
// "RrosPollHead"
// );
}
}
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good for me.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

pub struct RrosPollConnector {
Expand Down Expand Up @@ -1123,28 +1123,30 @@ impl FileOperations for PollOps {
}
}

pub static mut RROS_POLL_FACTORY: SpinLock<factory::RrosFactory> = unsafe {
SpinLock::new(factory::RrosFactory {
name: CStr::from_bytes_with_nul_unchecked("poll\0".as_bytes()),
// fops: Some(&Pollops),
nrdev: 0,
build: None,
dispose: None,
attrs: None,
flags: factory::RrosFactoryType::SINGLE,
inside: Some(factory::RrosFactoryInside {
type_: DeviceType::new(),
class: None,
cdev: None,
device: None,
sub_rdev: None,
kuid: None,
kgid: None,
minor_map: None,
index: None,
name_hash: None,
hash_lock: None,
register: None,
}),
})
pub static mut RROS_POLL_FACTORY: Pin<Box<SpinLock<factory::RrosFactory>>> = unsafe {
Box::pin_init(
new_spinlock!(factory::RrosFactory {
name: CStr::from_bytes_with_nul_unchecked("poll\0".as_bytes()),
// fops: Some(&Pollops),
nrdev: 0,
build: None,
dispose: None,
attrs: None,
flags: factory::RrosFactoryType::SINGLE,
inside: Some(factory::RrosFactoryInside {
type_: DeviceType::new(),
class: None,
cdev: None,
device: None,
sub_rdev: None,
kuid: None,
kgid: None,
minor_map: None,
index: None,
name_hash: None,
hash_lock: None,
register: None,
}),
})
).unwrap()
};
8 changes: 3 additions & 5 deletions rust/kernel/memory_rros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! Rros Memory.
use crate::timekeeping::*;
use crate::{bindings, Result};
use crate::{c_types, mm, prelude::*, premmpt, spinlock_init, sync::SpinLock, vmalloc};
use crate::{c_types, mm, prelude::*, premmpt, new_spinlock, sync::SpinLock, vmalloc};
use core::{mem::size_of, ptr::addr_of_mut};

const PAGE_SIZE: u32 = 4096 as u32;
Expand Down Expand Up @@ -175,7 +175,7 @@ pub struct RrosHeap {
pub buckets: [u32; RROS_HEAP_MAX_BUCKETS as usize],
/// `lock` is an optional SpinLock used for ensuring thread-safety in the `RrosHeap`.
/// It is initialized in the `init` method of the `RrosHeap` struct.
pub lock: Option<SpinLock<i32>>,
pub lock: Option<Pin<Box<SpinLock<i32>>>>,
}

/// Implementation of the `RrosHeap` struct.
Expand All @@ -192,9 +192,7 @@ impl RrosHeap {
return Err(crate::Error::EINVAL);
}

let mut spinlock = unsafe { SpinLock::new(1) };
let pinned = unsafe { Pin::new_unchecked(&mut spinlock) };
spinlock_init!(pinned, "spinlock");
let mut spinlock = Box::pin_init(new_spinlock!(1 as i32,"spinlock",)).unwrap();
self.lock = Some(spinlock);

for i in self.buckets.iter_mut() {
Expand Down
26 changes: 13 additions & 13 deletions rust/kernel/sync/lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ pub unsafe trait Backend {
///
/// Exposes one of the kernel locking primitives. Which one is exposed depends on the lock
/// [`Backend`] specified as the generic parameter `B`.
#[cfg(not(CONFIG_RROS))]
#[cfg(not(CONFIG_RROS_SPINLOCK))]
#[pin_data]
pub struct Lock<T: ?Sized, B: Backend> {
/// The kernel lock object.
Expand All @@ -95,15 +95,15 @@ pub struct Lock<T: ?Sized, B: Backend> {
}

// SAFETY: `Lock` can be transferred across thread boundaries iff the data it protects can.
#[cfg(not(CONFIG_RROS))]
#[cfg(not(CONFIG_RROS_SPINLOCK))]
unsafe impl<T: ?Sized + Send, B: Backend> Send for Lock<T, B> {}

// SAFETY: `Lock` serialises the interior mutability it provides, so it is `Sync` as long as the
// data it protects is `Send`.
#[cfg(not(CONFIG_RROS))]
#[cfg(not(CONFIG_RROS_SPINLOCK))]
unsafe impl<T: ?Sized + Send, B: Backend> Sync for Lock<T, B> {}

#[cfg(not(CONFIG_RROS))]
#[cfg(not(CONFIG_RROS_SPINLOCK))]
impl<T, B: Backend> Lock<T, B> {
/// Constructs a new lock initialiser.
#[allow(clippy::new_ret_no_self)]
Expand All @@ -120,7 +120,7 @@ impl<T, B: Backend> Lock<T, B> {
}
}

#[cfg(not(CONFIG_RROS))]
#[cfg(not(CONFIG_RROS_SPINLOCK))]
impl<T: ?Sized, B: Backend> Lock<T, B> {
/// Acquires the lock and gives the caller access to the data protected by it.
pub fn lock(&self) -> Guard<'_, T, B> {
Expand All @@ -137,7 +137,7 @@ impl<T: ?Sized, B: Backend> Lock<T, B> {
/// Allows mutual exclusion primitives that implement the [`Backend`] trait to automatically unlock
/// when a guard goes out of scope. It also provides a safe and convenient way to access the data
/// protected by the lock.
#[cfg(not(CONFIG_RROS))]
#[cfg(not(CONFIG_RROS_SPINLOCK))]
#[must_use = "the lock unlocks immediately when the guard is unused"]
pub struct Guard<'a, T: ?Sized, B: Backend> {
pub(crate) lock: &'a Lock<T, B>,
Expand All @@ -146,10 +146,10 @@ pub struct Guard<'a, T: ?Sized, B: Backend> {
}

// SAFETY: `Guard` is sync when the data protected by the lock is also sync.
#[cfg(not(CONFIG_RROS))]
#[cfg(not(CONFIG_RROS_SPINLOCK))]
unsafe impl<T: Sync + ?Sized, B: Backend> Sync for Guard<'_, T, B> {}

#[cfg(not(CONFIG_RROS))]
#[cfg(not(CONFIG_RROS_SPINLOCK))]
impl<T: ?Sized, B: Backend> Guard<'_, T, B> {
pub(crate) fn do_unlocked(&mut self, cb: impl FnOnce()) {
// SAFETY: The caller owns the lock, so it is safe to unlock it.
Expand All @@ -163,7 +163,7 @@ impl<T: ?Sized, B: Backend> Guard<'_, T, B> {
}
}

#[cfg(not(CONFIG_RROS))]
#[cfg(not(CONFIG_RROS_SPINLOCK))]
impl<T: ?Sized, B: Backend> core::ops::Deref for Guard<'_, T, B> {
type Target = T;

Expand All @@ -173,23 +173,23 @@ impl<T: ?Sized, B: Backend> core::ops::Deref for Guard<'_, T, B> {
}
}

#[cfg(not(CONFIG_RROS))]
#[cfg(not(CONFIG_RROS_SPINLOCK))]
impl<T: ?Sized, B: Backend> core::ops::DerefMut for Guard<'_, T, B> {
fn deref_mut(&mut self) -> &mut Self::Target {
// SAFETY: The caller owns the lock, so it is safe to deref the protected data.
unsafe { &mut *self.lock.data.get() }
}
}

#[cfg(not(CONFIG_RROS))]
#[cfg(not(CONFIG_RROS_SPINLOCK))]
impl<T: ?Sized, B: Backend> Drop for Guard<'_, T, B> {
fn drop(&mut self) {
// SAFETY: The caller owns the lock, so it is safe to unlock it.
unsafe { B::unlock(self.lock.state.get(), &self.state) };
}
}

#[cfg(not(CONFIG_RROS))]
#[cfg(not(CONFIG_RROS_SPINLOCK))]
impl<'a, T: ?Sized, B: Backend> Guard<'a, T, B> {
/// Constructs a new immutable lock guard.
///
Expand Down Expand Up @@ -247,7 +247,7 @@ pub trait NeedsLockClass {
}

/// Reschedules the caller's task if needed.
#[cfg(CONFIG_RROS)]
#[cfg(CONFIG_RROS_SPINLOCK)]
pub fn cond_resched() -> bool {
// SAFETY: No arguments, reschedules `current` if needed.
unsafe { rust_helper_cond_resched() != 0 }
Expand Down
Loading