mirror of
https://github.com/redox-os/kernel.git
synced 2026-09-09 00:07:34 +08:00
Safe get-percpu wrapper and warnings fixes.
This commit is contained in:
@@ -258,23 +258,6 @@ impl Context {
|
||||
}
|
||||
}
|
||||
|
||||
/// Unblock context, and return true if it was blocked before being marked runnable
|
||||
pub fn unblock(&mut self) -> bool {
|
||||
if self.unblock_no_ipi() {
|
||||
// TODO: Only send IPI if currently running?
|
||||
if let Some(cpu_id) = self.cpu_id
|
||||
&& cpu_id != crate::cpu_id()
|
||||
{
|
||||
// Send IPI if not on current CPU
|
||||
ipi(IpiKind::Wakeup, IpiTarget::Other);
|
||||
}
|
||||
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Unblock context without IPI, and return true if it was blocked before being marked runnable
|
||||
pub fn unblock_no_ipi(&mut self) -> bool {
|
||||
if self.status.is_soft_blocked() {
|
||||
|
||||
+17
-29
@@ -18,7 +18,7 @@ use crate::{
|
||||
cpu_stats::CpuStatsData,
|
||||
ipi::{ipi, IpiKind, IpiTarget},
|
||||
memory::{RmmA, RmmArch, TableKind},
|
||||
percpu::PercpuBlock,
|
||||
percpu::{get_percpu_block, PercpuBlock},
|
||||
sync::{
|
||||
ArcRwLockWriteGuard, CleanLockToken, LockToken, Mutex, MutexGuard, RwLock, RwLockReadGuard,
|
||||
RwLockWriteGuard, L0, L1, L2, L3, L4,
|
||||
@@ -27,8 +27,6 @@ use crate::{
|
||||
Ordering,
|
||||
};
|
||||
|
||||
use crate::percpu::ALL_PERCPU_BLOCKS;
|
||||
|
||||
use self::context::Kstack;
|
||||
pub use self::{
|
||||
context::{BorrowedHtBuf, Context, Status},
|
||||
@@ -144,21 +142,17 @@ pub fn wakeup_context(
|
||||
|
||||
let target_cpu = cpu_id.unwrap_or(curr_cpu);
|
||||
|
||||
if target_cpu != curr_cpu {
|
||||
if let Some(percpu) = unsafe {
|
||||
ALL_PERCPU_BLOCKS[target_cpu.get() as usize]
|
||||
.load(Ordering::Acquire)
|
||||
.as_ref()
|
||||
} {
|
||||
// non-local wakeup
|
||||
percpu
|
||||
.switch_internals
|
||||
.ipi_context_wakeup_list
|
||||
.lock(token.token())
|
||||
.push(weak);
|
||||
ipi(IpiKind::Wakeup, IpiTarget::Other);
|
||||
return;
|
||||
}
|
||||
if target_cpu != curr_cpu
|
||||
&& let Some(percpu) = get_percpu_block(target_cpu)
|
||||
{
|
||||
// non-local wakeup
|
||||
percpu
|
||||
.switch_internals
|
||||
.ipi_context_wakeup_list
|
||||
.lock(token.token())
|
||||
.push(weak);
|
||||
ipi(IpiKind::Wakeup, IpiTarget::Other);
|
||||
return;
|
||||
}
|
||||
|
||||
// local wakeup
|
||||
@@ -393,17 +387,11 @@ pub fn get_contexts_stats(token: &mut CleanLockToken) -> [usize; 5] {
|
||||
let mut switches = 0;
|
||||
let mut syscall_switches = 0;
|
||||
|
||||
for i in 0..crate::cpu_count() {
|
||||
if let Some(percpu) = unsafe {
|
||||
ALL_PERCPU_BLOCKS[i as usize]
|
||||
.load(Ordering::Acquire)
|
||||
.as_ref()
|
||||
} {
|
||||
running += percpu.switch_internals.run_queue.lock().queue.len();
|
||||
let data = CpuStatsData::from(&percpu.stats);
|
||||
switches += data.context_switches as usize;
|
||||
syscall_switches += data.syscall_switches as usize;
|
||||
}
|
||||
for percpu in crate::percpu::all_percpu_blocks() {
|
||||
running += percpu.switch_internals.run_queue.lock().queue.len();
|
||||
let data = CpuStatsData::from(&percpu.stats);
|
||||
switches += data.context_switches as usize;
|
||||
syscall_switches += data.syscall_switches as usize;
|
||||
}
|
||||
|
||||
let blocked = alive.saturating_sub(running);
|
||||
|
||||
+3
-11
@@ -9,7 +9,7 @@ use crate::{
|
||||
},
|
||||
cpu_set::LogicalCpuId,
|
||||
cpu_stats::{self, CpuState},
|
||||
percpu::{self, PercpuBlock, ALL_PERCPU_BLOCKS},
|
||||
percpu::{self, get_percpu_block, PercpuBlock},
|
||||
sync::{ArcRwLockWriteGuard, CleanLockToken, Mutex, L4},
|
||||
};
|
||||
use alloc::{
|
||||
@@ -697,11 +697,7 @@ fn select_next_context(
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(p) = unsafe {
|
||||
ALL_PERCPU_BLOCKS[i as usize]
|
||||
.load(Ordering::Acquire)
|
||||
.as_ref()
|
||||
} {
|
||||
if let Some(p) = get_percpu_block(LogicalCpuId::new(i as u32)) {
|
||||
let neighbour_len = p.switch_internals.queue_len.load(Ordering::Relaxed);
|
||||
|
||||
if neighbour_len > max_neighbour {
|
||||
@@ -723,11 +719,7 @@ fn select_next_context(
|
||||
if target_cpu == curr_cpu {
|
||||
continue;
|
||||
}
|
||||
let Some(target_percpu) = (unsafe {
|
||||
ALL_PERCPU_BLOCKS[target_cpu as usize]
|
||||
.load(Ordering::Acquire)
|
||||
.as_ref()
|
||||
}) else {
|
||||
let Some(target_percpu) = get_percpu_block(LogicalCpuId::new(target_cpu)) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
|
||||
+23
-29
@@ -3,7 +3,7 @@ use core::{mem, ops::Add, ptr::write_bytes, slice};
|
||||
use crate::{
|
||||
acpi,
|
||||
cpu_set::{LogicalCpuId, LogicalCpuSet, MAX_CPU_COUNT},
|
||||
percpu::{self, ALL_PERCPU_BLOCKS},
|
||||
percpu,
|
||||
sync::{CleanLockToken, Mutex, L0},
|
||||
};
|
||||
use alloc::{sync::Arc, vec::Vec};
|
||||
@@ -116,36 +116,30 @@ pub fn init_arch() {
|
||||
numa_nodes[memory.node_id as usize].memories.enable_index(i);
|
||||
}
|
||||
|
||||
for cpu_ptr in percpu::ALL_PERCPU_BLOCKS.as_ref() {
|
||||
if let Some(cpu) =
|
||||
unsafe { cpu_ptr.load(core::sync::atomic::Ordering::Relaxed).as_mut() }
|
||||
{
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
let cpu_id = cpu
|
||||
.misc_arch_info
|
||||
.apic_id_opt
|
||||
.get()
|
||||
.map(|e| e.get())
|
||||
.unwrap();
|
||||
for cpu in percpu::all_percpu_blocks() {
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
let cpu_id = cpu
|
||||
.misc_arch_info
|
||||
.apic_id_opt
|
||||
.get()
|
||||
.map(|e| e.get())
|
||||
.unwrap();
|
||||
|
||||
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
||||
let cpu_id = 0; // TODO
|
||||
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
||||
let cpu_id = 0; // TODO
|
||||
|
||||
let n = numa_nodes
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(i, node)| {
|
||||
if node.cpus & 1u128 << cpu_id != 0 {
|
||||
Some((i, node))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.map(|(i, node)| (i as u32, node));
|
||||
cpu.numa_node.set(n);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
let n = numa_nodes
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(i, node)| {
|
||||
if node.cpus & 1u128 << cpu_id != 0 {
|
||||
Some((i, node))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.map(|(i, node)| (i as u32, node));
|
||||
cpu.numa_node.set(n);
|
||||
}
|
||||
|
||||
NUMA_NODES.call_once(|| numa_nodes);
|
||||
|
||||
+16
-8
@@ -25,6 +25,8 @@ use crate::{
|
||||
};
|
||||
|
||||
/// The percpu block, that stored all percpu variables.
|
||||
// TODO: consider splitting this struct into a !Sync part (which safe code is not allowed to get
|
||||
// references to for other hw threads' blocks) and a Sync part
|
||||
pub struct PercpuBlock {
|
||||
/// A unique immutable number that identifies the current CPU - used for scheduling
|
||||
pub cpu_id: LogicalCpuId,
|
||||
@@ -57,15 +59,25 @@ pub struct PercpuBlock {
|
||||
pub static ALL_PERCPU_BLOCKS: [AtomicPtr<PercpuBlock>; MAX_CPU_COUNT as usize] =
|
||||
[const { AtomicPtr::new(core::ptr::null_mut()) }; MAX_CPU_COUNT as usize];
|
||||
|
||||
#[inline]
|
||||
pub fn get_percpu_block(idx: LogicalCpuId) -> Option<&'static PercpuBlock> {
|
||||
let ptr = ALL_PERCPU_BLOCKS
|
||||
.get(idx.get() as usize)?
|
||||
.load(Ordering::Relaxed);
|
||||
unsafe { ptr.as_ref() }
|
||||
}
|
||||
pub fn all_percpu_blocks() -> impl Iterator<Item = &'static PercpuBlock> {
|
||||
(0..ALL_PERCPU_BLOCKS.len()).filter_map(|i| get_percpu_block(LogicalCpuId::new(i as u32)))
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub unsafe fn init_tlb_shootdown(id: LogicalCpuId, block: *mut PercpuBlock) {
|
||||
ALL_PERCPU_BLOCKS[id.get() as usize].store(block, Ordering::Release)
|
||||
}
|
||||
|
||||
pub fn get_all_stats() -> Vec<(LogicalCpuId, CpuStatsData)> {
|
||||
let mut res = ALL_PERCPU_BLOCKS
|
||||
.iter()
|
||||
.filter_map(|block| unsafe { block.load(Ordering::Relaxed).as_ref() })
|
||||
let mut res = (0..ALL_PERCPU_BLOCKS.len())
|
||||
.filter_map(|i| get_percpu_block(LogicalCpuId::new(i as u32)))
|
||||
.map(|block| {
|
||||
let stats = &block.stats;
|
||||
(block.cpu_id, stats.into())
|
||||
@@ -86,11 +98,7 @@ pub fn shootdown_tlb_ipi(target: Option<LogicalCpuId>) {
|
||||
let my_percpublock = PercpuBlock::current();
|
||||
assert_ne!(target, my_percpublock.cpu_id);
|
||||
|
||||
let Some(percpublock) = (unsafe {
|
||||
ALL_PERCPU_BLOCKS[target.get() as usize]
|
||||
.load(Ordering::Acquire)
|
||||
.as_ref()
|
||||
}) else {
|
||||
let Some(percpublock) = (get_percpu_block(target)) else {
|
||||
warn!("Trying to TLB shootdown a CPU that doesn't exist or isn't initialized.");
|
||||
return;
|
||||
};
|
||||
|
||||
+1
-2
@@ -23,11 +23,10 @@ use crate::{
|
||||
GrantFileRef, MmapMode, PageSpan, UnmapVec, DANGLING,
|
||||
},
|
||||
unblock_context, wakeup_context, BorrowedHtBuf, ContextLock, PreemptGuard, PreemptGuardL1,
|
||||
Status, WeakContextRef,
|
||||
Status,
|
||||
},
|
||||
event,
|
||||
memory::{Frame, Page, VirtualAddress, PAGE_SIZE},
|
||||
percpu::PercpuBlock,
|
||||
scheme::SchemeId,
|
||||
sync::{CleanLockToken, LockToken, Mutex, RwLock, WaitQueue, L1},
|
||||
syscall::{
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ use crate::{
|
||||
},
|
||||
},
|
||||
memory::{Page, VirtualAddress, PAGE_SIZE},
|
||||
scheme::{self, FileHandle, KernelScheme, OpenResult, StrOrBytes},
|
||||
scheme::{FileHandle, KernelScheme, OpenResult, StrOrBytes},
|
||||
sync::{CleanLockToken, RwLock},
|
||||
syscall::{data::Stat, error::*, flag::*},
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ use syscall::EINTR;
|
||||
use crate::{
|
||||
context::{
|
||||
self,
|
||||
memory::{AccessMode, AddrSpace, AddrSpaceWrapper, Provider},
|
||||
memory::{AccessMode, AddrSpace, Provider},
|
||||
unblock_context, ContextLock,
|
||||
},
|
||||
memory::{Page, PhysicalAddress, VirtualAddress},
|
||||
|
||||
@@ -20,8 +20,7 @@ use crate::{
|
||||
context::{self, context::FdTbl},
|
||||
memory::{Page, VirtualAddress, PAGE_SIZE},
|
||||
scheme::{
|
||||
FileHandle, KernelScheme, SchemeExt, SchemeId, SchemeList, ALL_KERNEL_SCHEMES,
|
||||
KERNEL_SCHEMES_COUNT,
|
||||
FileHandle, KernelScheme, SchemeExt, SchemeList, ALL_KERNEL_SCHEMES, KERNEL_SCHEMES_COUNT,
|
||||
},
|
||||
startup::Bootstrap,
|
||||
syscall::{error::*, flag::MapFlags},
|
||||
|
||||
Reference in New Issue
Block a user