Solve lock token and contexts for fdstat and debugger

This commit is contained in:
Wildan M
2026-04-06 13:35:23 +07:00
committed by Jeremy Soller
parent 0ad905f26e
commit ce08b60502
3 changed files with 88 additions and 45 deletions
+52 -17
View File
@@ -20,14 +20,13 @@ pub unsafe fn debugger(target_id: Option<*const ContextLock>, token: &mut CleanL
let old_table = unsafe { RmmA::table(TableKind::User) };
let mut contexts_guard = crate::context::contexts(token.token());
let (contexts, mut context_token) = contexts_guard.token_split();
for context_lock in contexts.iter() {
if target_id.map_or(false, |target_id| Arc::as_ptr(&context_lock.0) != target_id) {
let mut contexts = crate::percpu::get_all_contexts(token.downgrade());
for context_arc in contexts.iter() {
if target_id.map_or(false, |target_id| Arc::as_ptr(&context_arc) != target_id) {
continue;
}
let context = context_lock.0.read(context_token.token());
println!("{:p}: {}", Arc::as_ptr(&context_lock.0), context.name);
let context = context_arc.read(token.token());
println!("{:p}: {}", Arc::as_ptr(&context_arc), context.name);
let mut mark_frame_use = |frame| {
tree.entry(frame).or_insert((0, false)).0 += 1;
@@ -49,16 +48,36 @@ pub unsafe fn debugger(target_id: Option<*const ContextLock>, token: &mut CleanL
mark_frame_use(sig.thread_control.get());
}
// TODO: Lock ordering violation
let mut token = unsafe { CleanLockToken::new() };
// Switch to context page table to ensure syscall debug and stack dump will work
if let Some(ref space) = context.addr_space {
let was_new = spaces.insert(space.acquire_read().table.utable.table().phys().data());
let was_new = spaces.insert(
space
.acquire_read(token.downgrade())
.table
.utable
.table()
.phys()
.data(),
);
unsafe {
RmmA::set_table(
TableKind::User,
space.acquire_read().table.utable.table().phys(),
space
.acquire_read(token.downgrade())
.table
.utable
.table()
.phys(),
);
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
check_page_table_consistency(&mut space.acquire_write(), was_new, &mut tree);
check_page_table_consistency(
&mut space.acquire_write(token.downgrade()),
was_new,
&mut tree,
);
}
}
@@ -73,7 +92,7 @@ pub unsafe fn debugger(target_id: Option<*const ContextLock>, token: &mut CleanL
);
}
if let Some(ref addr_space) = context.addr_space {
let addr_space = addr_space.acquire_read();
let addr_space = addr_space.acquire_read(token.downgrade());
if !addr_space.grants.is_empty() {
println!("grants:");
for (base, info) in addr_space.grants.iter() {
@@ -150,11 +169,24 @@ pub unsafe fn debugger(target_id: Option<*const ContextLock>, token: &mut CleanL
println!();
}
drop(contexts_guard);
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
crate::scheme::proc::foreach_addrsp(token, |addrsp| {
let was_new = spaces.insert(addrsp.acquire_read().table.utable.table().phys().data());
unsafe { check_page_table_consistency(&mut *addrsp.acquire_write(), was_new, &mut tree) };
crate::scheme::proc::foreach_addrsp(token, |addrsp, mut token| {
let was_new = spaces.insert(
addrsp
.acquire_read(token.downgrade())
.table
.utable
.table()
.phys()
.data(),
);
unsafe {
check_page_table_consistency(
&mut *addrsp.acquire_write(token.downgrade()),
was_new,
&mut tree,
)
};
});
for (frame, (count, p)) in tree {
let Some(info) = get_page_info(frame) else {
@@ -182,15 +214,15 @@ fn dump_stack(context: &Context, mut sp: usize) {
let width = size_of::<usize>();
println!("stack: {:>0width$x}", sp, width = width);
let mut token = unsafe { CleanLockToken::new() };
//Maximum 64 usizes
for _ in 0..64 {
if context.addr_space.as_ref().map_or(false, |space| {
space
.acquire_read()
.acquire_read(token.downgrade())
.table
.utable
.translate(crate::paging::VirtualAddress::new(sp))
.translate(crate::memory::VirtualAddress::new(sp))
.is_some()
}) {
let value = unsafe { *(sp as *const usize) };
@@ -241,6 +273,9 @@ unsafe fn check_page_table_consistency(
};
for p1i in 0..512 {
use crate::memory::Page;
use rmm::VirtualAddress;
let (physaddr, flags) = match unsafe { p1.entry(p1i) } {
Some(e) => {
if let Ok(address) = e.address() {
+8 -3
View File
@@ -161,8 +161,13 @@ static HANDLES: RwLock<L1, HashMap<usize, Handle>> =
#[cfg(feature = "debugger")]
#[allow(dead_code)]
pub fn foreach_addrsp(token: &mut CleanLockToken, mut f: impl FnMut(&Arc<AddrSpaceWrapper>)) {
for (_, handle) in HANDLES.read(token.token()).iter() {
pub fn foreach_addrsp(
token: &mut CleanLockToken,
mut f: impl FnMut(&Arc<AddrSpaceWrapper>, LockToken<L1>),
) {
let mut handles_guard = HANDLES.read(token.token());
let (handles, mut token) = handles_guard.token_split();
for (_, handle) in handles.iter() {
let Handle {
kind:
ContextHandle::AddrSpace { addrspace, .. }
@@ -173,7 +178,7 @@ pub fn foreach_addrsp(token: &mut CleanLockToken, mut f: impl FnMut(&Arc<AddrSpa
else {
continue;
};
f(&addrspace);
f(&addrspace, token.token());
}
}
+28 -25
View File
@@ -1,7 +1,12 @@
use crate::{
context,
context::{file::FileDescription, memory::AddrSpaceWrapper},
scheme,
alloc::string::ToString,
context::{
self,
file::{FileDescription, LockedFileDescription},
memory::AddrSpaceWrapper,
},
percpu,
scheme::{self, handles, KernelSchemes},
sync::CleanLockToken,
syscall::error::Result,
};
@@ -27,17 +32,18 @@ pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
#[derive(Default)]
struct Descr {
owners: HashMap<Ref<AddrSpaceWrapper>, String>,
scheme: Box<str>,
scheme: &'static str,
}
let mut map = HashMap::<Ref<LockedFileDescription>, Descr>::new();
let mut report = String::new();
'contexts: for context in context::contexts(token.token())
.iter()
.filter_map(|c| c.upgrade())
{
let context = context.read();
let files = context.files.read();
let mut schemes_guard = handles().read(token.token());
let (schemes, mut token) = schemes_guard.token_split();
'contexts: for context in percpu::get_all_contexts(token.token()) {
let mut context_guard = context.read(token.token());
let (context, mut token) = context_guard.token_split();
let mut files_guard = context.files.read(token);
let (files, mut token) = files_guard.token_split();
writeln!(report, "'{}' {{", context.name).unwrap();
for file in files.iter().filter_map(|f| f.clone()) {
@@ -54,23 +60,20 @@ pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
};
let descr = map.entry(fr).or_default();
let scheme_id = file.description.read().scheme;
let scheme = scheme::schemes(token.token())
.names
.iter()
.flat_map(|(_, v)| v.iter())
.find_map(|(name, id)| {
if *id == scheme_id {
Some(name.clone())
} else {
None
}
});
let scheme_id = file.description.read(token.token()).scheme;
let scheme = schemes.get(&scheme_id);
descr
.owners
.entry(Ref(a))
.or_insert(context.name.clone().into_owned());
descr.scheme = scheme.unwrap_or(Box::from("[unknown]"));
.or_insert(context.name.clone().to_string());
descr.scheme = scheme
.map(|k| match k {
scheme::Handle::SchemeCreationCapability => "SchemeCreationCapability",
scheme::Handle::Scheme(KernelSchemes::Global(g)) => g.as_str(),
scheme::Handle::Scheme(KernelSchemes::User(g)) => "[user]",
scheme::Handle::Scheme(KernelSchemes::SchemeMgr) => "SchemeMgr",
})
.unwrap_or("[unknown]");
}
writeln!(report, "}}").unwrap();
}