Fix sys stats to reveal contexts in all CPU
This commit is contained in:
+18
-2
@@ -13,11 +13,13 @@ use syscall::PtraceFlags;
|
||||
|
||||
use crate::{
|
||||
arch::device::ArchPercpuMisc,
|
||||
context::{empty_cr3, memory::AddrSpaceWrapper, switch::ContextSwitchPercpu, ContextRef},
|
||||
context::{
|
||||
empty_cr3, memory::AddrSpaceWrapper, switch::ContextSwitchPercpu, ContextLock, ContextRef,
|
||||
},
|
||||
cpu_set::{LogicalCpuId, MAX_CPU_COUNT},
|
||||
cpu_stats::{CpuStats, CpuStatsData},
|
||||
ptrace::Session,
|
||||
sync::{CleanLockToken, RwLock, L1},
|
||||
sync::{CleanLockToken, LockToken, RwLock, L0, L1},
|
||||
syscall::debug::SyscallDebugInfo,
|
||||
};
|
||||
|
||||
@@ -70,6 +72,20 @@ pub fn get_all_stats() -> Vec<(LogicalCpuId, CpuStatsData)> {
|
||||
res
|
||||
}
|
||||
|
||||
/// Get copy of all cpu ref contexts
|
||||
pub fn get_all_contexts(mut token: LockToken<'_, L1>) -> Vec<Arc<ContextLock>> {
|
||||
let mut all_contexts = Vec::new();
|
||||
for block in ALL_PERCPU_BLOCKS
|
||||
.iter()
|
||||
.filter_map(|block| unsafe { block.load(Ordering::Relaxed).as_ref() })
|
||||
{
|
||||
// TODO: Lock token violation, downgrade this to L2 later
|
||||
let contexts = unsafe { &block.contexts.reupgradeable_read(token.token()) };
|
||||
all_contexts.extend(contexts.iter().filter_map(|x| x.upgrade()));
|
||||
}
|
||||
all_contexts
|
||||
}
|
||||
|
||||
// PercpuBlock::current() is implemented somewhere in the arch-specific modules
|
||||
|
||||
pub fn shootdown_tlb_ipi(target: Option<LogicalCpuId>) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use alloc::{string::String, vec::Vec};
|
||||
use core::fmt::Write;
|
||||
|
||||
use crate::{context, sync::CleanLockToken, syscall::error::Result};
|
||||
use crate::{context, percpu, sync::CleanLockToken, syscall::error::Result};
|
||||
|
||||
pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
||||
let mut string = String::new();
|
||||
@@ -9,9 +9,8 @@ pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
||||
{
|
||||
let mut rows = Vec::new();
|
||||
{
|
||||
let mut contexts = context::contexts(token.token());
|
||||
let (contexts, mut token) = contexts.token_split();
|
||||
for context_lock in contexts.iter().filter_map(|r| r.upgrade()) {
|
||||
let contexts = percpu::get_all_contexts(token.downgrade());
|
||||
for context_lock in contexts {
|
||||
let context = context_lock.read(token.token());
|
||||
rows.push((context.pid, context.name, context.status_reason));
|
||||
}
|
||||
|
||||
+52
-41
@@ -5,7 +5,7 @@ use alloc::{
|
||||
};
|
||||
use core::fmt::Write;
|
||||
|
||||
use crate::{context, sync::CleanLockToken, syscall::error::Result};
|
||||
use crate::{context, percpu, sync::CleanLockToken, syscall::error::Result};
|
||||
|
||||
pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
||||
let mut string = format!(
|
||||
@@ -15,32 +15,59 @@ pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
||||
|
||||
let mut rows = Vec::new();
|
||||
{
|
||||
let mut contexts = context::contexts(token.token());
|
||||
let (contexts, mut token) = contexts.token_split();
|
||||
for context_ref in contexts.iter().filter_map(|r| r.upgrade()) {
|
||||
let mut contexts = percpu::get_all_contexts(token.downgrade());
|
||||
for context_ref in contexts {
|
||||
let context = context_ref.read(token.token());
|
||||
let addr_space = context.addr_space().map(|a| a.clone());
|
||||
|
||||
let affinity = context.sched_affinity.to_string();
|
||||
let cpu_time_s = context.cpu_time / crate::time::NANOS_PER_SEC;
|
||||
let cpu_time_ns = context.cpu_time % crate::time::NANOS_PER_SEC;
|
||||
let mut memory = context.kfx.len();
|
||||
if let Some(ref kstack) = context.kstack {
|
||||
memory += kstack.len();
|
||||
}
|
||||
let (status, cpuid) = (context.status.clone(), context.cpu_id);
|
||||
let (pid, euid, egid) = (context.pid, context.euid, context.egid);
|
||||
let (running, is_awake) = (context.running, context.wake.is_some());
|
||||
let name = context.name;
|
||||
drop(context);
|
||||
|
||||
let heap = match addr_space {
|
||||
Ok(addr_space) => {
|
||||
let addr_space_guard = addr_space.acquire_read(token.downgrade());
|
||||
let mut memory = 0;
|
||||
// TODO: All user programs must have some grant in order for executable memory to even
|
||||
// exist, but is this a good indicator of whether it is user or kernel?
|
||||
let is_kernel = addr_space_guard.grants.is_empty();
|
||||
for (_base, info) in addr_space_guard.grants.iter() {
|
||||
// TODO: shared memory? wrap as method?
|
||||
if matches!(info.provider, context::memory::Provider::Allocated { .. }) {
|
||||
memory += info.page_count() * crate::memory::PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
Some((memory, is_kernel))
|
||||
}
|
||||
Err(_) => None,
|
||||
};
|
||||
|
||||
let mut stat_string = String::new();
|
||||
// TODO: All user programs must have some grant in order for executable memory to even
|
||||
// exist, but is this a good indicator of whether it is user or kernel?
|
||||
stat_string.push(match context.addr_space() {
|
||||
Ok(addr_space) => {
|
||||
// TODO: Commented out due Lock ordering violation
|
||||
// if addr_space.acquire_read(token.downgrade()).grants.is_empty() {
|
||||
// 'K'
|
||||
// } else {
|
||||
// 'U'
|
||||
// }
|
||||
'U'
|
||||
stat_string.push(match heap {
|
||||
Some((pages, is_kernel)) => {
|
||||
if is_kernel {
|
||||
'K'
|
||||
} else {
|
||||
'U'
|
||||
}
|
||||
}
|
||||
_ => 'R',
|
||||
});
|
||||
match context.status {
|
||||
match status {
|
||||
context::Status::Runnable => {
|
||||
stat_string.push('R');
|
||||
}
|
||||
context::Status::Blocked | context::Status::HardBlocked { .. } => {
|
||||
if context.wake.is_some() {
|
||||
if is_awake {
|
||||
stat_string.push('S');
|
||||
} else {
|
||||
stat_string.push('B');
|
||||
@@ -50,20 +77,16 @@ pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
||||
stat_string.push('Z');
|
||||
}
|
||||
}
|
||||
if context.running {
|
||||
if running {
|
||||
stat_string.push('+');
|
||||
}
|
||||
|
||||
let cpu_string = match context.cpu_id {
|
||||
let cpu_string = match cpuid {
|
||||
Some(cpu_id) => {
|
||||
format!("{cpu_id}")
|
||||
}
|
||||
_ => "?".to_owned(),
|
||||
};
|
||||
let affinity = context.sched_affinity.to_string();
|
||||
|
||||
let cpu_time_s = context.cpu_time / crate::time::NANOS_PER_SEC;
|
||||
let cpu_time_ns = context.cpu_time % crate::time::NANOS_PER_SEC;
|
||||
let cpu_time_string = format!(
|
||||
"{:02}:{:02}:{:02}.{:02}",
|
||||
cpu_time_s / 3600,
|
||||
@@ -72,21 +95,9 @@ pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
||||
cpu_time_ns / 10_000_000
|
||||
);
|
||||
|
||||
let mut memory = context.kfx.len();
|
||||
if let Some(ref kstack) = context.kstack {
|
||||
memory += kstack.len();
|
||||
if let Some((heap, _)) = heap {
|
||||
memory += heap;
|
||||
}
|
||||
// TODO: Commented out due Lock ordering violation
|
||||
/*
|
||||
if let Ok(addr_space) = context.addr_space() {
|
||||
for (_base, info) in addr_space.acquire_read(token.downgrade()).grants.iter() {
|
||||
// TODO: method
|
||||
if matches!(info.provider, context::memory::Provider::Allocated { .. }) {
|
||||
memory += info.page_count() * PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
let memory_string = if memory >= 1024 * 1024 * 1024 {
|
||||
format!("{} GB", memory / 1024 / 1024 / 1024)
|
||||
@@ -99,15 +110,15 @@ pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
||||
};
|
||||
|
||||
rows.push((
|
||||
context.pid,
|
||||
context.euid,
|
||||
context.egid,
|
||||
pid,
|
||||
euid,
|
||||
egid,
|
||||
stat_string,
|
||||
cpu_string,
|
||||
affinity,
|
||||
cpu_time_string,
|
||||
memory_string,
|
||||
context.name,
|
||||
name,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::{
|
||||
memory::{Grant, PageSpan},
|
||||
},
|
||||
memory::PAGE_SIZE,
|
||||
scheme,
|
||||
percpu, scheme,
|
||||
sync::CleanLockToken,
|
||||
syscall::{
|
||||
error::Result,
|
||||
@@ -22,9 +22,7 @@ fn inner(fpath_user: UserSliceRw, token: &mut CleanLockToken) -> Result<Vec<u8>>
|
||||
{
|
||||
let mut rows = Vec::new();
|
||||
{
|
||||
let mut contexts = context::contexts(token.token());
|
||||
let (contexts, mut token) = contexts.token_split();
|
||||
for context_ref in contexts.iter().filter_map(|r| r.upgrade()) {
|
||||
for context_ref in percpu::get_all_contexts(token.downgrade()) {
|
||||
let mut current = context_ref.read(token.token());
|
||||
let (context, mut token) = current.token_split();
|
||||
rows.push((
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use core::fmt::Write as _;
|
||||
|
||||
use crate::{
|
||||
context::{contexts, ContextRef, Status},
|
||||
context::{ContextRef, Status},
|
||||
cpu_stats::{get_context_switch_count, get_contexts_count, irq_counts},
|
||||
percpu::get_all_stats,
|
||||
percpu::{self, get_all_stats},
|
||||
sync::CleanLockToken,
|
||||
syscall::error::Result,
|
||||
time::START,
|
||||
@@ -76,11 +76,8 @@ fn get_contexts_stats(token: &mut CleanLockToken) -> (u64, u64) {
|
||||
let mut running = 0;
|
||||
let mut blocked = 0;
|
||||
|
||||
let mut contexts = contexts(token.token());
|
||||
let (contexts, mut token) = contexts.token_split();
|
||||
let statuses = contexts
|
||||
let statuses = percpu::get_all_contexts(token.downgrade())
|
||||
.iter()
|
||||
.filter_map(ContextRef::upgrade)
|
||||
.map(|context| context.read(token.token()).status.clone())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
use alloc::{string::String, vec::Vec};
|
||||
use core::fmt::Write;
|
||||
|
||||
use crate::{context, sync::CleanLockToken, syscall, syscall::error::Result};
|
||||
use crate::{
|
||||
context, percpu,
|
||||
sync::CleanLockToken,
|
||||
syscall::{self, error::Result},
|
||||
};
|
||||
|
||||
pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
||||
let mut string = String::new();
|
||||
@@ -9,9 +13,7 @@ pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
||||
{
|
||||
let mut rows = Vec::new();
|
||||
{
|
||||
let mut contexts = context::contexts(token.token());
|
||||
let (contexts, mut token) = contexts.token_split();
|
||||
for context_ref in contexts.iter().filter_map(|r| r.upgrade()) {
|
||||
for context_ref in percpu::get_all_contexts(token.downgrade()) {
|
||||
let context = context_ref.read(token.token());
|
||||
rows.push((context.pid, context.name, context.current_syscall()));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user