From: Minep Date: Sat, 11 Jun 2022 23:25:28 +0000 (+0100) Subject: fix: The timer sequence stuck in infinite loop after series of delete operation X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/commitdiff_plain/088403ac98acf7991507715d29a282dcba222053?ds=sidebyside;hp=--cc fix: The timer sequence stuck in infinite loop after series of delete operation fix: To mitigate race condition, make the system call mask interrupt by default, and unmask when and only when needed. improve: better debugging experience when GP happened due to the buggy iret! --- 088403ac98acf7991507715d29a282dcba222053 diff --git a/lunaix-os/bx_enh_dbg.ini b/lunaix-os/bx_enh_dbg.ini index c9f2bf5..5e8e298 100644 --- a/lunaix-os/bx_enh_dbg.ini +++ b/lunaix-os/bx_enh_dbg.ini @@ -19,8 +19,8 @@ isLittleEndian = TRUE DefaultAsmLines = 512 DumpWSIndex = 2 DockOrder = 0x123 -ListWidthPix[0] = 485 -ListWidthPix[1] = 667 -ListWidthPix[2] = 764 -MainWindow = 0, 0, 1283, 500 +ListWidthPix[0] = 257 +ListWidthPix[1] = 318 +ListWidthPix[2] = 367 +MainWindow = 0, 0, 743, 500 FontName = Normal diff --git a/lunaix-os/includes/lunaix/ds/llist.h b/lunaix-os/includes/lunaix/ds/llist.h index dd2a192..79fa991 100644 --- a/lunaix-os/includes/lunaix/ds/llist.h +++ b/lunaix-os/includes/lunaix/ds/llist.h @@ -1,12 +1,13 @@ /** * @file llist.h * @author Lunaixsky - * @brief This doubly linked cyclic list is adopted from Linux kernel + * @brief This doubly linked cyclic list is adopted from Linux kernel + * * @version 0.1 * @date 2022-03-12 - * + * * @copyright Copyright (c) 2022 - * + * */ #ifndef __LUNAIX_LLIST_H #define __LUNAIX_LLIST_H @@ -31,7 +32,8 @@ __llist_add(struct llist_header* elem, } static inline void -llist_init_head(struct llist_header* head) { +llist_init_head(struct llist_header* head) +{ head->next = head; head->prev = head; } @@ -49,16 +51,19 @@ llist_prepend(struct llist_header* head, struct llist_header* elem) } static inline void -llist_delete(struct llist_header* elem) { +llist_delete(struct llist_header* elem) +{ elem->prev->next = elem->next; - elem->next->prev = elem->next; - + elem->next->prev = elem->prev; + // make elem orphaned - elem->prev = elem; - elem->next = elem; + // elem->prev = elem; + // elem->next = elem; } -static inline int llist_empty(struct llist_header* elem) { +static inline int +llist_empty(struct llist_header* elem) +{ return elem->next == elem; } @@ -68,8 +73,7 @@ static inline int llist_empty(struct llist_header* elem) { * @type: the type of the struct this is embedded in. * @member: the name of the list_struct within the struct. */ -#define list_entry(ptr, type, member) \ - container_of(ptr, type, member) +#define list_entry(ptr, type, member) container_of(ptr, type, member) /** * list_for_each_entry - iterate over list of given type @@ -77,10 +81,10 @@ static inline int llist_empty(struct llist_header* elem) { * @head: the head for your list. * @member: the name of the list_struct within the struct. */ -#define llist_for_each(pos, n, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) +#define llist_for_each(pos, n, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member), \ + n = list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, typeof(*n), member)) #endif /* __LUNAIX_LLIST_H */ diff --git a/lunaix-os/kernel/asm/x86/idt.c b/lunaix-os/kernel/asm/x86/idt.c index 6c7246c..f453313 100644 --- a/lunaix-os/kernel/asm/x86/idt.c +++ b/lunaix-os/kernel/asm/x86/idt.c @@ -7,24 +7,40 @@ uint64_t _idt[IDT_ENTRY]; uint16_t _idt_limit = sizeof(_idt) - 1; -static inline void _set_idt_entry(uint32_t vector, uint16_t seg_selector, void (*isr)(), uint8_t dpl, uint8_t type) { +static inline void +_set_idt_entry(uint32_t vector, + uint16_t seg_selector, + void (*isr)(), + uint8_t dpl, + uint8_t type) +{ uintptr_t offset = (uintptr_t)isr; _idt[vector] = (offset & 0xffff0000) | IDT_ATTR(dpl, type); _idt[vector] <<= 32; _idt[vector] |= (seg_selector << 16) | (offset & 0x0000ffff); } -void _set_idt_intr_entry(uint32_t vector, uint16_t seg_selector, void (*isr)(), uint8_t dpl) { +void +_set_idt_intr_entry(uint32_t vector, + uint16_t seg_selector, + void (*isr)(), + uint8_t dpl) +{ _set_idt_entry(vector, seg_selector, isr, dpl, IDT_INTERRUPT); } -void _set_idt_trap_entry(uint32_t vector, uint16_t seg_selector, void (*isr)(), uint8_t dpl) { +void +_set_idt_trap_entry(uint32_t vector, + uint16_t seg_selector, + void (*isr)(), + uint8_t dpl) +{ _set_idt_entry(vector, seg_selector, isr, dpl, IDT_TRAP); } - void -_init_idt() { +_init_idt() +{ // CPU defined interrupts _set_idt_intr_entry(FAULT_DIVISION_ERROR, 0x08, _asm_isr0, 0); _set_idt_intr_entry(FAULT_GENERAL_PROTECTION, 0x08, _asm_isr13, 0); @@ -32,17 +48,21 @@ _init_idt() { _set_idt_intr_entry(APIC_ERROR_IV, 0x08, _asm_isr250, 0); _set_idt_intr_entry(APIC_LINT0_IV, 0x08, _asm_isr251, 0); - _set_idt_intr_entry(APIC_SPIV_IV, 0x08, _asm_isr252, 0); + _set_idt_intr_entry(APIC_SPIV_IV, 0x08, _asm_isr252, 0); _set_idt_intr_entry(APIC_TIMER_IV, 0x08, _asm_isr253, 0); - _set_idt_intr_entry(PC_KBD_IV, 0x08, _asm_isr201, 0); + _set_idt_intr_entry(PC_KBD_IV, 0x08, _asm_isr201, 0); - _set_idt_intr_entry(RTC_TIMER_IV, 0x08, _asm_isr210, 0); + _set_idt_intr_entry(RTC_TIMER_IV, 0x08, _asm_isr210, 0); // system defined interrupts _set_idt_intr_entry(LUNAIX_SYS_PANIC, 0x08, _asm_isr32, 0); - // syscall is a trap gate (recall: trap does NOT clear IF flag upon interruption) - // XXX: this should be fine, as our design of context switch support interruptible syscall - // FIXME: This may cause nasty concurrency bug! We should 'lockify' our code! - _set_idt_trap_entry(LUNAIX_SYS_CALL, 0x08, _asm_isr33, 3); + // syscall is a trap gate (recall: trap does NOT clear IF flag upon + // interruption) + // // XXX: this should be fine, as our design of context switch support + // interruptible syscall We make this a non-trap entry, and enable interrupt + // only when needed! + // FIXME: This may cause nasty concurrency bug! We should 'lockify' our + // code! + _set_idt_intr_entry(LUNAIX_SYS_CALL, 0x08, _asm_isr33, 3); } \ No newline at end of file diff --git a/lunaix-os/kernel/asm/x86/interrupt.S b/lunaix-os/kernel/asm/x86/interrupt.S index 4647e95..e0cda17 100644 --- a/lunaix-os/kernel/asm/x86/interrupt.S +++ b/lunaix-os/kernel/asm/x86/interrupt.S @@ -1,7 +1,7 @@ #define __ASM__ #include #include -// #define __ASM_INTR_DIAGNOSIS +#define __ASM_INTR_DIAGNOSIS .macro isr_template vector, no_error_code=1 .global _asm_isr\vector @@ -118,14 +118,9 @@ addl $8, %esp #ifdef __ASM_INTR_DIAGNOSIS - cmpl $0, (%esp) - jz 1f - iret -1: - movl $__current, %eax - movl (%esp), %ebx - movl $debug_resv, %ecx - ud2 -#else - iret + pushl %eax + movl 4(%esp), %eax + movl %eax, debug_resv + popl %eax #endif + iret diff --git a/lunaix-os/kernel/asm/x86/intr_routines.c b/lunaix-os/kernel/asm/x86/intr_routines.c index f68b2ce..0b05e75 100644 --- a/lunaix-os/kernel/asm/x86/intr_routines.c +++ b/lunaix-os/kernel/asm/x86/intr_routines.c @@ -1,7 +1,8 @@ #include -#include +#include #include #include +#include #include @@ -10,42 +11,46 @@ LOG_MODULE("INTR") extern void -intr_routine_page_fault (const isr_param* param); +intr_routine_page_fault(const isr_param* param); + +extern uint32_t debug_resv; -void -__print_panic_msg(const char* msg, const isr_param* param) +void +__print_panic_msg(const char* msg, const isr_param* param) { kprint_panic(" INT %u: (%x) [%p: %p] %s", - param->vector, - param->err_code, - param->cs, - param->eip, - msg); + param->vector, + param->err_code, + param->cs, + param->eip, + msg); } void -intr_routine_divide_zero (const isr_param* param) +intr_routine_divide_zero(const isr_param* param) { __print_panic_msg("Divide by zero!", param); spin(); } void -intr_routine_general_protection (const isr_param* param) +intr_routine_general_protection(const isr_param* param) { + kprintf(KERROR "Addr: %p\n", (&debug_resv)[0]); + kprintf(KERROR "Expected: %p\n", __current->intr_ctx.eip); __print_panic_msg("General Protection", param); spin(); } void -intr_routine_sys_panic (const isr_param* param) +intr_routine_sys_panic(const isr_param* param) { __print_panic_msg((char*)(param->registers.edi), param); spin(); } void -intr_routine_fallback (const isr_param* param) +intr_routine_fallback(const isr_param* param) { __print_panic_msg("Unknown Interrupt", param); spin(); @@ -53,17 +58,17 @@ intr_routine_fallback (const isr_param* param) /** * @brief ISR for Spurious interrupt - * + * * @param isr_param passed by CPU */ void -intr_routine_apic_spi (const isr_param* param) +intr_routine_apic_spi(const isr_param* param) { // FUTURE: do nothing for now } -void -intr_routine_apic_error (const isr_param* param) +void +intr_routine_apic_error(const isr_param* param) { uint32_t error_reg = apic_read_reg(APIC_ESR); char buf[32]; @@ -73,14 +78,14 @@ intr_routine_apic_error (const isr_param* param) } void -intr_routine_init() +intr_routine_init() { - intr_subscribe(FAULT_DIVISION_ERROR, intr_routine_divide_zero); + intr_subscribe(FAULT_DIVISION_ERROR, intr_routine_divide_zero); intr_subscribe(FAULT_GENERAL_PROTECTION, intr_routine_general_protection); - intr_subscribe(FAULT_PAGE_FAULT, intr_routine_page_fault); - intr_subscribe(LUNAIX_SYS_PANIC, intr_routine_sys_panic); - intr_subscribe(APIC_SPIV_IV, intr_routine_apic_spi); - intr_subscribe(APIC_ERROR_IV, intr_routine_apic_error); + intr_subscribe(FAULT_PAGE_FAULT, intr_routine_page_fault); + intr_subscribe(LUNAIX_SYS_PANIC, intr_routine_sys_panic); + intr_subscribe(APIC_SPIV_IV, intr_routine_apic_spi); + intr_subscribe(APIC_ERROR_IV, intr_routine_apic_error); intr_set_fallback_handler(intr_set_fallback_handler); } \ No newline at end of file diff --git a/lunaix-os/kernel/lxinit.c b/lunaix-os/kernel/lxinit.c index f7b0f95..fa8458c 100644 --- a/lunaix-os/kernel/lxinit.c +++ b/lunaix-os/kernel/lxinit.c @@ -15,7 +15,7 @@ extern uint8_t __kernel_start; LOG_MODULE("INIT") // #define FORK_BOMB_DEMO -#define WAIT_DEMO +// #define WAIT_DEMO void _lxinit_main() @@ -48,20 +48,16 @@ _lxinit_main() pid_t p = 0; - if (!(p = fork())) { + if (!fork()) { kprintf("Test no hang!"); - sleep(1); + sleep(12); _exit(0); } - waitpid(-1, &status, 0); - // FIXME: WNOHANG还有点问题…… - // waitpid(-1, &status, WNOHANG); - - sleep(2); + waitpid(-1, &status, WNOHANG); // 这里是就是LunaixOS的第一个进程了! - for (size_t i = 0; i < 10; i++) { + for (size_t i = 0; i < 5; i++) { pid_t pid = 0; if (!(pid = fork())) { sleep(i); diff --git a/lunaix-os/kernel/sched.c b/lunaix-os/kernel/sched.c index 35e3cff..442921e 100644 --- a/lunaix-os/kernel/sched.c +++ b/lunaix-os/kernel/sched.c @@ -70,6 +70,8 @@ schedule() return; } + // 上下文切换相当的敏感!我们不希望任何的中断打乱栈的顺序…… + cpu_disable_interrupt(); struct proc_info* next; int prev_ptr = sched_ctx.procs_index; int ptr = prev_ptr; @@ -81,8 +83,6 @@ schedule() sched_ctx.procs_index = ptr; - // 上下文切换相当的敏感!我们不希望任何的中断打乱栈的顺序…… - cpu_disable_interrupt(); run(next); } @@ -99,6 +99,7 @@ __DEFINE_LXSYSCALL1(unsigned int, sleep, unsigned int, seconds) if (!seconds) { return 0; } + if (__current->timer) { return __current->timer->counter / timer_context()->running_frequency; } @@ -118,7 +119,7 @@ __DEFINE_LXSYSCALL1(void, exit, int, status) __DEFINE_LXSYSCALL(void, yield) { - sched_yield(); + schedule(); } pid_t @@ -143,6 +144,8 @@ _wait(pid_t wpid, int* status, int options) if (llist_empty(&__current->children)) { return -1; } + + cpu_enable_interrupt(); repeat: llist_for_each(proc, n, &__current->children, siblings) { @@ -165,6 +168,7 @@ repeat: goto repeat; done: + cpu_disable_interrupt(); *status = (proc->exit_code & 0xffff) | status_flags; return destroy_process(proc->pid); }