From d0f9e8dfcf417fadda0a39ad6210bc2688206e4f Mon Sep 17 00:00:00 2001 From: Sparchatus Date: Tue, 12 Apr 2022 10:56:09 +0000 Subject: [PATCH] Fix a deadlock during paging --- lib/aos/aos_rpc.c | 20 ++++++++++---------- lib/aos/paging.c | 8 +++++++- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/lib/aos/aos_rpc.c b/lib/aos/aos_rpc.c index 50b421f..4a08083 100644 --- a/lib/aos/aos_rpc.c +++ b/lib/aos/aos_rpc.c @@ -77,7 +77,7 @@ aos_rpc_send_number(struct aos_rpc *rpc, uintptr_t num) { // given channel and wait until the ack gets returned. errval_t err; - thread_mutex_lock(&rpc->lock); + thread_mutex_lock_nested(&rpc->lock); err = do_aos_rpc( rpc, RPC_MTYPE_SEND_NUMBER, 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; 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); err = do_aos_rpc( 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; - thread_mutex_lock(&rpc->lock); + thread_mutex_lock_nested(&rpc->lock); err = do_aos_rpc( rpc, RPC_MTYPE_GET_RAM_CAP, NULL_CAP, 0, bytes, alignment, @@ -135,7 +135,7 @@ aos_rpc_serial_getchar(struct aos_rpc *rpc, char *retc) { errval_t err; uintptr_t retval; - thread_mutex_lock(&rpc->lock); + thread_mutex_lock_nested(&rpc->lock); err = do_aos_rpc( rpc, RPC_MTYPE_SERIAL_GETCHAR, NULL_CAP, 0, 0, 0, @@ -153,7 +153,7 @@ aos_rpc_serial_putchar(struct aos_rpc *rpc, char c) { // serial port. errval_t err; - thread_mutex_lock(&rpc->lock); + thread_mutex_lock_nested(&rpc->lock); err = do_aos_rpc( rpc, RPC_MTYPE_SERIAL_PUTCHAR, 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 written_bytes; - thread_mutex_lock(&rpc->lock); + thread_mutex_lock_nested(&rpc->lock); memcpy(rpc->shared_mem, buf, chunk_len); err = do_aos_rpc( 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 read_bytes; - thread_mutex_lock(&rpc->lock); + thread_mutex_lock_nested(&rpc->lock); err = do_aos_rpc( rpc, RPC_MTYPE_SERIAL_READ, 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; 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); uintptr_t retval; 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; errval_t err; - thread_mutex_lock(&rpc->lock); + thread_mutex_lock_nested(&rpc->lock); err = do_aos_rpc( rpc, RPC_MTYPE_PROCESS_GET_NAME, 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; errval_t err; - thread_mutex_lock(&rpc->lock); + thread_mutex_lock_nested(&rpc->lock); err = do_aos_rpc( rpc, RPC_MTYPE_PROCESS_GET_ALL_PIDS, NULL_CAP, 0, 0, 0, diff --git a/lib/aos/paging.c b/lib/aos/paging.c index 810ad55..b3e265e 100644 --- a/lib/aos/paging.c +++ b/lib/aos/paging.c @@ -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, struct capref frame, size_t bytes, int flags); +__attribute__((__used__)) static char *pt_exception_type_to_string(enum exception_type type, int subtype) { switch(type) { @@ -96,11 +97,12 @@ static void pt_exception_handler(enum exception_type type, int subtype, errval_t err; 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), addr, ip ); + // WARNING: these debug calls can overflow the stack // debug_print_save_area(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); 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); + // debug_printf("[pt_exception_handler] Got paging mutex.\n"); struct pt_vaddr_reg_t *vaddr_reg = &st->vaddr_head; 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"); } + // debug_printf("[pt_exception_handler] Releasing paging mutex.\n"); thread_mutex_unlock(&st->lock); + // debug_printf("[pt_exception_handler] done\n"); } /**