* [RFC PATCH v2 0/3] arm/arm64: fix a migrating irq bug when hotplug cpu
@ 2015-09-14 9:29 Yang Yingliang
2015-09-14 9:29 ` [RFC PATCH v2 1/3] irqchip: GICv3: set non-percpu irqs status with IRQ_MOVE_PCNTXT Yang Yingliang
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Yang Yingliang @ 2015-09-14 9:29 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel
Cc: Yang Yingliang, Jiang Liu, Thomas Gleixner, Marc Zyngier,
Mark Rutland, Will Deacon, Russell King - ARM Linux
Hi All,
There is a bug:
When cpu is disabled, all irqs will be migratged to another cpu.
In some cases, a new affinity is different, it needed to be coppied
to irq's affinity. But if the type of irq is LPI, it's affinity will
not be coppied because of irq_set_affinity's return value.
As Marc and Will suggested, I refactor the arm/arm64 migrating interrupts
code and fix the migrating irq bug while cpu is offline.
I'm trying let the core code do the migrating interrupts matter. kernel/irq/migration.c
depends on CONFIG_GENERIC_PENDING_IRQ, so I make it selected by CONFIG_SMP and
CONFIG_HOTPLUG_CPU and rename it to CONFIG_GENERIC_IRQ_MIGRATION for more general.
When CONFIG_GENERIC_IRQ_MIGRATION is enabled, an interrupt whose state_use_accessors
is not set with IRQD_MOVE_PCNTXT won't be migrated immediately in irq_set_affinity_locked().
So use irq_set_status_flags() helper to set the state in gic_irq_domain_map().
With the above preparation, move the migrating interrupts code into kernel/irq/migration.c
and fix the bug by using irq_do_set_affinity().
Changes in v2:
- use the exiting helper to set IRQD_MOVE_PCNTXT flag
- use for_each_active_irq() instead of for_each_irq_desc()
- add some warn messages when affinity is null or do set affinity failed
Cc: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Russell King - ARM Linux <linux@arm.linux.org.uk>
Yang Yingliang (3):
irqchip: GICv3: set non-percpu irqs status with IRQ_MOVE_PCNTXT
genirq: rename config GENERIC_PENDING_IRQ to GENERIC_IRQ_MIGRATION
arm/arm64: fix a migrating irq bug when hotplug cpu
arch/arc/Kconfig | 2 +-
arch/arm/Kconfig | 1 +
arch/arm/include/asm/irq.h | 1 -
arch/arm/kernel/irq.c | 62 ---------------------------------------
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/irq.h | 1 -
arch/arm64/kernel/irq.c | 62 ---------------------------------------
arch/hexagon/Kconfig | 2 +-
arch/ia64/Kconfig | 2 +-
arch/tile/Kconfig | 2 +-
arch/x86/Kconfig | 2 +-
arch/x86/kernel/apic/io_apic.c | 2 +-
drivers/irqchip/irq-gic-v3.c | 2 ++
include/linux/irq.h | 4 ++-
include/linux/irqdesc.h | 2 +-
kernel/irq/Kconfig | 4 +--
kernel/irq/Makefile | 2 +-
kernel/irq/irqdesc.c | 6 ++--
kernel/irq/manage.c | 2 +-
kernel/irq/migration.c | 66 ++++++++++++++++++++++++++++++++++++++++++
kernel/irq/proc.c | 2 +-
21 files changed, 88 insertions(+), 142 deletions(-)
--
2.5.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [RFC PATCH v2 1/3] irqchip: GICv3: set non-percpu irqs status with IRQ_MOVE_PCNTXT
2015-09-14 9:29 [RFC PATCH v2 0/3] arm/arm64: fix a migrating irq bug when hotplug cpu Yang Yingliang
@ 2015-09-14 9:29 ` Yang Yingliang
2015-09-14 12:50 ` Marc Zyngier
2015-09-14 9:29 ` [RFC PATCH v2 2/3] genirq: rename config GENERIC_PENDING_IRQ to GENERIC_IRQ_MIGRATION Yang Yingliang
2015-09-14 9:29 ` [RFC PATCH v2 3/3] arm/arm64: fix a migrating irq bug when hotplug cpu Yang Yingliang
2 siblings, 1 reply; 6+ messages in thread
From: Yang Yingliang @ 2015-09-14 9:29 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel
Cc: Yang Yingliang, Jiang Liu, Thomas Gleixner, Marc Zyngier,
Mark Rutland, Will Deacon, Russell King - ARM Linux
Use irq_set_status_flags() helper set irqs status with
IRQ_MOVE_PCNTXT. So that it can do set affinity when
calling irq_set_affinity_locked().
Cc: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Russell King - ARM Linux <linux@arm.linux.org.uk>
Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
---
drivers/irqchip/irq-gic-v3.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 7deed6e..3d8f400 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -761,6 +761,7 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
irq_domain_set_info(d, irq, hw, chip, d->host_data,
handle_fasteoi_irq, NULL, NULL);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ irq_set_status_flags(irq, IRQ_MOVE_PCNTXT);
}
/* LPIs */
if (hw >= 8192 && hw < GIC_ID_NR) {
@@ -769,6 +770,7 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
irq_domain_set_info(d, irq, hw, chip, d->host_data,
handle_fasteoi_irq, NULL, NULL);
set_irq_flags(irq, IRQF_VALID);
+ irq_set_status_flags(irq, IRQ_MOVE_PCNTXT);
}
return 0;
--
2.5.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [RFC PATCH v2 2/3] genirq: rename config GENERIC_PENDING_IRQ to GENERIC_IRQ_MIGRATION
2015-09-14 9:29 [RFC PATCH v2 0/3] arm/arm64: fix a migrating irq bug when hotplug cpu Yang Yingliang
2015-09-14 9:29 ` [RFC PATCH v2 1/3] irqchip: GICv3: set non-percpu irqs status with IRQ_MOVE_PCNTXT Yang Yingliang
@ 2015-09-14 9:29 ` Yang Yingliang
2015-09-14 9:29 ` [RFC PATCH v2 3/3] arm/arm64: fix a migrating irq bug when hotplug cpu Yang Yingliang
2 siblings, 0 replies; 6+ messages in thread
From: Yang Yingliang @ 2015-09-14 9:29 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel
Cc: Yang Yingliang, Jiang Liu, Thomas Gleixner, Marc Zyngier,
Mark Rutland, Will Deacon, Russell King - ARM Linux
Make the config name more general for moving other migration
interrupts code into kernel/irq/migration.c
Cc: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Russell King - ARM Linux <linux@arm.linux.org.uk>
Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
---
arch/arc/Kconfig | 2 +-
arch/hexagon/Kconfig | 2 +-
arch/ia64/Kconfig | 2 +-
arch/tile/Kconfig | 2 +-
arch/x86/Kconfig | 2 +-
arch/x86/kernel/apic/io_apic.c | 2 +-
include/linux/irq.h | 4 +++-
include/linux/irqdesc.h | 2 +-
kernel/irq/Kconfig | 4 ++--
kernel/irq/Makefile | 2 +-
kernel/irq/irqdesc.c | 6 +++---
kernel/irq/manage.c | 2 +-
kernel/irq/proc.c | 2 +-
13 files changed, 18 insertions(+), 16 deletions(-)
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 78c0621..5d11976 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -19,7 +19,7 @@ config ARC
select GENERIC_FIND_FIRST_BIT
# for now, we don't need GENERIC_IRQ_PROBE, CONFIG_GENERIC_IRQ_CHIP
select GENERIC_IRQ_SHOW
- select GENERIC_PENDING_IRQ if SMP
+ select GENERIC_IRQ_MIGRATION if SMP
select GENERIC_SMP_IDLE_THREAD
select HAVE_ARCH_KGDB
select HAVE_ARCH_TRACEHOOK
diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig
index 4dc89d1..ffee613 100644
--- a/arch/hexagon/Kconfig
+++ b/arch/hexagon/Kconfig
@@ -11,7 +11,7 @@ config HEXAGON
# select ARCH_WANT_OPTIONAL_GPIOLIB
# select ARCH_REQUIRE_GPIOLIB
# select HAVE_CLK
- # select GENERIC_PENDING_IRQ if SMP
+ # select GENERIC_IRQ_MIGRATION if SMP
select GENERIC_ATOMIC64
select HAVE_PERF_EVENTS
# GENERIC_ALLOCATOR is used by dma_alloc_coherent()
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index eb0249e..56e1d17 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -36,7 +36,7 @@ config IA64
select VIRT_TO_BUS
select ARCH_DISCARD_MEMBLOCK
select GENERIC_IRQ_PROBE
- select GENERIC_PENDING_IRQ if SMP
+ select GENERIC_IRQ_MIGRATION if SMP
select GENERIC_IRQ_SHOW
select GENERIC_IRQ_LEGACY
select ARCH_WANT_OPTIONAL_GPIOLIB
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index 106c21b..841102c 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -13,7 +13,7 @@ config TILE
select CC_OPTIMIZE_FOR_SIZE
select HAVE_DEBUG_KMEMLEAK
select GENERIC_IRQ_PROBE
- select GENERIC_PENDING_IRQ if SMP
+ select GENERIC_IRQ_MIGRATION if SMP
select GENERIC_IRQ_SHOW
select HAVE_DEBUG_BUGVERBOSE
select VIRT_TO_BUS
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 7aef2d5..9c07c63 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -67,7 +67,7 @@ config X86
select GENERIC_IOMAP
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
- select GENERIC_PENDING_IRQ if SMP
+ select GENERIC_IRQ_MIGRATION if SMP
select GENERIC_SMP_IDLE_THREAD
select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 38a76f8..a1203d5 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1684,7 +1684,7 @@ static unsigned int startup_ioapic_irq(struct irq_data *data)
atomic_t irq_mis_count;
-#ifdef CONFIG_GENERIC_PENDING_IRQ
+#ifdef CONFIG_GENERIC_IRQ_MIGRATION
static bool io_apic_level_ack_pending(struct mp_chip_data *data)
{
struct irq_pin_list *entry;
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 6f8b340..43053ea 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -438,12 +438,14 @@ extern int irq_set_affinity_locked(struct irq_data *data,
const struct cpumask *cpumask, bool force);
extern int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info);
-#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ)
+#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_IRQ_MIGRATION)
void irq_move_irq(struct irq_data *data);
void irq_move_masked_irq(struct irq_data *data);
+void migrate_irqs(void);
#else
static inline void irq_move_irq(struct irq_data *data) { }
static inline void irq_move_masked_irq(struct irq_data *data) { }
+static inline void migrate_irqs(void) { }
#endif
extern int no_irq_affinity;
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index 5acfa26..1ec727d 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -66,7 +66,7 @@ struct irq_desc {
#ifdef CONFIG_SMP
const struct cpumask *affinity_hint;
struct irq_affinity_notify *affinity_notify;
-#ifdef CONFIG_GENERIC_PENDING_IRQ
+#ifdef CONFIG_GENERIC_IRQ_MIGRATION
cpumask_var_t pending_mask;
#endif
#endif
diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig
index 9a76e3b..4350358 100644
--- a/kernel/irq/Kconfig
+++ b/kernel/irq/Kconfig
@@ -26,8 +26,8 @@ config GENERIC_IRQ_SHOW_LEVEL
config GENERIC_IRQ_LEGACY_ALLOC_HWIRQ
bool
-# Support for delayed migration from interrupt context
-config GENERIC_PENDING_IRQ
+# Support for generic irq migration
+config GENERIC_IRQ_MIGRATION
bool
# Alpha specific irq affinity mechanism
diff --git a/kernel/irq/Makefile b/kernel/irq/Makefile
index d121235..bdd31b7 100644
--- a/kernel/irq/Makefile
+++ b/kernel/irq/Makefile
@@ -4,6 +4,6 @@ obj-$(CONFIG_GENERIC_IRQ_CHIP) += generic-chip.o
obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o
obj-$(CONFIG_IRQ_DOMAIN) += irqdomain.o
obj-$(CONFIG_PROC_FS) += proc.o
-obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o
+obj-$(CONFIG_GENERIC_IRQ_MIGRATION) += migration.o
obj-$(CONFIG_PM_SLEEP) += pm.o
obj-$(CONFIG_GENERIC_MSI_IRQ) += msi.o
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 0a2a4b6..9514e56 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -41,7 +41,7 @@ static int alloc_masks(struct irq_desc *desc, gfp_t gfp, int node)
if (!zalloc_cpumask_var_node(&desc->irq_data.affinity, gfp, node))
return -ENOMEM;
-#ifdef CONFIG_GENERIC_PENDING_IRQ
+#ifdef CONFIG_GENERIC_IRQ_MIGRATION
if (!zalloc_cpumask_var_node(&desc->pending_mask, gfp, node)) {
free_cpumask_var(desc->irq_data.affinity);
return -ENOMEM;
@@ -54,7 +54,7 @@ static void desc_smp_init(struct irq_desc *desc, int node)
{
desc->irq_data.node = node;
cpumask_copy(desc->irq_data.affinity, irq_default_affinity);
-#ifdef CONFIG_GENERIC_PENDING_IRQ
+#ifdef CONFIG_GENERIC_IRQ_MIGRATION
cpumask_clear(desc->pending_mask);
#endif
}
@@ -118,7 +118,7 @@ static void delete_irq_desc(unsigned int irq)
#ifdef CONFIG_SMP
static void free_masks(struct irq_desc *desc)
{
-#ifdef CONFIG_GENERIC_PENDING_IRQ
+#ifdef CONFIG_GENERIC_IRQ_MIGRATION
free_cpumask_var(desc->pending_mask);
#endif
free_cpumask_var(desc->irq_data.affinity);
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index ad1b064..6207deb 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -153,7 +153,7 @@ void irq_set_thread_affinity(struct irq_desc *desc)
}
}
-#ifdef CONFIG_GENERIC_PENDING_IRQ
+#ifdef CONFIG_GENERIC_IRQ_MIGRATION
static inline bool irq_can_move_pcntxt(struct irq_data *data)
{
return irqd_can_move_in_process_context(data);
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 0e97c14..c070fa6 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -41,7 +41,7 @@ static int show_irq_affinity(int type, struct seq_file *m, void *v)
struct irq_desc *desc = irq_to_desc((long)m->private);
const struct cpumask *mask = desc->irq_data.affinity;
-#ifdef CONFIG_GENERIC_PENDING_IRQ
+#ifdef CONFIG_GENERIC_IRQ_MIGRATION
if (irqd_is_setaffinity_pending(&desc->irq_data))
mask = desc->pending_mask;
#endif
--
2.5.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [RFC PATCH v2 3/3] arm/arm64: fix a migrating irq bug when hotplug cpu
2015-09-14 9:29 [RFC PATCH v2 0/3] arm/arm64: fix a migrating irq bug when hotplug cpu Yang Yingliang
2015-09-14 9:29 ` [RFC PATCH v2 1/3] irqchip: GICv3: set non-percpu irqs status with IRQ_MOVE_PCNTXT Yang Yingliang
2015-09-14 9:29 ` [RFC PATCH v2 2/3] genirq: rename config GENERIC_PENDING_IRQ to GENERIC_IRQ_MIGRATION Yang Yingliang
@ 2015-09-14 9:29 ` Yang Yingliang
2 siblings, 0 replies; 6+ messages in thread
From: Yang Yingliang @ 2015-09-14 9:29 UTC (permalink / raw)
To: linux-arm-kernel, linux-kernel
Cc: Yang Yingliang, Jiang Liu, Thomas Gleixner, Marc Zyngier,
Mark Rutland, Will Deacon, Russell King - ARM Linux
When cpu is disabled, all irqs will be migratged to another cpu.
In some cases, a new affinity is different, it needed to be coppied
to irq's affinity. But if the type of irq is LPI, it's affinity will
not be coppied because of irq_set_affinity's return value. Fix it by
using irq_do_set_affinity.
And migrating interrupts is a core code matter, so move the code to
kernel/irq/migration.c and select CONFIG_GENERIC_IRQ_MIGRATION when
CONFIG_HOTPLUG_CPU and CONFIG_SMP is enabled.
Cc: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Russell King - ARM Linux <linux@arm.linux.org.uk>
Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
---
arch/arm/Kconfig | 1 +
arch/arm/include/asm/irq.h | 1 -
arch/arm/kernel/irq.c | 62 -----------------------------------------
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/irq.h | 1 -
arch/arm64/kernel/irq.c | 62 -----------------------------------------
kernel/irq/migration.c | 66 ++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 68 insertions(+), 126 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 72ad724..d70ddd5 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -22,6 +22,7 @@ config ARM
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
select GENERIC_IDLE_POLL_SETUP
select GENERIC_IRQ_PROBE
+ select GENERIC_IRQ_MIGRATION if SMP && HOTPLUG_CPU
select GENERIC_IRQ_SHOW
select GENERIC_IRQ_SHOW_LEVEL
select GENERIC_PCI_IOMAP
diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h
index be1d07d..882bf98 100644
--- a/arch/arm/include/asm/irq.h
+++ b/arch/arm/include/asm/irq.h
@@ -24,7 +24,6 @@
#ifndef __ASSEMBLY__
struct irqaction;
struct pt_regs;
-extern void migrate_irqs(void);
extern void asm_do_IRQ(unsigned int, struct pt_regs *);
void handle_IRQ(unsigned int, struct pt_regs *);
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 5ff4826..78abea8 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -31,7 +31,6 @@
#include <linux/smp.h>
#include <linux/init.h>
#include <linux/seq_file.h>
-#include <linux/ratelimit.h>
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/kallsyms.h>
@@ -136,64 +135,3 @@ int __init arch_probe_nr_irqs(void)
return nr_irqs;
}
#endif
-
-#ifdef CONFIG_HOTPLUG_CPU
-static bool migrate_one_irq(struct irq_desc *desc)
-{
- struct irq_data *d = irq_desc_get_irq_data(desc);
- const struct cpumask *affinity = irq_data_get_affinity_mask(d);
- struct irq_chip *c;
- bool ret = false;
-
- /*
- * If this is a per-CPU interrupt, or the affinity does not
- * include this CPU, then we have nothing to do.
- */
- if (irqd_is_per_cpu(d) || !cpumask_test_cpu(smp_processor_id(), affinity))
- return false;
-
- if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
- affinity = cpu_online_mask;
- ret = true;
- }
-
- c = irq_data_get_irq_chip(d);
- if (!c->irq_set_affinity)
- pr_debug("IRQ%u: unable to set affinity\n", d->irq);
- else if (c->irq_set_affinity(d, affinity, false) == IRQ_SET_MASK_OK && ret)
- cpumask_copy(irq_data_get_affinity_mask(d), affinity);
-
- return ret;
-}
-
-/*
- * The current CPU has been marked offline. Migrate IRQs off this CPU.
- * If the affinity settings do not allow other CPUs, force them onto any
- * available CPU.
- *
- * Note: we must iterate over all IRQs, whether they have an attached
- * action structure or not, as we need to get chained interrupts too.
- */
-void migrate_irqs(void)
-{
- unsigned int i;
- struct irq_desc *desc;
- unsigned long flags;
-
- local_irq_save(flags);
-
- for_each_irq_desc(i, desc) {
- bool affinity_broken;
-
- raw_spin_lock(&desc->lock);
- affinity_broken = migrate_one_irq(desc);
- raw_spin_unlock(&desc->lock);
-
- if (affinity_broken)
- pr_warn_ratelimited("IRQ%u no longer affine to CPU%u\n",
- i, smp_processor_id());
- }
-
- local_irq_restore(flags);
-}
-#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 7d95663..70d5b23 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -33,6 +33,7 @@ config ARM64
select GENERIC_CPU_AUTOPROBE
select GENERIC_EARLY_IOREMAP
select GENERIC_IRQ_PROBE
+ select GENERIC_IRQ_MIGRATION if SMP && HOTPLUG_CPU
select GENERIC_IRQ_SHOW
select GENERIC_IRQ_SHOW_LEVEL
select GENERIC_PCI_IOMAP
diff --git a/arch/arm64/include/asm/irq.h b/arch/arm64/include/asm/irq.h
index bbb251b..0916929 100644
--- a/arch/arm64/include/asm/irq.h
+++ b/arch/arm64/include/asm/irq.h
@@ -7,7 +7,6 @@
struct pt_regs;
-extern void migrate_irqs(void);
extern void set_handle_irq(void (*handle_irq)(struct pt_regs *));
static inline void acpi_irq_init(void)
diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c
index 11dc3fd..9f17ec0 100644
--- a/arch/arm64/kernel/irq.c
+++ b/arch/arm64/kernel/irq.c
@@ -27,7 +27,6 @@
#include <linux/init.h>
#include <linux/irqchip.h>
#include <linux/seq_file.h>
-#include <linux/ratelimit.h>
unsigned long irq_err_count;
@@ -54,64 +53,3 @@ void __init init_IRQ(void)
if (!handle_arch_irq)
panic("No interrupt controller found.");
}
-
-#ifdef CONFIG_HOTPLUG_CPU
-static bool migrate_one_irq(struct irq_desc *desc)
-{
- struct irq_data *d = irq_desc_get_irq_data(desc);
- const struct cpumask *affinity = irq_data_get_affinity_mask(d);
- struct irq_chip *c;
- bool ret = false;
-
- /*
- * If this is a per-CPU interrupt, or the affinity does not
- * include this CPU, then we have nothing to do.
- */
- if (irqd_is_per_cpu(d) || !cpumask_test_cpu(smp_processor_id(), affinity))
- return false;
-
- if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
- affinity = cpu_online_mask;
- ret = true;
- }
-
- c = irq_data_get_irq_chip(d);
- if (!c->irq_set_affinity)
- pr_debug("IRQ%u: unable to set affinity\n", d->irq);
- else if (c->irq_set_affinity(d, affinity, false) == IRQ_SET_MASK_OK && ret)
- cpumask_copy(irq_data_get_affinity_mask(d), affinity);
-
- return ret;
-}
-
-/*
- * The current CPU has been marked offline. Migrate IRQs off this CPU.
- * If the affinity settings do not allow other CPUs, force them onto any
- * available CPU.
- *
- * Note: we must iterate over all IRQs, whether they have an attached
- * action structure or not, as we need to get chained interrupts too.
- */
-void migrate_irqs(void)
-{
- unsigned int i;
- struct irq_desc *desc;
- unsigned long flags;
-
- local_irq_save(flags);
-
- for_each_irq_desc(i, desc) {
- bool affinity_broken;
-
- raw_spin_lock(&desc->lock);
- affinity_broken = migrate_one_irq(desc);
- raw_spin_unlock(&desc->lock);
-
- if (affinity_broken)
- pr_warn_ratelimited("IRQ%u no longer affine to CPU%u\n",
- i, smp_processor_id());
- }
-
- local_irq_restore(flags);
-}
-#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index 37ddb7b..7271dbc 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -1,6 +1,7 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
+#include <linux/ratelimit.h>
#include "internals.h"
@@ -77,3 +78,68 @@ void irq_move_irq(struct irq_data *idata)
if (!masked)
idata->chip->irq_unmask(idata);
}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static bool migrate_one_irq(struct irq_desc *desc)
+{
+ struct irq_data *d = irq_desc_get_irq_data(desc);
+ const struct cpumask *affinity = d->affinity;
+ struct irq_chip *c;
+ bool ret = false;
+
+ /*
+ * If this is a per-CPU interrupt, or the affinity does not
+ * include this CPU, then we have nothing to do.
+ */
+ if (irqd_is_per_cpu(d) || !cpumask_test_cpu(smp_processor_id(), affinity))
+ return false;
+
+ if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
+ affinity = cpu_online_mask;
+ ret = true;
+ }
+
+ c = irq_data_get_irq_chip(d);
+ if (!c->irq_set_affinity) {
+ pr_warn_ratelimited("IRQ%u: unable to set affinity\n", d->irq);
+ } else {
+ int r = irq_do_set_affinity(d, affinity, false);
+ if (r)
+ pr_warn_ratelimited("IRQ%u: set affinity failed(%d).\n", d->irq, r);
+ }
+
+ return ret;
+}
+
+/*
+ * The current CPU has been marked offline. Migrate IRQs off this CPU.
+ * If the affinity settings do not allow other CPUs, force them onto any
+ * available CPU.
+ *
+ * Note: we must iterate over all IRQs, whether they have an attached
+ * action structure or not, as we need to get chained interrupts too.
+ */
+void migrate_irqs(void)
+{
+ unsigned int irq;
+ struct irq_desc *desc;
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ for_each_active_irq(irq) {
+ bool affinity_broken;
+
+ desc = irq_to_desc(irq);
+ raw_spin_lock(&desc->lock);
+ affinity_broken = migrate_one_irq(desc);
+ raw_spin_unlock(&desc->lock);
+
+ if (affinity_broken)
+ pr_warn_ratelimited("IRQ%u no longer affine to CPU%u\n",
+ irq, smp_processor_id());
+ }
+
+ local_irq_restore(flags);
+}
+#endif /* CONFIG_HOTPLUG_CPU */
--
2.5.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [RFC PATCH v2 1/3] irqchip: GICv3: set non-percpu irqs status with IRQ_MOVE_PCNTXT
2015-09-14 9:29 ` [RFC PATCH v2 1/3] irqchip: GICv3: set non-percpu irqs status with IRQ_MOVE_PCNTXT Yang Yingliang
@ 2015-09-14 12:50 ` Marc Zyngier
2015-09-15 3:07 ` Yang Yingliang
0 siblings, 1 reply; 6+ messages in thread
From: Marc Zyngier @ 2015-09-14 12:50 UTC (permalink / raw)
To: Yang Yingliang, linux-arm-kernel, linux-kernel
Cc: Jiang Liu, Thomas Gleixner, Mark Rutland, Will Deacon,
Russell King - ARM Linux
On 14/09/15 10:29, Yang Yingliang wrote:
> Use irq_set_status_flags() helper set irqs status with
> IRQ_MOVE_PCNTXT. So that it can do set affinity when
> calling irq_set_affinity_locked().
>
> Cc: Jiang Liu <jiang.liu@linux.intel.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Russell King - ARM Linux <linux@arm.linux.org.uk>
> Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
> ---
> drivers/irqchip/irq-gic-v3.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index 7deed6e..3d8f400 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -761,6 +761,7 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
> irq_domain_set_info(d, irq, hw, chip, d->host_data,
> handle_fasteoi_irq, NULL, NULL);
> set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
> + irq_set_status_flags(irq, IRQ_MOVE_PCNTXT);
> }
> /* LPIs */
> if (hw >= 8192 && hw < GIC_ID_NR) {
> @@ -769,6 +770,7 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
> irq_domain_set_info(d, irq, hw, chip, d->host_data,
> handle_fasteoi_irq, NULL, NULL);
> set_irq_flags(irq, IRQF_VALID);
> + irq_set_status_flags(irq, IRQ_MOVE_PCNTXT);
> }
>
> return 0;
>
I'm still not keen on this approach. As far as I can tell, the only
reason you are setting this flag is to be able to use
GENERIC_PENDING_IRQ. irq_set_affinity_locked would work even if you
don't select this config option, because irq_can_move_pcntxt() will
always return true if this is not selected.
So instead of adding flags that are not required on ARM, why don't you
just make migration.c to compile even when GENERIC_PENDING_IRQ is not
selected? I think this would make a lot more sense.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFC PATCH v2 1/3] irqchip: GICv3: set non-percpu irqs status with IRQ_MOVE_PCNTXT
2015-09-14 12:50 ` Marc Zyngier
@ 2015-09-15 3:07 ` Yang Yingliang
0 siblings, 0 replies; 6+ messages in thread
From: Yang Yingliang @ 2015-09-15 3:07 UTC (permalink / raw)
To: Marc Zyngier, linux-arm-kernel, linux-kernel
Cc: Jiang Liu, Thomas Gleixner, Mark Rutland, Will Deacon,
Russell King - ARM Linux
On 2015/9/14 20:50, Marc Zyngier wrote:
> On 14/09/15 10:29, Yang Yingliang wrote:
>> Use irq_set_status_flags() helper set irqs status with
>> IRQ_MOVE_PCNTXT. So that it can do set affinity when
>> calling irq_set_affinity_locked().
>>
>> Cc: Jiang Liu <jiang.liu@linux.intel.com>
>> Cc: Thomas Gleixner <tglx@linutronix.de>
>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>> Cc: Mark Rutland <mark.rutland@arm.com>
>> Cc: Will Deacon <will.deacon@arm.com>
>> Cc: Russell King - ARM Linux <linux@arm.linux.org.uk>
>> Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
>> ---
>> drivers/irqchip/irq-gic-v3.c | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>> index 7deed6e..3d8f400 100644
>> --- a/drivers/irqchip/irq-gic-v3.c
>> +++ b/drivers/irqchip/irq-gic-v3.c
>> @@ -761,6 +761,7 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
>> irq_domain_set_info(d, irq, hw, chip, d->host_data,
>> handle_fasteoi_irq, NULL, NULL);
>> set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
>> + irq_set_status_flags(irq, IRQ_MOVE_PCNTXT);
>> }
>> /* LPIs */
>> if (hw >= 8192 && hw < GIC_ID_NR) {
>> @@ -769,6 +770,7 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
>> irq_domain_set_info(d, irq, hw, chip, d->host_data,
>> handle_fasteoi_irq, NULL, NULL);
>> set_irq_flags(irq, IRQF_VALID);
>> + irq_set_status_flags(irq, IRQ_MOVE_PCNTXT);
>> }
>>
>> return 0;
>>
>
> I'm still not keen on this approach. As far as I can tell, the only
> reason you are setting this flag is to be able to use
> GENERIC_PENDING_IRQ. irq_set_affinity_locked would work even if you
> don't select this config option, because irq_can_move_pcntxt() will
> always return true if this is not selected.
>
> So instead of adding flags that are not required on ARM, why don't you
> just make migration.c to compile even when GENERIC_PENDING_IRQ is not
> selected? I think this would make a lot more sense.
OK, I will try this way.
Thanks,
Yang
>
> Thanks,
>
> M.
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2015-09-15 3:08 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-09-14 9:29 [RFC PATCH v2 0/3] arm/arm64: fix a migrating irq bug when hotplug cpu Yang Yingliang
2015-09-14 9:29 ` [RFC PATCH v2 1/3] irqchip: GICv3: set non-percpu irqs status with IRQ_MOVE_PCNTXT Yang Yingliang
2015-09-14 12:50 ` Marc Zyngier
2015-09-15 3:07 ` Yang Yingliang
2015-09-14 9:29 ` [RFC PATCH v2 2/3] genirq: rename config GENERIC_PENDING_IRQ to GENERIC_IRQ_MIGRATION Yang Yingliang
2015-09-14 9:29 ` [RFC PATCH v2 3/3] arm/arm64: fix a migrating irq bug when hotplug cpu Yang Yingliang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).