hc
2024-11-01 2f529f9b558ca1c1bd74be7437a84e4711743404
kernel/arch/x86/kernel/apic/io_apic.c
....@@ -78,7 +78,7 @@
7878 #define for_each_irq_pin(entry, head) \
7979 list_for_each_entry(entry, &head, list)
8080
81
-static DEFINE_RAW_SPINLOCK(ioapic_lock);
81
+static DEFINE_HARD_SPINLOCK(ioapic_lock);
8282 static DEFINE_MUTEX(ioapic_mutex);
8383 static unsigned int ioapic_dynirq_base;
8484 static int ioapic_initialized;
....@@ -1634,7 +1634,7 @@
16341634 return 1;
16351635
16361636 local_save_flags(flags);
1637
- local_irq_enable();
1637
+ local_irq_enable_full();
16381638
16391639 if (boot_cpu_has(X86_FEATURE_TSC))
16401640 delay_with_tsc();
....@@ -1642,6 +1642,8 @@
16421642 delay_without_tsc();
16431643
16441644 local_irq_restore(flags);
1645
+ if (raw_irqs_disabled_flags(flags))
1646
+ hard_local_irq_disable();
16451647
16461648 /*
16471649 * Expect a few ticks at least, to be sure some possible
....@@ -1722,14 +1724,56 @@
17221724 return false;
17231725 }
17241726
1727
+static inline void do_prepare_move(struct irq_data *data)
1728
+{
1729
+ if (!irqd_irq_masked(data))
1730
+ mask_ioapic_irq(data);
1731
+}
1732
+
1733
+#ifdef CONFIG_IRQ_PIPELINE
1734
+
1735
+static inline void ioapic_finish_move(struct irq_data *data, bool moveit);
1736
+
1737
+static void ioapic_deferred_irq_move(struct irq_work *work)
1738
+{
1739
+ struct irq_data *data;
1740
+ struct irq_desc *desc;
1741
+ unsigned long flags;
1742
+
1743
+ data = container_of(work, struct irq_data, move_work);
1744
+ desc = irq_data_to_desc(data);
1745
+ raw_spin_lock_irqsave(&desc->lock, flags);
1746
+ do_prepare_move(data);
1747
+ ioapic_finish_move(data, true);
1748
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
1749
+}
1750
+
1751
+static inline bool __ioapic_prepare_move(struct irq_data *data)
1752
+{
1753
+ init_irq_work(&data->move_work, ioapic_deferred_irq_move);
1754
+ irq_work_queue(&data->move_work);
1755
+
1756
+ return false; /* Postpone ioapic_finish_move(). */
1757
+}
1758
+
1759
+#else /* !CONFIG_IRQ_PIPELINE */
1760
+
1761
+static inline bool __ioapic_prepare_move(struct irq_data *data)
1762
+{
1763
+ do_prepare_move(data);
1764
+
1765
+ return true;
1766
+}
1767
+
1768
+#endif
1769
+
17251770 static inline bool ioapic_prepare_move(struct irq_data *data)
17261771 {
17271772 /* If we are moving the IRQ we need to mask it */
1728
- if (unlikely(irqd_is_setaffinity_pending(data))) {
1729
- if (!irqd_irq_masked(data))
1730
- mask_ioapic_irq(data);
1731
- return true;
1732
- }
1773
+ if (irqd_is_setaffinity_pending(data) &&
1774
+ !irqd_is_setaffinity_blocked(data))
1775
+ return __ioapic_prepare_move(data);
1776
+
17331777 return false;
17341778 }
17351779
....@@ -1828,7 +1872,7 @@
18281872 * We must acknowledge the irq before we move it or the acknowledge will
18291873 * not propagate properly.
18301874 */
1831
- ack_APIC_irq();
1875
+ __ack_APIC_irq();
18321876
18331877 /*
18341878 * Tail end of clearing remote IRR bit (either by delivering the EOI
....@@ -1949,7 +1993,8 @@
19491993 .irq_retrigger = irq_chip_retrigger_hierarchy,
19501994 .irq_get_irqchip_state = ioapic_irq_get_chip_state,
19511995 .flags = IRQCHIP_SKIP_SET_WAKE |
1952
- IRQCHIP_AFFINITY_PRE_STARTUP,
1996
+ IRQCHIP_AFFINITY_PRE_STARTUP |
1997
+ IRQCHIP_PIPELINE_SAFE,
19531998 };
19541999
19552000 static struct irq_chip ioapic_ir_chip __read_mostly = {
....@@ -1963,7 +2008,8 @@
19632008 .irq_retrigger = irq_chip_retrigger_hierarchy,
19642009 .irq_get_irqchip_state = ioapic_irq_get_chip_state,
19652010 .flags = IRQCHIP_SKIP_SET_WAKE |
1966
- IRQCHIP_AFFINITY_PRE_STARTUP,
2011
+ IRQCHIP_AFFINITY_PRE_STARTUP |
2012
+ IRQCHIP_PIPELINE_SAFE,
19672013 };
19682014
19692015 static inline void init_IO_APIC_traps(void)
....@@ -2010,7 +2056,7 @@
20102056
20112057 static void ack_lapic_irq(struct irq_data *data)
20122058 {
2013
- ack_APIC_irq();
2059
+ __ack_APIC_irq();
20142060 }
20152061
20162062 static struct irq_chip lapic_chip __read_mostly = {
....@@ -2018,6 +2064,7 @@
20182064 .irq_mask = mask_lapic_irq,
20192065 .irq_unmask = unmask_lapic_irq,
20202066 .irq_ack = ack_lapic_irq,
2067
+ .flags = IRQCHIP_PIPELINE_SAFE,
20212068 };
20222069
20232070 static void lapic_register_intr(int irq)
....@@ -2135,7 +2182,7 @@
21352182 if (!global_clock_event)
21362183 return;
21372184
2138
- local_irq_save(flags);
2185
+ local_irq_save_full(flags);
21392186
21402187 /*
21412188 * get/set the timer IRQ vector:
....@@ -2203,7 +2250,7 @@
22032250 goto out;
22042251 }
22052252 panic_if_irq_remap("timer doesn't work through Interrupt-remapped IO-APIC");
2206
- local_irq_disable();
2253
+ local_irq_disable_full();
22072254 clear_IO_APIC_pin(apic1, pin1);
22082255 if (!no_pin1)
22092256 apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: "
....@@ -2227,7 +2274,7 @@
22272274 /*
22282275 * Cleanup, just in case ...
22292276 */
2230
- local_irq_disable();
2277
+ local_irq_disable_full();
22312278 legacy_pic->mask(0);
22322279 clear_IO_APIC_pin(apic2, pin2);
22332280 apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
....@@ -2244,7 +2291,7 @@
22442291 apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
22452292 goto out;
22462293 }
2247
- local_irq_disable();
2294
+ local_irq_disable_full();
22482295 legacy_pic->mask(0);
22492296 apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | cfg->vector);
22502297 apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
....@@ -2263,7 +2310,7 @@
22632310 apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
22642311 goto out;
22652312 }
2266
- local_irq_disable();
2313
+ local_irq_disable_full();
22672314 apic_printk(APIC_QUIET, KERN_INFO "..... failed :(.\n");
22682315 if (apic_is_x2apic_enabled())
22692316 apic_printk(APIC_QUIET, KERN_INFO
....@@ -2272,7 +2319,7 @@
22722319 panic("IO-APIC + timer doesn't work! Boot with apic=debug and send a "
22732320 "report. Then try booting with the 'noapic' option.\n");
22742321 out:
2275
- local_irq_restore(flags);
2322
+ local_irq_restore_full(flags);
22762323 }
22772324
22782325 /*
....@@ -3018,13 +3065,13 @@
30183065 cfg = irqd_cfg(irq_data);
30193066 add_pin_to_irq_node(data, ioapic_alloc_attr_node(info), ioapic, pin);
30203067
3021
- local_irq_save(flags);
3068
+ local_irq_save_full(flags);
30223069 if (info->ioapic.entry)
30233070 mp_setup_entry(cfg, data, info->ioapic.entry);
30243071 mp_register_handler(virq, data->trigger);
30253072 if (virq < nr_legacy_irqs())
30263073 legacy_pic->mask(virq);
3027
- local_irq_restore(flags);
3074
+ local_irq_restore_full(flags);
30283075
30293076 apic_printk(APIC_VERBOSE, KERN_DEBUG
30303077 "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> IRQ %d Mode:%i Active:%i Dest:%d)\n",