Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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.
102 changes: 59 additions & 43 deletions kernel/rros/clock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ use crate::{
RROS_OOB_CPUS,
};

use core::cell::OnceCell;

use alloc::rc::Rc;

use core::{
Expand All @@ -46,7 +48,7 @@ use kernel::{
ktime::*,
percpu,
prelude::*,
premmpt, spinlock_init,
premmpt, new_spinlock,
str::CStr,
sync::{Lock, SpinLock},
sysfs,
Expand All @@ -56,8 +58,15 @@ use kernel::{
user_ptr::{UserSlicePtr, UserSlicePtrReader, UserSlicePtrWriter},
};

static mut CLOCKLIST_LOCK: SpinLock<i32> = unsafe { SpinLock::new(1) };
pub static mut CLOCKLIST_LOCK: OnceCell<Pin<Box<SpinLock<i32>>>> = OnceCell::new();

pub fn clocklist_lock_init() {
unsafe {
CLOCKLIST_LOCK.get_or_init(|| {
Box::pin_init(new_spinlock!(1, "CLOCKLIST_LOCK")).unwrap()
});
}
}
// Define it as a constant here first, and then read it from /dev/rros.
const CONFIG_RROS_LATENCY_USER: KtimeT = 0;
const CONFIG_RROS_LATENCY_KERNEL: KtimeT = 0;
Expand Down Expand Up @@ -293,8 +302,8 @@ impl RrosClock {

pub fn adjust_timer(
clock: &RrosClock,
timer: Arc<SpinLock<RrosTimer>>,
tq: &mut List<Arc<SpinLock<RrosTimer>>>,
timer: Arc<Pin<Box<SpinLock<RrosTimer>>>>,
tq: &mut List<Arc<Pin<Box<SpinLock<RrosTimer>>>>>,
delta: KtimeT,
) {
let date = timer.lock().get_date();
Expand Down Expand Up @@ -350,7 +359,7 @@ pub fn rros_adjust_timers(clock: &mut RrosClock, delta: KtimeT) -> Result {

let flags: u64 = unsafe { (*tmb).lock.irq_lock_noguard() };

let mut timers_adjust: Vec<Arc<SpinLock<RrosTimer>>> =
let mut timers_adjust: Vec<Arc<Pin<Box<SpinLock<RrosTimer>>>>> =
Vec::try_with_capacity(tq.len() as usize)?;

while !tq.is_empty() {
Expand Down Expand Up @@ -538,33 +547,40 @@ pub static mut CLOCK_LIST: List<*mut RrosClock> = List::<*mut RrosClock> {
},
};

pub static mut RROS_CLOCK_FACTORY: SpinLock<factory::RrosFactory> = unsafe {
SpinLock::new(factory::RrosFactory {
name: unsafe { CStr::from_bytes_with_nul_unchecked("clock\0".as_bytes()) },
nrdev: CONFIG_RROS_NR_CLOCKS,
build: None,
dispose: Some(clock_factory_dispose),
attrs: None, //sysfs::attribute_group::new(),
flags: factory::RrosFactoryType::Invalid,
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_CLOCK_FACTORY: OnceCell<Pin<Box<SpinLock<factory::RrosFactory>>>> = OnceCell::new();

pub fn rros_clock_factory_init() {
unsafe {
RROS_CLOCK_FACTORY.get_or_init(|| {
Box::pin_init(new_spinlock!(factory::RrosFactory {
name: CStr::from_bytes_with_nul_unchecked("clock\0".as_bytes()),
nrdev: CONFIG_RROS_NR_CLOCKS,
build: None,
dispose: Some(clock_factory_dispose),
attrs: None, // sysfs::attribute_group::new(),
flags: factory::RrosFactoryType::Invalid,
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()
});
}
}

pub struct RrosTimerFd {
timer: Arc<SpinLock<RrosTimer>>,
timer: Arc<Pin<Box<SpinLock<RrosTimer>>>>,
readers: RrosWaitQueue,
poll_head: RrosPollHead,
efile: RrosFile,
Expand All @@ -574,7 +590,7 @@ pub struct RrosTimerFd {
impl RrosTimerFd {
fn new() -> Self {
Self {
timer: Arc::try_new(unsafe { SpinLock::new(RrosTimer::new(0)) }).unwrap(),
timer: Arc::try_new(unsafe { Box::pin_init(new_spinlock!(RrosTimer::new(0))).unwrap() }).unwrap(),
//FIXME: readers initiation is not sure
readers: RrosWaitQueue::new(core::ptr::null_mut(), 0),
poll_head: RrosPollHead::new(),
Expand All @@ -584,7 +600,7 @@ impl RrosTimerFd {
}
}

fn get_timer_value(timer: Arc<SpinLock<RrosTimer>>, value: &mut Itimerspec64) {
fn get_timer_value(timer: Arc<Pin<Box<SpinLock<RrosTimer>>>>, value: &mut Itimerspec64) {
let mut inner_timer_lock = timer.lock();
let inner_timer: &mut RrosTimer = inner_timer_lock.deref_mut();
value.it_interval = ktime_to_timespec64(inner_timer.interval);
Expand All @@ -596,7 +612,7 @@ fn get_timer_value(timer: Arc<SpinLock<RrosTimer>>, value: &mut Itimerspec64) {
}
}

fn set_timer_value(timer: Arc<SpinLock<RrosTimer>>, value: &Itimerspec64) -> Result<i32> {
fn set_timer_value(timer: Arc<Pin<Box<SpinLock<RrosTimer>>>>, value: &Itimerspec64) -> Result<i32> {
let start: KtimeT;
let period: KtimeT;

Expand Down Expand Up @@ -648,7 +664,7 @@ pub fn double_timer_base_unlock(tb1: *mut RrosTimerbase, tb2: *mut RrosTimerbase
// `RrosClock`, `RrosTimerbase`, `RrosRq`. Maybe we can use references to avoid so many raw pointers.
// FYI: https://github.com/BUPT-OS/RROS/pull/41#discussion_r1680738528
pub fn rros_move_timer(
timer: Arc<SpinLock<RrosTimer>>,
timer: Arc<Pin<Box<SpinLock<RrosTimer>>>>,
clock: *mut RrosClock,
mut rq: *mut rros_rq,
) {
Expand Down Expand Up @@ -697,7 +713,7 @@ pub fn rros_move_timer(
}

#[cfg(CONFIG_SMP)]
fn pin_timer(timer: Arc<SpinLock<RrosTimer>>) {
fn pin_timer(timer: Arc<Pin<Box<SpinLock<RrosTimer>>>>) {
let flags = hard_local_irq_save();

let this_rq = rros_current_rq();
Expand All @@ -713,7 +729,7 @@ fn pin_timer(timer: Arc<SpinLock<RrosTimer>>) {
}

#[cfg(not(CONFIG_SMP))]
fn pin_timer(_timer: Arc<SpinLock<RrosTimer>>) {}
fn pin_timer(_timer: Arc<Pin<Box<SpinLock<RrosTimer>>>>) {}

fn set_timerfd(
timerfd: &RrosTimerFd,
Expand Down Expand Up @@ -1079,7 +1095,7 @@ pub fn do_clock_tick(clock: &mut RrosClock, tmb: *mut RrosTimerbase) {
let timer_addr = timer.locked_data().get();

let inband_timer_addr = (*rq).get_inband_timer().locked_data().get();
if (timer_addr == inband_timer_addr) {
if (timer_addr as *const _ == inband_timer_addr as *const _) {
(*rq).add_local_flags(RQ_TPROXY);
(*rq).change_local_flags(!RQ_TDEFER);
continue;
Expand Down Expand Up @@ -1172,7 +1188,7 @@ fn init_clock(clock: *mut RrosClock, master: *mut RrosClock) -> Result<usize> {
unsafe {
ret = factory::rros_init_element(
(*clock).element.as_ref().unwrap().clone(),
&mut RROS_CLOCK_FACTORY,
RROS_CLOCK_FACTORY.get_mut().unwrap(),
(*clock).flags & RROS_CLONE_PUBLIC,
);
}
Expand All @@ -1188,7 +1204,7 @@ fn init_clock(clock: *mut RrosClock, master: *mut RrosClock) -> Result<usize> {
unsafe {
ret = factory::rros_create_core_element_device(
(*clock).element.as_ref().unwrap().clone(),
&mut RROS_CLOCK_FACTORY,
RROS_CLOCK_FACTORY.get_mut().unwrap(),
(*clock).name,
);
}
Expand All @@ -1199,9 +1215,9 @@ fn init_clock(clock: *mut RrosClock, master: *mut RrosClock) -> Result<usize> {
}

unsafe {
CLOCKLIST_LOCK.lock();
clocklist_lock_init();
CLOCKLIST_LOCK.get().unwrap().lock();
CLOCK_LIST.add_head(clock);
CLOCKLIST_LOCK.unlock();
}

Ok(0)
Expand Down Expand Up @@ -1269,8 +1285,8 @@ fn rros_init_clock(clock: &mut RrosClock, affinity: &CpumaskT) -> Result<usize>
}

pub fn rros_clock_init() -> Result<usize> {
let pinned = unsafe { Pin::new_unchecked(&mut CLOCKLIST_LOCK) };
spinlock_init!(pinned, "CLOCKLIST_LOCK");
// let pinned = unsafe { Pin::new_unchecked(&mut CLOCKLIST_LOCK) };
// spinlock_init!(pinned, "CLOCKLIST_LOCK");
unsafe {
RROS_MONO_CLOCK.reset_gravity();
RROS_REALTIME_CLOCK.reset_gravity();
Expand Down
38 changes: 19 additions & 19 deletions kernel/rros/clock_test.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use crate::{clock::*, timer::*};

use kernel::{ktime::*, prelude::*, spinlock_init, sync::SpinLock};
use kernel::{ktime::*, prelude::*, new_spinlock, sync::SpinLock};

#[allow(dead_code)]
pub fn test_do_clock_tick() -> Result<usize> {
pr_debug!("~~~test_do_clock_tick begin~~~");
unsafe {
let tmb = rros_percpu_timers(&RROS_MONO_CLOCK, 0);
let mut a = SpinLock::new(RrosTimer::new(580000000));
let pinned = Pin::new_unchecked(&mut a);
spinlock_init!(pinned, "zbw");
let mut a = Box::pin_init(new_spinlock!(RrosTimer::new(580000000))).unwrap();
// let pinned = Pin::new_unchecked(&mut a);
// spinlock_init!(pinned, "zbw");

let xx = Arc::try_new(a)?;
xx.lock().add_status(RROS_TIMER_DEQUEUED);
Expand All @@ -33,9 +33,9 @@ pub fn test_adjust_timer() -> Result<usize> {
pr_debug!("~~~test_adjust_timer begin~~~");
unsafe {
let tmb = rros_percpu_timers(&RROS_MONO_CLOCK, 0);
let mut a = SpinLock::new(RrosTimer::new(580000000));
let pinned = Pin::new_unchecked(&mut a);
spinlock_init!(pinned, "a");
let mut a = Box::pin_init(new_spinlock!(RrosTimer::new(580000000))).unwrap();
// let pinned = Pin::new_unchecked(&mut a);
// spinlock_init!(pinned, "a");

let xx = Arc::try_new(a)?;
xx.lock().add_status(RROS_TIMER_DEQUEUED);
Expand All @@ -59,13 +59,13 @@ pub fn test_rros_adjust_timers() -> Result<usize> {
pr_debug!("~~~test_rros_adjust_timers begin~~~");
unsafe {
let tmb = rros_percpu_timers(&RROS_MONO_CLOCK, 0);
let mut a = SpinLock::new(RrosTimer::new(580000000));
let pinned = Pin::new_unchecked(&mut a);
spinlock_init!(pinned, "a");
let mut a = Box::pin_init(new_spinlock!(RrosTimer::new(580000000))).unwrap();
// let pinned = Pin::new_unchecked(&mut a);
// spinlock_init!(pinned, "a");

let mut b = SpinLock::new(RrosTimer::new(580000000));
let pinned = Pin::new_unchecked(&mut b);
spinlock_init!(pinned, "b");
let mut b = Box::pin_init(new_spinlock!(RrosTimer::new(580000000))).unwrap();
// let pinned = Pin::new_unchecked(&mut b);
// spinlock_init!(pinned, "b");

let xx = Arc::try_new(a)?;
let yy = Arc::try_new(b)?;
Expand Down Expand Up @@ -104,13 +104,13 @@ pub fn test_rros_stop_timers() -> Result<usize> {
pr_debug!("~~~test_rros_stop_timers begin~~~");
unsafe {
let tmb = rros_percpu_timers(&RROS_MONO_CLOCK, 0);
let mut a = SpinLock::new(RrosTimer::new(580000000));
let pinned = Pin::new_unchecked(&mut a);
spinlock_init!(pinned, "a");
let mut a = Box::pin_init(new_spinlock!(RrosTimer::new(580000000))).unwrap();
// let pinned = Pin::new_unchecked(&mut a);
// spinlock_init!(pinned, "a");

let mut b = SpinLock::new(RrosTimer::new(580000000));
let pinned = Pin::new_unchecked(&mut b);
spinlock_init!(pinned, "b");
let mut b = Box::pin_init(new_spinlock!(RrosTimer::new(580000000))).unwrap();
// let pinned = Pin::new_unchecked(&mut b);
// spinlock_init!(pinned, "b");

let xx = Arc::try_new(a)?;
let yy = Arc::try_new(b)?;
Expand Down
65 changes: 41 additions & 24 deletions kernel/rros/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,51 @@ use kernel::{
prelude::*,
str::CStr,
sync::SpinLock,
new_spinlock,
};

use core::cell::OnceCell;

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: OnceCell<Pin<Box<SpinLock<RrosFactory>>>> = OnceCell::new();

pub fn rros_control_factory_init()
{
unsafe{
RROS_CONTROL_FACTORY.get_or_init(|| {
let temp_lock = Box::pin_init(
new_spinlock!(
RrosFactory {
name: CStr::from_bytes_with_nul("control\0".as_bytes()).expect("Invalid CStr"),
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();
temp_lock
});
};
}



pub struct ControlOps;

Expand Down
Loading