From 2f529f9b558ca1c1bd74be7437a84e4711743404 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Fri, 01 Nov 2024 02:11:33 +0000 Subject: [PATCH] add xenomai --- kernel/arch/x86/kernel/apic/io_apic.c | 85 +++++++++++++++++++++++++++++++++--------- 1 files changed, 66 insertions(+), 19 deletions(-) diff --git a/kernel/arch/x86/kernel/apic/io_apic.c b/kernel/arch/x86/kernel/apic/io_apic.c index 25b1d5c..47f9d4a 100644 --- a/kernel/arch/x86/kernel/apic/io_apic.c +++ b/kernel/arch/x86/kernel/apic/io_apic.c @@ -78,7 +78,7 @@ #define for_each_irq_pin(entry, head) \ list_for_each_entry(entry, &head, list) -static DEFINE_RAW_SPINLOCK(ioapic_lock); +static DEFINE_HARD_SPINLOCK(ioapic_lock); static DEFINE_MUTEX(ioapic_mutex); static unsigned int ioapic_dynirq_base; static int ioapic_initialized; @@ -1634,7 +1634,7 @@ return 1; local_save_flags(flags); - local_irq_enable(); + local_irq_enable_full(); if (boot_cpu_has(X86_FEATURE_TSC)) delay_with_tsc(); @@ -1642,6 +1642,8 @@ delay_without_tsc(); local_irq_restore(flags); + if (raw_irqs_disabled_flags(flags)) + hard_local_irq_disable(); /* * Expect a few ticks at least, to be sure some possible @@ -1722,14 +1724,56 @@ return false; } +static inline void do_prepare_move(struct irq_data *data) +{ + if (!irqd_irq_masked(data)) + mask_ioapic_irq(data); +} + +#ifdef CONFIG_IRQ_PIPELINE + +static inline void ioapic_finish_move(struct irq_data *data, bool moveit); + +static void ioapic_deferred_irq_move(struct irq_work *work) +{ + struct irq_data *data; + struct irq_desc *desc; + unsigned long flags; + + data = container_of(work, struct irq_data, move_work); + desc = irq_data_to_desc(data); + raw_spin_lock_irqsave(&desc->lock, flags); + do_prepare_move(data); + ioapic_finish_move(data, true); + raw_spin_unlock_irqrestore(&desc->lock, flags); +} + +static inline bool __ioapic_prepare_move(struct irq_data *data) +{ + init_irq_work(&data->move_work, ioapic_deferred_irq_move); + irq_work_queue(&data->move_work); + + return false; /* Postpone ioapic_finish_move(). */ +} + +#else /* !CONFIG_IRQ_PIPELINE */ + +static inline bool __ioapic_prepare_move(struct irq_data *data) +{ + do_prepare_move(data); + + return true; +} + +#endif + static inline bool ioapic_prepare_move(struct irq_data *data) { /* If we are moving the IRQ we need to mask it */ - if (unlikely(irqd_is_setaffinity_pending(data))) { - if (!irqd_irq_masked(data)) - mask_ioapic_irq(data); - return true; - } + if (irqd_is_setaffinity_pending(data) && + !irqd_is_setaffinity_blocked(data)) + return __ioapic_prepare_move(data); + return false; } @@ -1828,7 +1872,7 @@ * We must acknowledge the irq before we move it or the acknowledge will * not propagate properly. */ - ack_APIC_irq(); + __ack_APIC_irq(); /* * Tail end of clearing remote IRR bit (either by delivering the EOI @@ -1949,7 +1993,8 @@ .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_get_irqchip_state = ioapic_irq_get_chip_state, .flags = IRQCHIP_SKIP_SET_WAKE | - IRQCHIP_AFFINITY_PRE_STARTUP, + IRQCHIP_AFFINITY_PRE_STARTUP | + IRQCHIP_PIPELINE_SAFE, }; static struct irq_chip ioapic_ir_chip __read_mostly = { @@ -1963,7 +2008,8 @@ .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_get_irqchip_state = ioapic_irq_get_chip_state, .flags = IRQCHIP_SKIP_SET_WAKE | - IRQCHIP_AFFINITY_PRE_STARTUP, + IRQCHIP_AFFINITY_PRE_STARTUP | + IRQCHIP_PIPELINE_SAFE, }; static inline void init_IO_APIC_traps(void) @@ -2010,7 +2056,7 @@ static void ack_lapic_irq(struct irq_data *data) { - ack_APIC_irq(); + __ack_APIC_irq(); } static struct irq_chip lapic_chip __read_mostly = { @@ -2018,6 +2064,7 @@ .irq_mask = mask_lapic_irq, .irq_unmask = unmask_lapic_irq, .irq_ack = ack_lapic_irq, + .flags = IRQCHIP_PIPELINE_SAFE, }; static void lapic_register_intr(int irq) @@ -2135,7 +2182,7 @@ if (!global_clock_event) return; - local_irq_save(flags); + local_irq_save_full(flags); /* * get/set the timer IRQ vector: @@ -2203,7 +2250,7 @@ goto out; } panic_if_irq_remap("timer doesn't work through Interrupt-remapped IO-APIC"); - local_irq_disable(); + local_irq_disable_full(); clear_IO_APIC_pin(apic1, pin1); if (!no_pin1) apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: " @@ -2227,7 +2274,7 @@ /* * Cleanup, just in case ... */ - local_irq_disable(); + local_irq_disable_full(); legacy_pic->mask(0); clear_IO_APIC_pin(apic2, pin2); apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n"); @@ -2244,7 +2291,7 @@ apic_printk(APIC_QUIET, KERN_INFO "..... works.\n"); goto out; } - local_irq_disable(); + local_irq_disable_full(); legacy_pic->mask(0); apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector); apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n"); @@ -2263,7 +2310,7 @@ apic_printk(APIC_QUIET, KERN_INFO "..... works.\n"); goto out; } - local_irq_disable(); + local_irq_disable_full(); apic_printk(APIC_QUIET, KERN_INFO "..... failed :(.\n"); if (apic_is_x2apic_enabled()) apic_printk(APIC_QUIET, KERN_INFO @@ -2272,7 +2319,7 @@ panic("IO-APIC + timer doesn't work! Boot with apic=debug and send a " "report. Then try booting with the 'noapic' option.\n"); out: - local_irq_restore(flags); + local_irq_restore_full(flags); } /* @@ -3018,13 +3065,13 @@ cfg = irqd_cfg(irq_data); add_pin_to_irq_node(data, ioapic_alloc_attr_node(info), ioapic, pin); - local_irq_save(flags); + local_irq_save_full(flags); if (info->ioapic.entry) mp_setup_entry(cfg, data, info->ioapic.entry); mp_register_handler(virq, data->trigger); if (virq < nr_legacy_irqs()) legacy_pic->mask(virq); - local_irq_restore(flags); + local_irq_restore_full(flags); apic_printk(APIC_VERBOSE, KERN_DEBUG "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> IRQ %d Mode:%i Active:%i Dest:%d)\n", -- Gitblit v1.6.2