From cd6d19b8e42cfef81a1ee3c4e4367295e8025024 Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Thu, 22 Jun 2017 13:33:08 +0530 Subject: [PATCH 1/2] genriq: pick only one CPU while overriding the affinity during migration With commit bfc60d474137 ("genirq: Use irq_set_affinity_locked to change irq affinity"), affinity listeners receive the notification when the irq affinity is changed during migration. If there is no online and un-isolated CPU available from the user specified affinity, the affinity is overridden with all online and un-isolated CPUs. The same cpumask is notified to PM QOS affinity listener which applies PM_QOS_CPU_DMA_LATENCY vote to all those CPUs. As the low level irqchip driver sets affinity to only one CPU, do the same while overriding the affinity during migration. Change-Id: I0bcb75dd356658da100fbeeefd33ef8b121f4d6d Signed-off-by: Pavankumar Kondeti --- kernel/irq/cpuhotplug.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/kernel/irq/cpuhotplug.c b/kernel/irq/cpuhotplug.c index 6c8e154c7384..3dc1dbd9c166 100644 --- a/kernel/irq/cpuhotplug.c +++ b/kernel/irq/cpuhotplug.c @@ -40,6 +40,17 @@ static bool migrate_one_irq(struct irq_desc *desc) cpu_isolated_mask); if (cpumask_empty(affinity)) affinity = cpu_online_mask; + /* + * We are overriding the affinity with all online and + * un-isolated cpus. irq_set_affinity_locked() call + * below notify this mask to PM QOS affinity listener. + * That results in applying the CPU_DMA_LATENCY QOS + * to all the CPUs specified in the mask. But the low + * level irqchip driver sets the affinity of an irq + * to only one CPU. So pick only one CPU from the + * prepared mask while overriding the user affinity. + */ + affinity = cpumask_of(cpumask_any(affinity)); ret = true; } From 971af7d6edebc1ba813b7a1248bc4f1d6d763c97 Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Fri, 16 Jun 2017 09:36:25 +0530 Subject: [PATCH 2/2] genirq: honour default IRQ affinity setting during migration Userspace can set the default IRQ affinity setting by writing into /proc/irq/default_smp_affinity file. When an IRQ affinity is broken during isolation/hotplug,override the affinity to online and un-isolated CPUs from the default affinity CPUs. If no such CPU is available, then only override with cpu_online_mask. Change-Id: I7578728ed0d7c17c5890d9916cfd6451d1968568 Signed-off-by: Pavankumar Kondeti --- kernel/irq/cpuhotplug.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/kernel/irq/cpuhotplug.c b/kernel/irq/cpuhotplug.c index 3dc1dbd9c166..4684b7595e63 100644 --- a/kernel/irq/cpuhotplug.c +++ b/kernel/irq/cpuhotplug.c @@ -36,10 +36,21 @@ static bool migrate_one_irq(struct irq_desc *desc) affinity = &available_cpus; if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) { + /* + * The order of preference for selecting a fallback CPU is + * + * (1) online and un-isolated CPU from default affinity + * (2) online and un-isolated CPU + * (3) online CPU + */ cpumask_andnot(&available_cpus, cpu_online_mask, cpu_isolated_mask); - if (cpumask_empty(affinity)) + if (cpumask_intersects(&available_cpus, irq_default_affinity)) + cpumask_and(&available_cpus, &available_cpus, + irq_default_affinity); + else if (cpumask_empty(&available_cpus)) affinity = cpu_online_mask; + /* * We are overriding the affinity with all online and * un-isolated cpus. irq_set_affinity_locked() call