]> Zhao Yanbai Git Server - kernel.git/commitdiff
避免嵌套情况下底半处理丢失的问题
authoracevest <zhaoyanbai@126.com>
Sun, 28 May 2023 14:33:35 +0000 (22:33 +0800)
committeracevest <zhaoyanbai@126.com>
Sun, 28 May 2023 14:33:35 +0000 (22:33 +0800)
drivers/ide.c
include/irq.h
kernel/clock.c
kernel/irq.c
kernel/setup.c
kernel/system.c
scripts/link.ld

index 196952d39eb519c084409dff07a84094e1b1baf0..30fa230279af8b72ca2de0fb00464bf42fa66eb0 100644 (file)
@@ -576,7 +576,7 @@ void ide_init() {
     void ide_ata_init();
     ide_ata_init();
 
-    request_irq(0x0E, ide_irq_handler, NULL, "hard", "IDE");
+    request_irq(0x0E, ide_irq_handler, "hard", "IDE");
 
     // init_pci_controller(0x0106);
     init_pci_controller(0x0101);
index 59b44712241819247c08e5479bd9e46ce47931a7..034ca1a9c941863b310a304f150b78198ad06179 100644 (file)
@@ -32,7 +32,6 @@ 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;
@@ -45,13 +44,19 @@ typedef struct irq_desc {
     unsigned int depth;
 } irq_desc_t;
 
+typedef struct irq_bh_action {
+    void (*handler)();
+    struct irq_bh_action *next;
+} irq_bh_action_t;
+
 extern irq_chip_t i8259_chip;
 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 *), void (*bh_handler)(), const char *devname,
-                void *dev_id);
+                void (*handler)(unsigned int, pt_regs_t *, void *), const char *devname, void *dev_id);
+
+void add_irq_bh_handler(void (*handler)());
 
 int open_irq(unsigned int irq);
 int close_irq(unsigned int irq);
index 731cf603ef74a31ff7ef7f977892a07e320553b5..7b58c5eb4d331dc21b9f3274208cdcf18b730ad6 100644 (file)
@@ -23,6 +23,7 @@ unsigned int sys_clock() { return jiffies; }
 void debug_print_all_tasks();
 
 void dump_irq_nr_stack();
+void clk_bh_handler();
 void clk_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) {
     // if (jiffies % 100 == 0) {
     printl(MPL_CLOCK, "clock irq: %d", jiffies);
@@ -42,6 +43,8 @@ void clk_handler(unsigned int irq, pt_regs_t *regs, void *dev_id) {
     }
 
     assert(current->ticks <= TASK_MAX_PRIORITY);  // 防止ticks被减到0后再减溢出
+
+    add_irq_bh_handler(clk_bh_handler);
 }
 
 // 开中断执行这个函数
index b7a093c089b29ad5a0d5d332651a2e1dfd1dda11..155734367e8932191ced833515eebf2f4ae0afb2 100644 (file)
 #include <task.h>
 
 irq_desc_t irq_desc[NR_IRQS];
-
-int enable_no_irq_chip(unsigned int irq) { return 0; }
-int disable_no_irq_chip(unsigned int irq) { return 0; }
-
-irq_chip_t no_irq_chip = {.name = "none", .enable = enable_no_irq_chip, .disable = disable_no_irq_chip};
-
-irq_desc_t no_irq_desc = {.chip = &no_irq_chip, .action = NULL, .status = 0, .depth = 0};
+irq_bh_action_t *irq_bh_actions = NULL;
+irq_bh_action_t *irq_bh_actions_end = NULL;
 
 #if 0
 unsigned int irq_nr_stack[64] = {1, 2, 3, 4};
@@ -79,6 +74,8 @@ void dump_irq_nr_stack() {
 }
 #endif
 
+void irq_bh_handler();
+
 __attribute__((regparm(1))) void irq_handler(pt_regs_t *regs) {
     unsigned int irq = regs->irq;
     if (irq >= NR_IRQS) {
@@ -127,13 +124,7 @@ __attribute__((regparm(1))) void irq_handler(pt_regs_t *regs) {
     {
         enable_irq();
 
-        action = p->action;
-        while (action) {
-            if (action->bh_handler != NULL) {
-                action->bh_handler();
-            }
-            action = action->next;
-        }
+        irq_bh_handler();
 
         disable_irq();
     }
@@ -152,8 +143,45 @@ __attribute__((regparm(1))) void irq_handler(pt_regs_t *regs) {
     schedule();
 }
 
-int request_irq(unsigned int irq, void (*handler)(unsigned int, pt_regs_t *, void *), void (*bh_handler)(),
-                const char *devname, void *dev_id) {
+extern uint32_t jiffies;
+void irq_bh_handler() {
+    uint32_t end = jiffies + 2;
+    while (true) {
+        irq_bh_action_t *action = NULL;
+
+        disable_irq();
+
+        action = irq_bh_actions;
+        irq_bh_actions = NULL;
+        irq_bh_actions_end = NULL;
+
+        enable_irq();
+
+        if (action == NULL) {
+            break;
+        }
+
+        while (action != NULL) {
+            action->handler();
+            irq_bh_action_t *p = action;
+            action = action->next;
+            kfree(p);
+        }
+
+        if (jiffies >= end) {
+            break;
+        }
+
+        // 这里可能存在有部分没处理完
+    }
+
+    // 这之后也可能存在再次被中断加入下半部处理请求
+    // 但这些都不会丢失
+    // 而是会延迟到这次中断返回后下一次的中断的下半部分处理逻辑
+}
+
+int request_irq(unsigned int irq, void (*handler)(unsigned int, pt_regs_t *, void *), const char *devname,
+                void *dev_id) {
     irq_action_t *p;
 
     if (irq >= NR_IRQS) {
@@ -180,7 +208,6 @@ 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;
@@ -191,6 +218,31 @@ int request_irq(unsigned int irq, void (*handler)(unsigned int, pt_regs_t *, voi
     return 0;
 }
 
+void add_irq_bh_handler(void (*handler)()) {
+    // 只能在中断处理函数中调用
+    assert(irq_disabled());
+
+    irq_bh_action_t *p;
+    p = (irq_bh_action_t *)kmalloc(sizeof(irq_bh_action_t), 0);
+    assert(p != NULL);
+
+    p->handler = handler;
+
+    if (irq_bh_actions_end == NULL) {
+        assert(irq_bh_actions == NULL);
+        irq_bh_actions = p;
+        irq_bh_actions_end = p;
+
+    } else {
+        assert(irq_bh_actions != NULL);
+        irq_bh_actions_end->next = p;
+        irq_bh_actions_end = p;
+    }
+    p->next = NULL;
+
+    irq_bh_actions = p;
+}
+
 int open_irq(unsigned int irq) { return irq_desc[irq].chip->enable(irq); }
 
 int close_irq(unsigned int irq) { return irq_desc[irq].chip->disable(irq); }
@@ -206,4 +258,10 @@ bool irq_enabled() {
     return false;
 }
 
-bool irq_disabled() { return !irq_enabled(); }
\ No newline at end of file
+bool irq_disabled() { return !irq_enabled(); }
+
+int enable_no_irq_chip(unsigned int irq) { return 0; }
+int disable_no_irq_chip(unsigned int irq) { return 0; }
+
+irq_chip_t no_irq_chip = {.name = "none", .enable = enable_no_irq_chip, .disable = disable_no_irq_chip};
+irq_desc_t no_irq_desc = {.chip = &no_irq_chip, .action = NULL, .status = 0, .depth = 0};
index 5af36189b4aee32873796729ccfe764a225d3efc..cd8802bc82cbf8fc239e88e61144dadfb88c243c 100644 (file)
@@ -65,7 +65,7 @@ void setup_kernel() {
     setup_gate();
     set_tss();
 
-    setup_i8253(20);
+    setup_i8253(100);
 
     setup_sysc();
 
index a0ff96af9894df8e704de714c763b21256463501..53b72dde2b213bf399882289273e6e975b3acb3e 100644 (file)
@@ -109,12 +109,12 @@ void setup_irqs() {
     void clk_handler(unsigned int irq, pt_regs_t *regs, void *dev_id);
     void clk_bh_handler();
 
-    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(0x00, clk_handler, "Intel 8254", "Clock Chip");
+    request_irq(0x01, kbd_handler, "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, NULL, "default", "default");
+            request_irq(i, default_irq_handler, "default", "default");
         }
     }
 
index 3a38a78364f89d1c5c73084d2df3685c3682700e..7d6272c87109cb574d0575fa427e610dba0e98ce 100644 (file)
@@ -29,7 +29,7 @@ SECTIONS
         boot/multiboot.S.o(.text)
         *(.multiboot2_header)
         *(.text)
-       *(.ring3.text);
+        *(.ring3.text);
         *(.sysexit) /* last */
     }
     etext = .;