]> Zhao Yanbai Git Server - kernel.git/commitdiff
中断处理不再允许嵌套执行;将不重要的中断处理逻辑归类为下半部分处理逻辑,并允许开中断执行,但在该部分逻辑在被中断打断的情况下也只允许执行一次.
authoracevest <zhaoyanbai@126.com>
Fri, 26 May 2023 16:52:37 +0000 (00:52 +0800)
committeracevest <zhaoyanbai@126.com>
Sat, 27 May 2023 02:21:57 +0000 (10:21 +0800)
15 files changed:
drivers/ide.c
include/irq.h
include/printk.h
include/sched.h
include/system.h
include/task.h
kernel/clock.c
kernel/fork.c
kernel/interrupts.S
kernel/irq.c
kernel/sched.c
kernel/syscall.S
kernel/system.c
kernel/task_init.c
kernel/wait.c

index 30fa230279af8b72ca2de0fb00464bf42fa66eb0..196952d39eb519c084409dff07a84094e1b1baf0 100644 (file)
@@ -576,7 +576,7 @@ void ide_init() {
     void ide_ata_init();
     ide_ata_init();
 
-    request_irq(0x0E, ide_irq_handler, "hard", "IDE");
+    request_irq(0x0E, ide_irq_handler, NULL, "hard", "IDE");
 
     // init_pci_controller(0x0106);
     init_pci_controller(0x0101);
index fc704c71e9995ba57b2a574770d89da448f07fe5..59b44712241819247c08e5479bd9e46ce47931a7 100644 (file)
@@ -32,6 +32,7 @@ typedef struct irq_chip {
 typedef struct irqaction {
     // void (*handler)(pt_regs_t * regs, unsigned int irq);
     void (*handler)(unsigned int irq, pt_regs_t *regs, void *dev_id);
+    void (*bh_handler)();
     const char *dev_name;
     void *dev_id;
     struct irqaction *next;
@@ -49,7 +50,8 @@ extern irq_desc_t irq_desc[];
 extern irq_desc_t no_irq_desc;
 int request_irq(unsigned int irq,
                 // void (*handler)(pt_regs_t *, unsigned int),
-                void (*handler)(unsigned int, pt_regs_t *, void *), const char *devname, void *dev_id);
+                void (*handler)(unsigned int, pt_regs_t *, void *), void (*bh_handler)(), const char *devname,
+                void *dev_id);
 
 int open_irq(unsigned int irq);
 int close_irq(unsigned int irq);
@@ -60,6 +62,7 @@ int close_irq(unsigned int irq);
 #define irq_save(x) __asm__ __volatile__("pushfl; popl %0; cli" : "=g"(x)::"memory")
 
 bool irq_enabled();
+bool irq_disabled();
 
 #define irq_restore(x)                                                     \
     do {                                                                   \
index 52747b29372c9c3a71f49c50a99681b5fb74118b..f142ebee00de7ed19507050e54317e908c382744 100644 (file)
@@ -33,7 +33,7 @@ enum {
     MPL_IDE,
     MPL_IDE_INTR,
     MPL_CURRENT,
-    MPL_FUCK,
+    MPL_TEST0,
     MPL_TEST,
     MPL_X,
     MPL_DEBUG,
index 73883e3fdadc9d2b409baf1cdf3cba5fe0e8da96..ed00ce6dde3f99f2c511245fd665088b63e011d1 100644 (file)
@@ -32,6 +32,7 @@ extern task_union root_task;
 extern void load_cr3(task_union *tsk);
 
 extern list_head_t all_tasks;
+extern list_head_t delay_tasks;
 
 #define set_current_state(st)  \
     do {                       \
index e54d77d7ce4827daa3a970883960873d70b74be8..a40cc795bead6c1ab01e3e985f5acaa16af1a847 100644 (file)
@@ -270,7 +270,7 @@ void init_task_entry();
 void disk_task_entry();
 void user_task_entry();
 
-extern volatile int irq_reenter;
+extern volatile int reenter;
 #endif
 
 #endif  //_SYSTEM_H
index 5e5c2c0aeed9be1a0c7772b82ba7477ad29d9c59..d246066aa29f4ca024a83bc3e7c85764e0e862b5 100644 (file)
@@ -53,6 +53,8 @@ typedef union task_union {
         uint32_t priority;
         uint64_t jiffies;
 
+        volatile int need_resched;
+
         pid_t pid;
         pid_t ppid;
         volatile unsigned int state;
index c856101d370e33beccd79670b27c6decd8ac9674..d5aabedd6f8ca0b52054d7edc030e3600d548209 100644 (file)
@@ -27,24 +27,38 @@ void clk_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) {
         printl(MPL_CLOCK, "clock irq: %d", jiffies);
     }
 
+#if 0
     unsigned long iflags;
     irq_save(iflags);
-
+#endif
     jiffies++;
 
     current->jiffies = jiffies;
-    // 若clk_handler嵌套在其它中断函数中执行
-    // 那么这个变量减到0时,再退出中clk_handler并不会引起调度
-    //
 
-    current->ticks--;
+    // 中断目前虽然不能嵌套,但依然可以打断前一个中断的下半部分处理
+    // 若前一个时钟中断将这个值减到0
+    // 同时其下半部分处理时间过长,直到这个时钟中断还没处理完
+    // 那么这个时钟中断是完全可以打断它,且在这里把这个ticks从0减到负数
+    // 而这个是uint32_t型,因此会溢出成0xFFFFFFFF
+    volatile uint32_t ticks;
+
+    ticks = current->ticks;
+    if (current->ticks > 0) {
+        current->ticks--;
+    }
+    ticks = current->ticks;
+
+#if 0
     if (current->ticks > TASK_MAX_PRIORITY) {
         printl(MPL_X, "current %08x ticks %u", current, current->ticks);
         printk("DIE: ");
         dump_irq_nr_stack();
     }
+#endif
+
     assert(current->ticks <= TASK_MAX_PRIORITY);  // 防止ticks被减到0后再减溢出
 
+#if 0
     task_union *p = 0;
     list_head_t *t = 0;
     list_head_t *pos = 0;
@@ -55,11 +69,41 @@ void clk_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) {
             p->state = TASK_READY;
         }
     }
+#endif
 
+#if 0
     debug_print_all_tasks();
     debug_print_all_tasks();
     debug_print_all_tasks();
     debug_print_all_tasks();
+#endif
 
+#if 0
     irq_restore(iflags);
+#endif
 }
+
+// 开中断执行这个函数
+const char *task_state(unsigned int state);
+void clk_bh_handler() {
+    unsigned long iflags;
+    irq_save(iflags);
+    task_union *p = 0;
+    list_head_t *t = 0;
+    list_head_t *pos = 0;
+    list_for_each_safe(pos, t, &delay_tasks) {
+        p = list_entry(pos, task_union, pend);
+        // printk("%s state: %s\n", p->name, task_state(p->state));
+        assert(p->state == TASK_WAIT);
+        assert(p->delay_jiffies != 0);
+        if (jiffies > p->delay_jiffies) {
+            list_del(&p->pend);
+            p->delay_jiffies = 0;
+            p->state = TASK_READY;
+        }
+    }
+
+    // 此处调用这个还是有问题的
+    debug_print_all_tasks();
+    irq_restore(iflags);
+}
\ No newline at end of file
index 1543c79037981f52ea05e629b3d211ab5948175c..e49942a3cfe5586878bd4a0c09f77f35396a34c4 100644 (file)
@@ -88,6 +88,7 @@ int do_fork(pt_regs_t *regs, unsigned long flags) {
     tsk->priority = current->priority;
     tsk->ticks = tsk->priority;
     tsk->turn = 0;  //
+    tsk->need_resched = 0;
     tsk->sched_cnt = 0;
     tsk->sched_keep_cnt = 0;
     assert(tsk->magic == TASK_MAGIC);
index 0af4f703080d698135a53cfa6b80ccf27ca67733..f480ff3a9db7aa5b7a1f5487ee2aaaddae4a4e52 100644 (file)
@@ -52,8 +52,6 @@ DEF_IRQ(0,F)
 
 .global _irq_handler
 .extern irq_handler
-.extern schedule
-.extern irq_reenter
 _irq_handler:
     SAVE_REGS
 
@@ -69,18 +67,7 @@ _irq_handler:
 
     movl    %esp, %eax
     call    irq_handler
-
-    cmpl    $0, (irq_reenter)
-    jnz     restore_regs
-
-
-    call    schedule
-
-    RESTORE_REGS
-    addl    $4, %esp
-    iret
-
-restore_regs:
+    
     RESTORE_REGS
     addl    $4, %esp
-    iret
+    iret
\ No newline at end of file
index 9b4d6aeb08d97dc07c0091695272aa96970c8f15..b5e683403860d7bb93e71db1b46a98ff25b473e4 100644 (file)
@@ -52,10 +52,10 @@ int vsprintf(char *buf, const char *fmt, char *args);
 void dump_irq_nr_stack() {
     if (irq_nr_stack_pos == 0) {
         printl(MPL_TEST, "irq nr stack empty");
-        return 0;
+        return;
     }
 
-    printl(MPL_FUCK, "irq nr stack pos %u", irq_nr_stack_pos);
+    printl(MPL_TEST0, "irq nr stack pos %u", irq_nr_stack_pos);
 
     char buf[128];
 
@@ -79,68 +79,102 @@ void dump_irq_nr_stack() {
 __attribute__((regparm(1))) void irq_handler(pt_regs_t *regs) {
     unsigned int irq = regs->irq;
     if (irq >= NR_IRQS) {
-        printk("invalid irq %d\n", irq);
-        return;
+        panic("invalid irq %d\n", irq);
     }
 
     irq_desc_t *p = irq_desc + irq;
     irq_action_t *action = p->action;
 
+    assert(irq_disabled());
+    reenter++;
+
     // 屏蔽当前中断
     p->chip->disable(irq);
 
     // 发送EOI
     p->chip->ack(irq);
 
-    if (irq_reenter == 0) {
-        // 可以切换到中断栈
-    }
-
-    irq_reenter++;
-
     assert(current->magic == TASK_MAGIC);
 
+#if 0
     push_irq_nr_stack(irq);
 
     // if (irq_nr_stack_pos >= 2) {
     dump_irq_nr_stack();
     //     panic("sdfasd");
     // }
+#endif
+
+#if 0
     // 开中断执行中断处理函数
     enable_irq();
+#endif
+
+#if 1
     unsigned long esp;
     asm("movl %%esp, %%eax" : "=a"(esp));
-    printl(MPL_CURRENT, "current %08x cr3 %08x reenter %d esp %08x", current, current->cr3, irq_reenter, esp);
-    printk("2: %d r %d t %d\n", irq, irq_reenter, current->ticks);
+    printl(MPL_CURRENT, "current %08x cr3 %08x reenter %d esp %08x %u", current, current->cr3, reenter, esp,
+           current->ticks);
+#endif
+
     while (action && action->handler) {
-        if (irq == 14) {
-            printk("a: %d r %d t %d \n", irq, irq_reenter, current->ticks);
-        }
         action->handler(irq, regs, action->dev_id);
-        if (irq == 14) {
-            printk("b: %d r %d t %d \n", irq, irq_reenter, current->ticks);
-        }
         action = action->next;
     }
 
+#if 0
     // 关全局中断
-    if (irq == 14) {
-        printk("c: %d r %d t %d \n", irq, irq_reenter, current->ticks);
-    }
     disable_irq();
+#endif
+
+#if 0
     pop_irq_nr_stack();
-    irq_reenter--;
-    if (irq == 14) {
-        printk("d: %d r %d t %d \n", irq, irq_reenter, current->ticks);
-    }
+#endif
+
     // 解除屏蔽当前中断
     p->chip->enable(irq);
 
-    printk("x: %d r %d t %d \n", irq, irq_reenter, current->ticks);
+    // 代表当前中断程序打断了前一个中断程序的“开中断处理的底半部分逻辑”
+    // 即前一个中断处理尚未完全完成
+    assert(irq_disabled());
+    if (reenter != 0) {
+        reenter--;
+        return;
+    }
+    // --以上逻辑CPU处于中断禁止状态--------------------------
+
+    // 此处执行中断函数的下半部分逻辑,开中断执行
+    {
+        enable_irq();
+
+        action = p->action;
+        while (action) {
+            if (action->bh_handler != NULL) {
+                action->bh_handler();
+            }
+            action = action->next;
+        }
+
+        disable_irq();
+    }
+
+    // --以下逻辑CPU处于中断禁止状态--------------------------
+    assert(irq_disabled());
+    assert(reenter == 0);
+    reenter--;
+    assert(reenter == -1);
+
+    // 考察如果不需要调度程序,直接退出
+    if (current->ticks != 0) {
+        return;
+    }
+
+    // 如果需要调度程序
+    schedule();
 }
 
-int request_irq(unsigned int irq, void (*handler)(unsigned int, pt_regs_t *, void *), const char *devname,
-                void *dev_id) {
+int request_irq(unsigned int irq, void (*handler)(unsigned int, pt_regs_t *, void *), void (*bh_handler)(),
+                const char *devname, void *dev_id) {
     irq_action_t *p;
 
     if (irq >= NR_IRQS) {
@@ -167,6 +201,7 @@ int request_irq(unsigned int irq, void (*handler)(unsigned int, pt_regs_t *, voi
     p->dev_name = devname;
     p->dev_id = dev_id;
     p->handler = handler;
+    p->bh_handler = bh_handler;
     p->next = NULL;
     if (irq_desc[irq].action != NULL) {
         p->next = irq_desc[irq].action;
@@ -190,4 +225,6 @@ bool irq_enabled() {
     }
 
     return false;
-}
\ No newline at end of file
+}
+
+bool irq_disabled() { return !irq_enabled(); }
\ No newline at end of file
index 98b9044c85ecbdfdaabc554cecea9efad8d64015..82c272dcf0b581e19fbf1cc5be36c8784952f3af 100644 (file)
@@ -59,6 +59,7 @@ void init_root_task() {
     root_task.priority = 7;
     root_task.ticks = root_task.priority;
     root_task.turn = 0;
+    root_task.need_resched = 0;
     root_task.sched_cnt = 0;
     root_task.sched_keep_cnt = 0;
     root_task.magic = TASK_MAGIC;
@@ -150,7 +151,7 @@ task_union *find_task(pid_t pid) {
     return p;
 }
 
-static const char *task_state(unsigned int state) {
+const char *task_state(unsigned int state) {
     static const char s[][16] = {
         "  ERROR", "RUNNING", "  READY", "   WAIT", "   INIT", "   EXIT",
     };
@@ -183,7 +184,6 @@ void schedule() {
     task_union *sel = 0;
     task_union *p = 0;
     list_head_t *pos = 0, *t = 0;
-    printk("*");
 
     printl(MPL_X, "disk req %u consumed %u irq %u", disk_request_cnt, disk_handled_cnt, disk_inter_cnt);
 
@@ -193,26 +193,25 @@ void schedule() {
     unsigned long iflags;
     irq_save(iflags);
 
-    if (TASK_RUNNING == current->state) {
-        if (0 == current->ticks) {
-            current->turn++;
-            current->ticks = current->priority;
-            current->state = TASK_READY;
-        } else {
-            irq_restore(iflags);
-            return;
-        }
+    if (0 == current->ticks) {
+        current->turn++;
+        current->ticks = current->priority;
+        current->state = TASK_READY;
     }
 
+    // printk("-----\n");
     list_for_each_safe(pos, t, &all_tasks) {
         p = list_entry(pos, task_union, list);
 
-        assert(p->state != TASK_RUNNING);
+        // printk("%s state: %s ticks %u\n", current->name, task_state(current->state), current->ticks);
+        // printk("%s state: %s\n", p->name, task_state(p->state));
 
         if (p == &root_task) {
             continue;
         }
 
+        assert(p->state != TASK_RUNNING);
+
         if (TASK_READY != p->state) {
             continue;
         }
index 6526d4580c88a53224ea61f845e5a0fd07a2ec97..d9227194ccc2c0972f9aa495567af6f3485af1fe 100644 (file)
 .global syscall_entry
 .global ret_from_fork_user
 .global ret_from_fork_krnl
+.extern reenter
 //.global syscall_exit
 
 syscall_entry:
 #if FIX_SYSENTER_ESP_MODE
     movl    (%esp),%esp 
 #endif
-
+    
     // sysenter have cleared IF, and sysexit will not set IF.
     sti
 
index 56183d92cea656f259aa86a81db2db992d455617..a0ff96af9894df8e704de714c763b21256463501 100644 (file)
@@ -107,13 +107,14 @@ void setup_irqs() {
 
     void kbd_handler(unsigned int irq, pt_regs_t *regs, void *dev_id);
     void clk_handler(unsigned int irq, pt_regs_t *regs, void *dev_id);
+    void clk_bh_handler();
 
-    request_irq(0x00, clk_handler, "Intel 8254", "Clock Chip");
-    request_irq(0x01, kbd_handler, "Intel 8042", "PS/2 Keyboard");
+    request_irq(0x00, clk_handler, clk_bh_handler, "Intel 8254", "Clock Chip");
+    request_irq(0x01, kbd_handler, NULL, "Intel 8042", "PS/2 Keyboard");
     // request_irq(0x0E, default_ide_irq_handler, "hard", "IDE");
     for (int i = 0; i < 16; i++) {
         if (i != 0 && i != 1 && i != 10 && i != 14) {
-            request_irq(i, default_irq_handler, "default", "default");
+            request_irq(i, default_irq_handler, NULL, "default", "default");
         }
     }
 
@@ -192,4 +193,4 @@ Desc gdt[NGDT] __attribute__((__aligned__(8)));
 char gdtr[6] __attribute__((__aligned__(4)));
 char idtr[6] __attribute__((__aligned__(4)));
 
-volatile int irq_reenter = 0x00;
\ No newline at end of file
+volatile int reenter = -1;
\ No newline at end of file
index 3e5e9bd2014b6323d6e4a51d6a0c2a8aab4f0daf..fbc0c03d07d73ece224227910d8b0d5ed19981de 100644 (file)
@@ -19,7 +19,7 @@ void init_task_entry() {
     setup_under_irq();
 
     while (1) {
-        asm("hlt;");
+        asm("sti;hlt;");
         sysc_wait(2);
     }
 }
index acbc179cbec039b23e77406942cfb1bea804f54e..016792d09b7fd5c7610e17f22c894644a0e47c80 100644 (file)
@@ -130,7 +130,7 @@ int sysc_wait(unsigned long cnt) {
     irq_save(flags);
     current->state = TASK_WAIT;
     current->delay_jiffies = jiffies + cnt;
-
+    list_add(&current->pend, &delay_tasks);
     irq_restore(flags);
 
     schedule();