diff options
| -rw-r--r-- | include/linux/irq.h | 49 | ||||
| -rw-r--r-- | kernel/irq/Makefile | 3 | ||||
| -rw-r--r-- | kernel/irq/migration.c | 52 |
3 files changed, 55 insertions, 49 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h index 6c5d4c898ccb..ee2a82a572f7 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
| @@ -114,53 +114,8 @@ static inline void set_native_irq_info(int irq, cpumask_t mask) | |||
| 114 | #if defined (CONFIG_GENERIC_PENDING_IRQ) || defined (CONFIG_IRQBALANCE) | 114 | #if defined (CONFIG_GENERIC_PENDING_IRQ) || defined (CONFIG_IRQBALANCE) |
| 115 | extern cpumask_t pending_irq_cpumask[NR_IRQS]; | 115 | extern cpumask_t pending_irq_cpumask[NR_IRQS]; |
| 116 | 116 | ||
| 117 | static inline void set_pending_irq(unsigned int irq, cpumask_t mask) | 117 | void set_pending_irq(unsigned int irq, cpumask_t mask); |
| 118 | { | 118 | void move_native_irq(int irq); |
| 119 | irq_desc_t *desc = irq_desc + irq; | ||
| 120 | unsigned long flags; | ||
| 121 | |||
| 122 | spin_lock_irqsave(&desc->lock, flags); | ||
| 123 | desc->move_irq = 1; | ||
| 124 | pending_irq_cpumask[irq] = mask; | ||
| 125 | spin_unlock_irqrestore(&desc->lock, flags); | ||
| 126 | } | ||
| 127 | |||
| 128 | static inline void | ||
| 129 | move_native_irq(int irq) | ||
| 130 | { | ||
| 131 | cpumask_t tmp; | ||
| 132 | irq_desc_t *desc = irq_descp(irq); | ||
| 133 | |||
| 134 | if (likely (!desc->move_irq)) | ||
| 135 | return; | ||
| 136 | |||
| 137 | desc->move_irq = 0; | ||
| 138 | |||
| 139 | if (likely(cpus_empty(pending_irq_cpumask[irq]))) | ||
| 140 | return; | ||
| 141 | |||
| 142 | if (!desc->handler->set_affinity) | ||
| 143 | return; | ||
| 144 | |||
| 145 | /* note - we hold the desc->lock */ | ||
| 146 | cpus_and(tmp, pending_irq_cpumask[irq], cpu_online_map); | ||
| 147 | |||
| 148 | /* | ||
| 149 | * If there was a valid mask to work with, please | ||
| 150 | * do the disable, re-program, enable sequence. | ||
| 151 | * This is *not* particularly important for level triggered | ||
| 152 | * but in a edge trigger case, we might be setting rte | ||
| 153 | * when an active trigger is comming in. This could | ||
| 154 | * cause some ioapics to mal-function. | ||
| 155 | * Being paranoid i guess! | ||
| 156 | */ | ||
| 157 | if (unlikely(!cpus_empty(tmp))) { | ||
| 158 | desc->handler->disable(irq); | ||
| 159 | desc->handler->set_affinity(irq,tmp); | ||
| 160 | desc->handler->enable(irq); | ||
| 161 | } | ||
| 162 | cpus_clear(pending_irq_cpumask[irq]); | ||
| 163 | } | ||
| 164 | 119 | ||
| 165 | #ifdef CONFIG_PCI_MSI | 120 | #ifdef CONFIG_PCI_MSI |
| 166 | /* | 121 | /* |
diff --git a/kernel/irq/Makefile b/kernel/irq/Makefile index 49378738ff5e..2b33f852be3e 100644 --- a/kernel/irq/Makefile +++ b/kernel/irq/Makefile | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | 1 | ||
| 2 | obj-y := handle.o manage.o spurious.o | 2 | obj-y := handle.o manage.o spurious.o migration.o |
| 3 | obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o | 3 | obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o |
| 4 | obj-$(CONFIG_PROC_FS) += proc.o | 4 | obj-$(CONFIG_PROC_FS) += proc.o |
| 5 | |||
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c new file mode 100644 index 000000000000..6bdd03c524c7 --- /dev/null +++ b/kernel/irq/migration.c | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | #include <linux/irq.h> | ||
| 2 | |||
| 3 | #if defined(CONFIG_GENERIC_PENDING_IRQ) | ||
| 4 | |||
| 5 | void set_pending_irq(unsigned int irq, cpumask_t mask) | ||
| 6 | { | ||
| 7 | irq_desc_t *desc = irq_desc + irq; | ||
| 8 | unsigned long flags; | ||
| 9 | |||
| 10 | spin_lock_irqsave(&desc->lock, flags); | ||
| 11 | desc->move_irq = 1; | ||
| 12 | pending_irq_cpumask[irq] = mask; | ||
| 13 | spin_unlock_irqrestore(&desc->lock, flags); | ||
| 14 | } | ||
| 15 | |||
| 16 | void move_native_irq(int irq) | ||
| 17 | { | ||
| 18 | cpumask_t tmp; | ||
| 19 | irq_desc_t *desc = irq_descp(irq); | ||
| 20 | |||
| 21 | if (likely (!desc->move_irq)) | ||
| 22 | return; | ||
| 23 | |||
| 24 | desc->move_irq = 0; | ||
| 25 | |||
| 26 | if (likely(cpus_empty(pending_irq_cpumask[irq]))) | ||
| 27 | return; | ||
| 28 | |||
| 29 | if (!desc->handler->set_affinity) | ||
| 30 | return; | ||
| 31 | |||
| 32 | /* note - we hold the desc->lock */ | ||
| 33 | cpus_and(tmp, pending_irq_cpumask[irq], cpu_online_map); | ||
| 34 | |||
| 35 | /* | ||
| 36 | * If there was a valid mask to work with, please | ||
| 37 | * do the disable, re-program, enable sequence. | ||
| 38 | * This is *not* particularly important for level triggered | ||
| 39 | * but in a edge trigger case, we might be setting rte | ||
| 40 | * when an active trigger is comming in. This could | ||
| 41 | * cause some ioapics to mal-function. | ||
| 42 | * Being paranoid i guess! | ||
| 43 | */ | ||
| 44 | if (unlikely(!cpus_empty(tmp))) { | ||
| 45 | desc->handler->disable(irq); | ||
| 46 | desc->handler->set_affinity(irq,tmp); | ||
| 47 | desc->handler->enable(irq); | ||
| 48 | } | ||
| 49 | cpus_clear(pending_irq_cpumask[irq]); | ||
| 50 | } | ||
| 51 | |||
| 52 | #endif | ||
