瀏覽代碼

bugfix: 修复多核启动时,自旋锁持有计数错误的问题

fslongjin 2 年之前
父節點
當前提交
9322d8ab20
共有 3 個文件被更改,包括 10 次插入8 次删除
  1. 2 2
      kernel/process/preempt.h
  2. 4 4
      kernel/process/process.h
  3. 4 2
      kernel/smp/smp.c

+ 2 - 2
kernel/process/preempt.h

@@ -9,7 +9,7 @@
 #define preempt_disable()   \
 do  \
 {   \
-    --(current_pcb->preempt_count);\
+    ++(current_pcb->preempt_count);\
 } while (0)
 
 /**
@@ -19,5 +19,5 @@ do  \
 #define preempt_enable()   \
 do  \
 {   \
-    ++(current_pcb->preempt_count);\
+    --(current_pcb->preempt_count);\
 }while(0)

+ 4 - 4
kernel/process/process.h

@@ -152,15 +152,15 @@ union proc_union
 	{                                     \
 		.state = PROC_UNINTERRUPTIBLE,    \
 		.flags = PF_KTHREAD,              \
+		.preempt_count = 0,               \
+		.signal = 0,                      \
+		.cpu_id = 0,                      \
 		.mm = &initial_mm,                \
 		.thread = &initial_thread,        \
 		.addr_limit = 0xffffffffffffffff, \
 		.pid = 0,                         \
-		.virtual_runtime = 0,             \
-		.signal = 0,                      \
 		.priority = 2,                    \
-		.preempt_count = 0,               \
-		.cpu_id = 0,                      \
+		.virtual_runtime = 0,             \
 		.fds = {0},                       \
 		.next_pcb = &proc,                \
 		.parent_pcb = &proc,              \

+ 4 - 2
kernel/smp/smp.c

@@ -55,6 +55,7 @@ void smp_init()
             continue;
 
         spin_lock(&multi_core_starting_lock);
+        preempt_enable();   // 由于ap处理器的pcb与bsp的不同,因此ap处理器放锁时,bsp的自旋锁持有计数不会发生改变,需要手动恢复preempt count
         current_starting_cpu = proc_local_apic_structs[i]->local_apic_id;
 
         kdebug("[core %d] acpi processor UID=%d, APIC ID=%d, flags=%#010lx", i, proc_local_apic_structs[i]->ACPI_Processor_UID, proc_local_apic_structs[i]->local_apic_id, proc_local_apic_structs[i]->flags);
@@ -95,7 +96,7 @@ void smp_init()
     {
         *(ul *)(phys_2_virt(global_CR3) + i) = 0UL;
     }
-
+    kdebug("init proc's preempt_count=%ld", current_pcb->preempt_count);
     kinfo("Successfully cleaned page table remapping!\n");
 }
 
@@ -147,10 +148,11 @@ void smp_ap_start()
     initial_proc[proc_current_cpu_id] = current_pcb;
 
     load_TR(10 + current_starting_cpu * 2);
+    current_pcb->preempt_count = 0;
 
     // kdebug("IDT_addr = %#018lx", phys_2_virt(IDT_Table));
     spin_unlock(&multi_core_starting_lock);
-    current_pcb->preempt_count = 0;
+    preempt_disable();// 由于ap处理器的pcb与bsp的不同,因此ap处理器放锁时,需要手动恢复preempt count
     sti();
 
     while (1)