From 06af77bd79e293dbd71fd423d92a40c50076b0be Mon Sep 17 00:00:00 2001 From: fslongjin Date: Mon, 15 Aug 2022 12:09:04 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=E4=BA=86page=E7=9A=84?= =?UTF-8?q?=E9=94=81=E6=9C=AA=E8=A2=AB=E5=88=9D=E5=A7=8B=E5=8C=96=E7=9A=84?= =?UTF-8?q?bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 3 ++- Makefile | 2 +- kernel/arch/x86_64/current.h | 2 +- kernel/driver/interrupt/apic/apic.c | 2 +- kernel/driver/interrupt/apic/apic_timer.c | 5 +++-- kernel/driver/usb/usb.c | 5 +++-- kernel/driver/usb/xhci/xhci.c | 6 +++--- kernel/exception/irq.c | 3 +++ kernel/lib/libUI/textui.c | 10 ++++++---- kernel/mm/mm.c | 6 +++--- kernel/mm/mmap.c | 7 ++----- kernel/mm/vma.c | 4 ++-- kernel/smp/smp.c | 4 +++- 13 files changed, 33 insertions(+), 26 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 56386d57..3ca7c3d3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -125,7 +125,8 @@ "semaphore.h": "c", "mm-types.h": "c", "vfs.h": "c", - "current.h": "c" + "current.h": "c", + "proc-types.h": "c" }, "C_Cpp.errorSquiggles": "Enabled", "esbonio.sphinx.confDir": "" diff --git a/Makefile b/Makefile index f3592417..1a87b4c1 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ export ARCH=__x86_64__ export ROOT_PATH=$(shell pwd) export DEBUG=DEBUG -export GLOBAL_CFLAGS := -mcmodel=large -fno-builtin -m64 -fno-stack-protector -D $(ARCH) -O0 +export GLOBAL_CFLAGS := -mcmodel=large -fno-builtin -m64 -fno-stack-protector -D $(ARCH) -O1 ifeq ($(DEBUG), DEBUG) GLOBAL_CFLAGS += -g diff --git a/kernel/arch/x86_64/current.h b/kernel/arch/x86_64/current.h index da26753d..44289785 100644 --- a/kernel/arch/x86_64/current.h +++ b/kernel/arch/x86_64/current.h @@ -5,7 +5,7 @@ #pragma GCC optimize("O0") struct process_control_block; // 获取当前的pcb -static __always_inline struct process_control_block *get_current_pcb() +struct process_control_block *get_current_pcb() { struct process_control_block *current = NULL; // 利用了当前pcb和栈空间总大小为32k大小对齐,将rsp低15位清空,即可获得pcb的起始地址 diff --git a/kernel/driver/interrupt/apic/apic.c b/kernel/driver/interrupt/apic/apic.c index 1d87c7e8..f77461db 100644 --- a/kernel/driver/interrupt/apic/apic.c +++ b/kernel/driver/interrupt/apic/apic.c @@ -509,7 +509,7 @@ void do_IRQ(struct pt_regs *rsp, ul number) // 检测当前进程是否可被调度 if (current_pcb->flags & PF_NEED_SCHED) { - // kdebug("to sched"); + io_mfence(); sched_cfs(); } } diff --git a/kernel/driver/interrupt/apic/apic_timer.c b/kernel/driver/interrupt/apic/apic_timer.c index 3f2768f1..3c873d42 100644 --- a/kernel/driver/interrupt/apic/apic_timer.c +++ b/kernel/driver/interrupt/apic/apic_timer.c @@ -73,7 +73,7 @@ hardware_intr_controller apic_timer_intr_controller = */ void apic_timer_handler(uint64_t number, uint64_t param, struct pt_regs *regs) { - + io_mfence(); sched_update_jiffies(); io_mfence(); } @@ -91,7 +91,8 @@ void apic_timer_init() hlt(); } kinfo("Initializing apic timer for cpu %d", proc_current_cpu_id); - + io_mfence(); irq_register(APIC_TIMER_IRQ_NUM, &apic_timer_ticks_result, &apic_timer_handler, 0, &apic_timer_intr_controller, "apic timer"); + io_mfence(); kinfo("Successfully initialized apic timer for cpu %d", proc_current_cpu_id); } \ No newline at end of file diff --git a/kernel/driver/usb/usb.c b/kernel/driver/usb/usb.c index 8f041eb2..f9e8d9a3 100644 --- a/kernel/driver/usb/usb.c +++ b/kernel/driver/usb/usb.c @@ -30,9 +30,9 @@ void usb_init() kwarn("There is no usb hardware in this computer!"); return; } - + kdebug("usb_pdevs_count=%d",usb_pdevs_count); // 初始化每个usb控制器 - for (int i = 0; i < usb_pdevs_count; ++i) + for (volatile int i = 0; i < usb_pdevs_count; ++i) { io_mfence(); switch (usb_pdevs[i]->ProgIF) @@ -47,6 +47,7 @@ void usb_init() case USB_TYPE_XHCI: // 初始化对应的xhci控制器 + io_mfence(); xhci_init((struct pci_device_structure_general_device_t *)usb_pdevs[i]); io_mfence(); break; diff --git a/kernel/driver/usb/xhci/xhci.c b/kernel/driver/usb/xhci/xhci.c index c7592e66..0411ebc4 100644 --- a/kernel/driver/usb/xhci/xhci.c +++ b/kernel/driver/usb/xhci/xhci.c @@ -10,7 +10,6 @@ #include // 由于xhci寄存器读取需要对齐,因此禁用GCC优化选项 -#pragma GCC push_options #pragma GCC optimize("O0") spinlock_t xhci_controller_init_lock = {0}; // xhci控制器初始化锁(在usb_init中被初始化) @@ -963,7 +962,9 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr) FAIL_ON_TO(xhci_hc_init_intr(cid), failed_free_dyn); io_mfence(); ++xhci_ctrl_count; + io_mfence(); spin_unlock(&xhci_controller_init_lock); + io_mfence(); return; failed_free_dyn:; // 释放动态申请的内存 @@ -990,5 +991,4 @@ failed:; failed_exceed_max:; kerror("Failed to initialize controller: bus=%d, dev=%d, func=%d", dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func); spin_unlock(&xhci_controller_init_lock); -} -#pragma GCC pop_options \ No newline at end of file +} \ No newline at end of file diff --git a/kernel/exception/irq.c b/kernel/exception/irq.c index 3c134ae2..eb066eee 100644 --- a/kernel/exception/irq.c +++ b/kernel/exception/irq.c @@ -215,8 +215,11 @@ int irq_register(ul irq_num, void *arg, void (*handler)(ul irq_num, ul parameter p->flags = 0; p->handler = handler; + io_mfence(); p->controller->install(irq_num, arg); + io_mfence(); p->controller->enable(irq_num); + io_mfence(); return 0; } diff --git a/kernel/lib/libUI/textui.c b/kernel/lib/libUI/textui.c index e8a047dc..0ec85b7a 100644 --- a/kernel/lib/libUI/textui.c +++ b/kernel/lib/libUI/textui.c @@ -208,13 +208,14 @@ int textui_putchar_window(struct textui_window_t *window, uint16_t character, ui if (!textui_is_chromatic(window->flags)) // 暂不支持纯文本窗口 return 0; - uint64_t rflags = 0; // 加锁后rflags存储到这里 - spin_lock_irqsave(&window->lock, rflags); + // uint64_t rflags = 0; // 加锁后rflags存储到这里 + spin_lock(&window->lock); uart_send(COM1, character); if (unlikely(character == '\n')) { __textui_new_line(window, window->vline_operating); - spin_unlock_irqrestore(&window->lock, rflags); + // spin_unlock_irqrestore(&window->lock, rflags); + spin_unlock(&window->lock); return 0; } else if (character == '\t') // 输出制表符 @@ -265,7 +266,8 @@ int textui_putchar_window(struct textui_window_t *window, uint16_t character, ui __textui_putchar_window(window, character, FRcolor, BKcolor); } - spin_unlock_irqrestore(&window->lock, rflags); + // spin_unlock_irqrestore(&window->lock, rflags); + spin_unlock(&window->lock); return 0; } diff --git a/kernel/mm/mm.c b/kernel/mm/mm.c index 77088409..689b3c37 100644 --- a/kernel/mm/mm.c +++ b/kernel/mm/mm.c @@ -60,7 +60,7 @@ void mm_init() for (int i = 0; i < count; ++i) { io_mfence(); - //可用的内存 + // 可用的内存 if (mb2_mem_info->type == 1) mm_Total_Memory += mb2_mem_info->len; @@ -332,7 +332,7 @@ struct Page *alloc_pages(unsigned int zone_select, int num, ul flags) *(memory_management_struct.bmp + ((x->addr_phys >> PAGE_2M_SHIFT) >> 6)) |= (1UL << (x->addr_phys >> PAGE_2M_SHIFT) % 64); ++(z->count_pages_using); --(z->count_pages_free); - x->attr = attr; + page_init(x, attr); } // 成功分配了页面,返回第一个页面的指针 // kwarn("start page num=%d\n", start_page_num); @@ -589,7 +589,7 @@ uint64_t mm_do_brk(uint64_t old_brk_end_addr, int64_t offset) { for (uint64_t i = old_brk_end_addr; i < end_addr; i += PAGE_2M_SIZE) { - struct vm_area_struct * vma=NULL; + struct vm_area_struct *vma = NULL; mm_create_vma(current_pcb->mm, i, PAGE_2M_SIZE, VM_USER | VM_ACCESS_FLAGS, NULL, &vma); mm_map_vma(vma, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys); } diff --git a/kernel/mm/mmap.c b/kernel/mm/mmap.c index 98508ac7..db33f9f5 100644 --- a/kernel/mm/mmap.c +++ b/kernel/mm/mmap.c @@ -353,13 +353,10 @@ int mm_map_vma(struct vm_area_struct *vma, uint64_t paddr) struct Page *pg = Phy_to_2M_Page(paddr); if (unlikely(pg->anon_vma == NULL)) // 若页面不存在anon_vma,则为页面创建anon_vma { - uint64_t rflags; - // todo: 查明为什么在mm_init中,spin init之后,pg会变为0 - spin_init(&pg->op_lock); - spin_lock_irqsave(&pg->op_lock, rflags); + spin_lock(&pg->op_lock); if (unlikely(pg->anon_vma == NULL)) __anon_vma_create_alloc(pg, false); - spin_unlock_irqrestore(&pg->op_lock, rflags); + spin_unlock(&pg->op_lock); } barrier(); // 将anon vma与vma进行绑定 diff --git a/kernel/mm/vma.c b/kernel/mm/vma.c index 40789b60..681988d4 100644 --- a/kernel/mm/vma.c +++ b/kernel/mm/vma.c @@ -179,9 +179,9 @@ struct anon_vma_t *__anon_vma_create_alloc(struct Page *page, bool lock_page) if (lock_page == true) // 需要加锁 { uint64_t rflags; - spin_lock_irqsave(&page->op_lock, rflags); + spin_lock(&page->op_lock); page->anon_vma = anon_vma; - spin_unlock_irqrestore(&page->op_lock, rflags); + spin_unlock(&page->op_lock); } else page->anon_vma = anon_vma; diff --git a/kernel/smp/smp.c b/kernel/smp/smp.c index e9068730..a4953e29 100644 --- a/kernel/smp/smp.c +++ b/kernel/smp/smp.c @@ -140,6 +140,7 @@ void smp_ap_start() // ============ 为ap处理器初始化IDLE进程 ============= memset(current_pcb, 0, sizeof(struct process_control_block)); + barrier(); current_pcb->state = PROC_RUNNING; current_pcb->flags = PF_KTHREAD; current_pcb->mm = &initial_mm; @@ -157,11 +158,12 @@ void smp_ap_start() current_pcb->cpu_id = current_starting_cpu; initial_proc[proc_current_cpu_id] = current_pcb; - + barrier(); load_TR(10 + current_starting_cpu * 2); current_pcb->preempt_count = 0; // kdebug("IDT_addr = %#018lx", phys_2_virt(IDT_Table)); + io_mfence(); spin_unlock(&multi_core_starting_lock); preempt_disable(); // 由于ap处理器的pcb与bsp的不同,因此ap处理器放锁时,需要手动恢复preempt count io_mfence();