LKML Archive on lore.kernel.org
 help / color / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>,
	Christoph Hellwig <hch@lst.de>, Ingo Molnar <mingo@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Michael Ellerman <mpe@ellerman.id.au>,
	Jens Axboe <axboe@kernel.dk>, Keith Busch <keith.busch@intel.com>
Subject: [patch 51/55] genirq/cpuhotplug: Handle managed IRQs on CPU hotplug
Date: Tue, 20 Jun 2017 01:37:51 +0200
Message-ID: <20170619235447.273417334@linutronix.de> (raw)
In-Reply-To: <20170619233700.547167146@linutronix.de>


[-- Attachment #0: genirq-cpuhotplug--Handle-managed-IRQs-on-CPU-hotplug.patch --]
[-- Type: text/plain, Size: 4371 bytes --]

If a CPU goes offline, interrupts affine to the CPU are moved away. If the
outgoing CPU is the last CPU in the affinity mask the migration code breaks
the affinity and sets it it all online cpus.

This is a problem for affinity managed interrupts as CPU hotplug is often
used for power management purposes. If the affinity is broken, the
interrupt is not longer affine to the CPUs to which it was allocated.

The affinity spreading allows to lay out multi queue devices in a way that
they are assigned to a single CPU or a group of CPUs. If the last CPU goes
offline, then the queue is not longer used, so the interrupt can be
shutdown gracefully and parked until one of the assigned CPUs comes online
again.

Add a graceful shutdown mechanism into the irq affinity breaking code path,
mark the irq as MANAGED_SHUTDOWN and leave the affinity mask unmodified.

In the online path, scan the active interrupts for managed interrupts and
if the interrupt is functional and the newly online CPU is part of the
affinity mask, restart the interrupt if it is marked MANAGED_SHUTDOWN or if
the interrupts is started up, try to add the CPU back to the effective
affinity mask.

Originally-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

---
 include/linux/cpuhotplug.h |    1 +
 include/linux/irq.h        |    5 +++++
 kernel/cpu.c               |    5 +++++
 kernel/irq/cpuhotplug.c    |   45 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 56 insertions(+)

--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -124,6 +124,7 @@ enum cpuhp_state {
 	CPUHP_AP_ONLINE_IDLE,
 	CPUHP_AP_SMPBOOT_THREADS,
 	CPUHP_AP_X86_VDSO_VMA_ONLINE,
+	CPUHP_AP_IRQ_AFFINITY_ONLINE,
 	CPUHP_AP_PERF_ONLINE,
 	CPUHP_AP_PERF_X86_ONLINE,
 	CPUHP_AP_PERF_X86_UNCORE_ONLINE,
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -499,7 +499,12 @@ extern int irq_set_affinity_locked(struc
 				   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_IRQ_MIGRATION)
 extern void irq_migrate_all_off_this_cpu(void);
+extern int irq_affinity_online_cpu(unsigned int cpu);
+#else
+# define irq_affinity_online_cpu	NULL
+#endif
 
 #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ)
 void irq_move_irq(struct irq_data *data);
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1252,6 +1252,11 @@ static struct cpuhp_step cpuhp_ap_states
 		.startup.single		= smpboot_unpark_threads,
 		.teardown.single	= NULL,
 	},
+	[CPUHP_AP_IRQ_AFFINITY_ONLINE] = {
+		.name			= "irq/affinity:online",
+		.startup.single		= irq_affinity_online_cpu,
+		.teardown.single	= NULL,
+	},
 	[CPUHP_AP_PERF_ONLINE] = {
 		.name			= "perf:online",
 		.startup.single		= perf_event_init_cpu,
--- a/kernel/irq/cpuhotplug.c
+++ b/kernel/irq/cpuhotplug.c
@@ -83,6 +83,15 @@ static bool migrate_one_irq(struct irq_d
 		chip->irq_mask(d);
 
 	if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
+		/*
+		 * If the interrupt is managed, then shut it down and leave
+		 * the affinity untouched.
+		 */
+		if (irqd_affinity_is_managed(d)) {
+			irqd_set_managed_shutdown(d);
+			irq_shutdown(desc);
+			return false;
+		}
 		affinity = cpu_online_mask;
 		brokeaff = true;
 	}
@@ -129,3 +138,39 @@ void irq_migrate_all_off_this_cpu(void)
 		}
 	}
 }
+
+static void irq_restore_affinity_of_irq(struct irq_desc *desc, unsigned int cpu)
+{
+	struct irq_data *data = irq_desc_get_irq_data(desc);
+	const struct cpumask *affinity = irq_data_get_affinity_mask(data);
+
+	if (!irqd_affinity_is_managed(data) || !desc->action ||
+	    !irq_data_get_irq_chip(data) || !cpumask_test_cpu(cpu, affinity))
+		return;
+
+	if (irqd_is_managed_and_shutdown(data))
+		irq_startup(desc, IRQ_RESEND, IRQ_START_COND);
+	else
+		irq_set_affinity_locked(data, affinity, false);
+}
+
+/**
+ * irq_affinity_online_cpu - Restore affinity for managed interrupts
+ * @cpu:	Upcoming CPU for which interrupts should be restored
+ */
+int irq_affinity_online_cpu(unsigned int cpu)
+{
+	struct irq_desc *desc;
+	unsigned int irq;
+
+	irq_lock_sparse();
+	for_each_active_irq(irq) {
+		desc = irq_to_desc(irq);
+		raw_spin_lock_irq(&desc->lock);
+		irq_restore_affinity_of_irq(desc, cpu);
+		raw_spin_unlock_irq(&desc->lock);
+	}
+	irq_unlock_sparse();
+
+	return 0;
+}

  parent reply index

Thread overview: 122+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-19 23:37 [patch 00/55] genirq: Debuggability, consolidation and managed affinities Thomas Gleixner
2017-06-19 23:37 ` [patch 01/55] x86/apic: Add name to irq chip Thomas Gleixner
2017-06-22 16:40   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 02/55] iommu/amd: " Thomas Gleixner
2017-06-21 15:51   ` Joerg Roedel
2017-06-22 16:40   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 03/55] iommu/vt-d: " Thomas Gleixner
2017-06-21 15:51   ` Joerg Roedel
2017-06-22 16:41   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 04/55] genirq/msi: Prevent overwriting domain name Thomas Gleixner
2017-06-22 16:41   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 05/55] genirq: Allow fwnode to carry name information only Thomas Gleixner
2017-06-22 16:42   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 06/55] x86/vector: Create named irq domain Thomas Gleixner
2017-06-22 16:42   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 07/55] x86/ioapic: " Thomas Gleixner
2017-06-22 16:43   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 08/55] x86/htirq: Create named domain Thomas Gleixner
2017-06-22 16:44   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 09/55] x86/uv: Create named irq domain Thomas Gleixner
2017-06-22 16:44   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 10/55] x86/msi: Provide new iommu irqdomain interface Thomas Gleixner
2017-06-22 16:45   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 11/55] iommu/vt-d: Use named irq domain interface Thomas Gleixner
2017-06-21 15:52   ` Joerg Roedel
2017-06-22 16:45   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 12/55] iommu/amd: " Thomas Gleixner
2017-06-21 15:52   ` Joerg Roedel
2017-06-22 16:46   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 13/55] x86/msi: Remove unused remap " Thomas Gleixner
2017-06-22 16:46   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 14/55] x86/msi: Create named irq domains Thomas Gleixner
2017-06-22 16:47   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 15/55] PCI: vmd: Create named irq domain Thomas Gleixner
2017-06-20 20:07   ` Keith Busch
2017-06-20 20:07     ` Thomas Gleixner
2017-06-20 20:39       ` Thomas Gleixner
2017-06-22 16:47   ` [tip:irq/core] PCI/vmd: " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 16/55] genirq/irqdomain: Add map counter Thomas Gleixner
2017-06-22 16:48   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 17/55] genirq/debugfs: Add proper debugfs interface Thomas Gleixner
2017-06-22 16:49   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 18/55] genirq: Add missing comment for IRQD_STARTED Thomas Gleixner
2017-06-22 16:49   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 19/55] genirq: Provide irq_fixup_move_pending() Thomas Gleixner
2017-06-20  4:21   ` Dou Liyang
2017-06-20  6:58     ` Thomas Gleixner
2017-06-22 16:50   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 20/55] x86/irq: Cleanup pending irq move in fixup_irqs() Thomas Gleixner
2017-06-22 16:50   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 21/55] genirq: Remove mask argument from setup_affinity() Thomas Gleixner
2017-06-22 16:51   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 22/55] genirq: Rename setup_affinity() to irq_setup_affinity() Thomas Gleixner
2017-06-22 16:52   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 23/55] genirq: Move initial affinity setup to irq_startup() Thomas Gleixner
2017-06-22 16:52   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 24/55] genirq: Move pending helpers to internal.h Thomas Gleixner
2017-06-22 16:53   ` [tip:irq/core] " tip-bot for Christoph Hellwig
2017-06-19 23:37 ` [patch 25/55] genirq/cpuhotplug: Remove irq disabling logic Thomas Gleixner
2017-06-22 16:53   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 26/55] genirq/cpuhotplug: Dont claim success on error Thomas Gleixner
2017-06-22 16:54   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 27/55] genirq/cpuhotplug: Reorder check logic Thomas Gleixner
2017-06-22 16:54   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 28/55] genirq/cpuhotplug: Do not migrated shutdown irqs Thomas Gleixner
2017-06-22 16:55   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 29/55] genirq/cpuhotplug: Add support for cleaning up move in progress Thomas Gleixner
2017-06-22 16:56   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 30/55] genirq/cpuhotplug: Add support for conditional masking Thomas Gleixner
2017-06-22 16:56   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 31/55] genirq/cpuhotplug: Set force affinity flag on hotplug migration Thomas Gleixner
2017-06-22 16:57   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 32/55] x86/irq: Restructure fixup_irqs() Thomas Gleixner
2017-06-20 21:34   ` Keith Busch
2017-06-20 21:28     ` Thomas Gleixner
2017-06-22 16:57   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 33/55] x86/irq: Use irq_migrate_all_off_this_cpu() Thomas Gleixner
2017-06-22 16:58   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 34/55] genirq: Move irq_fixup_move_pending() to core Thomas Gleixner
2017-06-22 16:58   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 35/55] genirq: Remove pointless arg from show_irq_affinity Thomas Gleixner
2017-06-22 16:59   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 36/55] genirq: Remove pointless gfp argument Thomas Gleixner
2017-06-22 17:00   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 37/55] genirq/proc: Replace ever repeating type cast Thomas Gleixner
2017-06-22 17:00   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 38/55] genirq: Introduce effective affinity mask Thomas Gleixner
2017-06-22 17:01   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 39/55] genirq/cpuhotplug: Use " Thomas Gleixner
2017-06-22 17:01   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 40/55] x86/apic: Move flat_cpu_mask_to_apicid_and() into C source Thomas Gleixner
2017-06-22 17:02   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 41/55] x86/uv: Use default_cpu_mask_to_apicid_and() Thomas Gleixner
2017-06-22 17:03   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 42/55] x86/apic: Move online masking to core code Thomas Gleixner
2017-06-22 17:03   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 43/55] x86/apic: Move cpumask and " Thomas Gleixner
2017-06-22 17:04   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 44/55] x86/apic: Add irq_data argument to apic->cpu_mask_to_apicid() Thomas Gleixner
2017-06-22 17:04   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 45/55] xen/events: Add support for effective affinity mask Thomas Gleixner
2017-06-22 17:05   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 46/55] x86/apic: Implement effective irq mask update Thomas Gleixner
2017-06-22 17:05   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 47/55] genirq: Introduce IRQD_MANAGED_SHUTDOWN Thomas Gleixner
2017-06-22 17:06   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 48/55] genirq: Split out irq_startup() code Thomas Gleixner
2017-06-22 17:06   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 49/55] genirq: Add force argument to irq_startup() Thomas Gleixner
2017-06-22 17:07   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 50/55] genirq: Handle managed irqs gracefully in irq_startup() Thomas Gleixner
2017-06-22 17:08   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` Thomas Gleixner [this message]
2017-06-22 17:08   ` [tip:irq/core] genirq/cpuhotplug: Handle managed IRQs on CPU hotplug tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 52/55] genirq: Introduce IRQD_SINGLE_TARGET flag Thomas Gleixner
2017-06-22 17:09   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 53/55] genirq/cpuhotplug: Avoid irq affinity setting for single targets Thomas Gleixner
2017-06-22 17:09   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 54/55] x86/apic: Mark single target interrupts Thomas Gleixner
2017-06-22 17:10   ` [tip:irq/core] " tip-bot for Thomas Gleixner
2017-06-19 23:37 ` [patch 55/55] genirq/affinity: Assign vectors to all present CPUs Thomas Gleixner
2017-06-20  9:23 ` [patch 00/55] genirq: Debuggability, consolidation and managed affinities Christoph Hellwig

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170619235447.273417334@linutronix.de \
    --to=tglx@linutronix.de \
    --cc=axboe@kernel.dk \
    --cc=hch@lst.de \
    --cc=keith.busch@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marc.zyngier@arm.com \
    --cc=mingo@kernel.org \
    --cc=mpe@ellerman.id.au \
    --cc=peterz@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

LKML Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/lkml/0 lkml/git/0.git
	git clone --mirror https://lore.kernel.org/lkml/1 lkml/git/1.git
	git clone --mirror https://lore.kernel.org/lkml/2 lkml/git/2.git
	git clone --mirror https://lore.kernel.org/lkml/3 lkml/git/3.git
	git clone --mirror https://lore.kernel.org/lkml/4 lkml/git/4.git
	git clone --mirror https://lore.kernel.org/lkml/5 lkml/git/5.git
	git clone --mirror https://lore.kernel.org/lkml/6 lkml/git/6.git
	git clone --mirror https://lore.kernel.org/lkml/7 lkml/git/7.git
	git clone --mirror https://lore.kernel.org/lkml/8 lkml/git/8.git
	git clone --mirror https://lore.kernel.org/lkml/9 lkml/git/9.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 lkml lkml/ https://lore.kernel.org/lkml \
		linux-kernel@vger.kernel.org
	public-inbox-index lkml

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-kernel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git