| .. | .. |
|---|
| 12 | 12 | #include <linux/interrupt.h> |
|---|
| 13 | 13 | #include <linux/ratelimit.h> |
|---|
| 14 | 14 | #include <linux/irq.h> |
|---|
| 15 | +#include <linux/sched/isolation.h> |
|---|
| 15 | 16 | |
|---|
| 16 | 17 | #include "internals.h" |
|---|
| 17 | 18 | |
|---|
| .. | .. |
|---|
| 41 | 42 | * If this happens then there was a missed IRQ fixup at some |
|---|
| 42 | 43 | * point. Warn about it and enforce fixup. |
|---|
| 43 | 44 | */ |
|---|
| 44 | | - pr_warn("Eff. affinity %*pbl of IRQ %u contains only offline CPUs after offlining CPU %u\n", |
|---|
| 45 | + pr_debug("Eff. affinity %*pbl of IRQ %u contains only offline CPUs after offlining CPU %u\n", |
|---|
| 45 | 46 | cpumask_pr_args(m), d->irq, cpu); |
|---|
| 46 | 47 | return true; |
|---|
| 47 | 48 | } |
|---|
| .. | .. |
|---|
| 165 | 166 | raw_spin_unlock(&desc->lock); |
|---|
| 166 | 167 | |
|---|
| 167 | 168 | if (affinity_broken) { |
|---|
| 168 | | - pr_warn_ratelimited("IRQ %u: no longer affine to CPU%u\n", |
|---|
| 169 | + pr_debug_ratelimited("IRQ %u: no longer affine to CPU%u\n", |
|---|
| 169 | 170 | irq, smp_processor_id()); |
|---|
| 170 | 171 | } |
|---|
| 171 | 172 | } |
|---|
| 173 | +} |
|---|
| 174 | + |
|---|
| 175 | +static bool hk_should_isolate(struct irq_data *data, unsigned int cpu) |
|---|
| 176 | +{ |
|---|
| 177 | + const struct cpumask *hk_mask; |
|---|
| 178 | + |
|---|
| 179 | + if (!housekeeping_enabled(HK_FLAG_MANAGED_IRQ)) |
|---|
| 180 | + return false; |
|---|
| 181 | + |
|---|
| 182 | + hk_mask = housekeeping_cpumask(HK_FLAG_MANAGED_IRQ); |
|---|
| 183 | + if (cpumask_subset(irq_data_get_effective_affinity_mask(data), hk_mask)) |
|---|
| 184 | + return false; |
|---|
| 185 | + |
|---|
| 186 | + return cpumask_test_cpu(cpu, hk_mask); |
|---|
| 172 | 187 | } |
|---|
| 173 | 188 | |
|---|
| 174 | 189 | static void irq_restore_affinity_of_irq(struct irq_desc *desc, unsigned int cpu) |
|---|
| .. | .. |
|---|
| 188 | 203 | /* |
|---|
| 189 | 204 | * If the interrupt can only be directed to a single target |
|---|
| 190 | 205 | * CPU then it is already assigned to a CPU in the affinity |
|---|
| 191 | | - * mask. No point in trying to move it around. |
|---|
| 206 | + * mask. No point in trying to move it around unless the |
|---|
| 207 | + * isolation mechanism requests to move it to an upcoming |
|---|
| 208 | + * housekeeping CPU. |
|---|
| 192 | 209 | */ |
|---|
| 193 | | - if (!irqd_is_single_target(data)) |
|---|
| 210 | + if (!irqd_is_single_target(data) || hk_should_isolate(data, cpu)) |
|---|
| 194 | 211 | irq_set_affinity_locked(data, affinity, false); |
|---|
| 195 | 212 | } |
|---|
| 196 | 213 | |
|---|