Browse Source

fix: 解决了page的锁未被初始化的bug

fslongjin 2 years ago
parent
commit
06af77bd79

+ 2 - 1
.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": ""

+ 1 - 1
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 

+ 1 - 1
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的起始地址

+ 1 - 1
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();
     }
 }

+ 3 - 2
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);
 }

+ 3 - 2
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;

+ 3 - 3
kernel/driver/usb/xhci/xhci.c

@@ -10,7 +10,6 @@
 #include <driver/interrupt/apic/apic.h>
 
 // 由于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
+}

+ 3 - 0
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;
 }

+ 6 - 4
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;
 }
 

+ 3 - 3
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);
         }

+ 2 - 5
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进行绑定

+ 2 - 2
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;

+ 3 - 1
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();