Fix a deadlock during paging

This commit is contained in:
Sparchatus 2022-04-12 10:56:09 +00:00
parent 53369ab564
commit d0f9e8dfcf
2 changed files with 17 additions and 11 deletions

View File

@ -77,7 +77,7 @@ aos_rpc_send_number(struct aos_rpc *rpc, uintptr_t num) {
// given channel and wait until the ack gets returned. // given channel and wait until the ack gets returned.
errval_t err; errval_t err;
thread_mutex_lock(&rpc->lock); thread_mutex_lock_nested(&rpc->lock);
err = do_aos_rpc( err = do_aos_rpc(
rpc, RPC_MTYPE_SEND_NUMBER, rpc, RPC_MTYPE_SEND_NUMBER,
NULL_CAP, 0, num, 0, NULL_CAP, 0, num, 0,
@ -96,7 +96,7 @@ aos_rpc_send_string(struct aos_rpc *rpc, const char *string) {
size_t string_size = strlen(string) + 1; size_t string_size = strlen(string) + 1;
if (string_size > RPC_SHARED_SIZE) return AOS_ERR_RPC_ARG_TOO_BIG; if (string_size > RPC_SHARED_SIZE) return AOS_ERR_RPC_ARG_TOO_BIG;
thread_mutex_lock(&rpc->lock); thread_mutex_lock_nested(&rpc->lock);
memcpy(rpc->shared_mem, string, string_size); memcpy(rpc->shared_mem, string, string_size);
err = do_aos_rpc( err = do_aos_rpc(
rpc, RPC_MTYPE_SEND_STRING, rpc, RPC_MTYPE_SEND_STRING,
@ -116,7 +116,7 @@ aos_rpc_get_ram_cap(struct aos_rpc *rpc, size_t bytes, size_t alignment,
errval_t err; errval_t err;
thread_mutex_lock(&rpc->lock); thread_mutex_lock_nested(&rpc->lock);
err = do_aos_rpc( err = do_aos_rpc(
rpc, RPC_MTYPE_GET_RAM_CAP, rpc, RPC_MTYPE_GET_RAM_CAP,
NULL_CAP, 0, bytes, alignment, NULL_CAP, 0, bytes, alignment,
@ -135,7 +135,7 @@ aos_rpc_serial_getchar(struct aos_rpc *rpc, char *retc) {
errval_t err; errval_t err;
uintptr_t retval; uintptr_t retval;
thread_mutex_lock(&rpc->lock); thread_mutex_lock_nested(&rpc->lock);
err = do_aos_rpc( err = do_aos_rpc(
rpc, RPC_MTYPE_SERIAL_GETCHAR, rpc, RPC_MTYPE_SERIAL_GETCHAR,
NULL_CAP, 0, 0, 0, NULL_CAP, 0, 0, 0,
@ -153,7 +153,7 @@ aos_rpc_serial_putchar(struct aos_rpc *rpc, char c) {
// serial port. // serial port.
errval_t err; errval_t err;
thread_mutex_lock(&rpc->lock); thread_mutex_lock_nested(&rpc->lock);
err = do_aos_rpc( err = do_aos_rpc(
rpc, RPC_MTYPE_SERIAL_PUTCHAR, rpc, RPC_MTYPE_SERIAL_PUTCHAR,
NULL_CAP, 0, c, 0, NULL_CAP, 0, c, 0,
@ -176,7 +176,7 @@ aos_rpc_serial_write(struct aos_rpc *rpc, const char *buf, size_t buf_len) {
size_t chunk_len = MIN(buf_len, RPC_SHARED_SIZE); size_t chunk_len = MIN(buf_len, RPC_SHARED_SIZE);
size_t written_bytes; size_t written_bytes;
thread_mutex_lock(&rpc->lock); thread_mutex_lock_nested(&rpc->lock);
memcpy(rpc->shared_mem, buf, chunk_len); memcpy(rpc->shared_mem, buf, chunk_len);
err = do_aos_rpc( err = do_aos_rpc(
rpc, RPC_MTYPE_SERIAL_WRITE, rpc, RPC_MTYPE_SERIAL_WRITE,
@ -217,7 +217,7 @@ aos_rpc_serial_read(struct aos_rpc *rpc, char *buf, size_t buf_len) {
size_t chunk_len = MIN(buf_len, RPC_SHARED_SIZE); size_t chunk_len = MIN(buf_len, RPC_SHARED_SIZE);
size_t read_bytes; size_t read_bytes;
thread_mutex_lock(&rpc->lock); thread_mutex_lock_nested(&rpc->lock);
err = do_aos_rpc( err = do_aos_rpc(
rpc, RPC_MTYPE_SERIAL_READ, rpc, RPC_MTYPE_SERIAL_READ,
NULL_CAP, 0, chunk_len, 0, NULL_CAP, 0, chunk_len, 0,
@ -253,7 +253,7 @@ aos_rpc_process_spawn(struct aos_rpc *rpc, char *cmdline,
size_t cmdline_size = strlen(cmdline) + 1; size_t cmdline_size = strlen(cmdline) + 1;
if (cmdline_size > RPC_SHARED_SIZE) return AOS_ERR_RPC_ARG_TOO_BIG; if (cmdline_size > RPC_SHARED_SIZE) return AOS_ERR_RPC_ARG_TOO_BIG;
thread_mutex_lock(&rpc->lock); thread_mutex_lock_nested(&rpc->lock);
memcpy(rpc->shared_mem, cmdline, cmdline_size); memcpy(rpc->shared_mem, cmdline, cmdline_size);
uintptr_t retval; uintptr_t retval;
errval_t err = do_aos_rpc( errval_t err = do_aos_rpc(
@ -275,7 +275,7 @@ aos_rpc_process_get_name(struct aos_rpc *rpc, domainid_t pid, char **name) {
size_t name_len; size_t name_len;
errval_t err; errval_t err;
thread_mutex_lock(&rpc->lock); thread_mutex_lock_nested(&rpc->lock);
err = do_aos_rpc( err = do_aos_rpc(
rpc, RPC_MTYPE_PROCESS_GET_NAME, rpc, RPC_MTYPE_PROCESS_GET_NAME,
NULL_CAP, 0, pid, 0, NULL_CAP, 0, pid, 0,
@ -301,7 +301,7 @@ aos_rpc_process_get_all_pids(struct aos_rpc *rpc, domainid_t **pids,
size_t ret_len; size_t ret_len;
errval_t err; errval_t err;
thread_mutex_lock(&rpc->lock); thread_mutex_lock_nested(&rpc->lock);
err = do_aos_rpc( err = do_aos_rpc(
rpc, RPC_MTYPE_PROCESS_GET_ALL_PIDS, rpc, RPC_MTYPE_PROCESS_GET_ALL_PIDS,
NULL_CAP, 0, 0, 0, NULL_CAP, 0, 0, 0,

View File

@ -37,6 +37,7 @@ static char pt_static_exception_stack[PT_STATIC_EXCEPTION_STACK_SIZE];
static errval_t _paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr, static errval_t _paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr,
struct capref frame, size_t bytes, int flags); struct capref frame, size_t bytes, int flags);
__attribute__((__used__))
static char *pt_exception_type_to_string(enum exception_type type, int subtype) static char *pt_exception_type_to_string(enum exception_type type, int subtype)
{ {
switch(type) { switch(type) {
@ -96,11 +97,12 @@ static void pt_exception_handler(enum exception_type type, int subtype,
errval_t err; errval_t err;
lvaddr_t ip = registers_get_ip(regs); lvaddr_t ip = registers_get_ip(regs);
debug_printf("Page Fault: type=%s, addr=%p, ip=%p\n", debug_printf("[pt_exception_handler] type=%s, addr=%p, ip=%p\n",
pt_exception_type_to_string(type, subtype), pt_exception_type_to_string(type, subtype),
addr, addr,
ip ip
); );
// WARNING: these debug calls can overflow the stack
// debug_print_save_area(regs); // debug_print_save_area(regs);
// debug_dump(regs); // debug_dump(regs);
@ -112,7 +114,9 @@ static void pt_exception_handler(enum exception_type type, int subtype,
lvaddr_t page_addr = ROUND_DOWN((lvaddr_t)addr, BASE_PAGE_SIZE); lvaddr_t page_addr = ROUND_DOWN((lvaddr_t)addr, BASE_PAGE_SIZE);
struct paging_state *st = get_current_paging_state(); struct paging_state *st = get_current_paging_state();
// debug_printf("[pt_exception_handler] Attempting to get paging mutex.\n");
thread_mutex_lock_nested(&st->lock); thread_mutex_lock_nested(&st->lock);
// debug_printf("[pt_exception_handler] Got paging mutex.\n");
struct pt_vaddr_reg_t *vaddr_reg = &st->vaddr_head; struct pt_vaddr_reg_t *vaddr_reg = &st->vaddr_head;
for (; vaddr_reg != NULL; vaddr_reg = vaddr_reg->next) { for (; vaddr_reg != NULL; vaddr_reg = vaddr_reg->next) {
@ -143,7 +147,9 @@ static void pt_exception_handler(enum exception_type type, int subtype,
USER_PANIC_ERR(err, "Failed to map frame in page fault handler"); USER_PANIC_ERR(err, "Failed to map frame in page fault handler");
} }
// debug_printf("[pt_exception_handler] Releasing paging mutex.\n");
thread_mutex_unlock(&st->lock); thread_mutex_unlock(&st->lock);
// debug_printf("[pt_exception_handler] done\n");
} }
/** /**