Solve lock token and contexts for fdstat and debugger
This commit is contained in:
+52
-17
@@ -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
@@ -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
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user