linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Yinghai Lu <yinghai@kernel.org>
To: Thomas Gleixner <tglx@linutronix.de>, Ingo Molnar <mingo@elte.hu>,
	"H. Peter Anvin" <hpa@zytor.com>, Tony Luck <tony.luck@intel.com>,
	Bjorn Helgaas <bhelgaas@google.com>,
	"Rafael J. Wysocki" <rjw@sisk.pl>
Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-acpi@vger.kernel.org, Yinghai Lu <yinghai@kernel.org>,
	Paul Gortmaker <paul.gortmaker@windriver.com>,
	Joerg Roedel <joro@8bytes.org>,
	Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>,
	Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Subject: [PATCH v5 21/33] x86, irq: Make mp_register_ioapic handle hot-added ioapic
Date: Thu,  2 Jan 2014 16:05:53 -0800	[thread overview]
Message-ID: <1388707565-16535-22-git-send-email-yinghai@kernel.org> (raw)
In-Reply-To: <1388707565-16535-1-git-send-email-yinghai@kernel.org>

It needs to reserve irq range in allocated_irqs bitmaps
and irq_base will be used to get right irq for ioapic/pin or gsi.

also need to use lock to protect ioapics_mask to avoid racing.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
---
 arch/x86/include/asm/mpspec.h  |  1 +
 arch/x86/kernel/apic/io_apic.c | 74 ++++++++++++++++++++++++++++++++----------
 2 files changed, 57 insertions(+), 18 deletions(-)

diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index 3142a94..59d8465 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -96,6 +96,7 @@ static inline void early_reserve_e820_mpc_new(void) { }
 
 int generic_processor_info(int apicid, int version);
 #ifdef CONFIG_ACPI
+int __mp_register_ioapic(int id, u32 address, u32 gsi_base, bool hot);
 extern void mp_register_ioapic(int id, u32 address, u32 gsi_base);
 extern void mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger,
 				   u32 gsi);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index d43894e..0fdda49 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -94,6 +94,16 @@ static struct ioapic {
 } ioapics[MAX_IO_APICS];
 
 DECLARE_BITMAP(ioapics_mask, MAX_IO_APICS);
+static DEFINE_MUTEX(ioapics_mask_lock);
+
+static void lock_ioapics(void)
+{
+	mutex_lock(&ioapics_mask_lock);
+}
+static void unlock_ioapics(void)
+{
+	mutex_unlock(&ioapics_mask_lock);
+}
 
 #define mpc_ioapic_ver(ioapic_idx)	ioapics[ioapic_idx].mp_config.apicver
 
@@ -3556,7 +3566,7 @@ int io_apic_set_pci_routing(struct device *dev, int irq,
 }
 
 #ifdef CONFIG_X86_32
-static int __init io_apic_get_unique_id(int ioapic, int apic_id)
+static int io_apic_get_unique_id(int ioapic, int apic_id)
 {
 	union IO_APIC_reg_00 reg_00;
 	static physid_mask_t apic_id_map = PHYSID_MASK_NONE;
@@ -3631,7 +3641,7 @@ static int __init io_apic_get_unique_id(int ioapic, int apic_id)
 	return apic_id;
 }
 
-static u8 __init io_apic_unique_id(u8 id)
+static u8 io_apic_unique_id(u8 id)
 {
 	if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
 	    !APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
@@ -3640,7 +3650,7 @@ static u8 __init io_apic_unique_id(u8 id)
 		return id;
 }
 #else
-static u8 __init io_apic_unique_id(u8 id)
+static u8 io_apic_unique_id(u8 id)
 {
 	int i;
 	DECLARE_BITMAP(used, 256);
@@ -3893,25 +3903,28 @@ static __init int bad_ioapic_register(int idx)
 	return 0;
 }
 
-void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
+int __mp_register_ioapic(int id, u32 address, u32 gsi_base, bool hotadd)
 {
 	int idx;
 	int entries;
 	struct mp_ioapic_gsi *gsi_cfg;
+	int ret = -EINVAL;
 
 	if (bad_ioapic(address))
-		return;
+		return ret;
+
+	lock_ioapics();
 
 	/* already registered ? */
 	idx = __mp_find_ioapic(gsi_base);
 	if (idx >= 0)
-		return;
+		goto out;
 
 	idx = find_first_zero_bit(ioapics_mask, MAX_IO_APICS);
 	if (idx >= MAX_IO_APICS) {
 		pr_warn("WARNING: Max # of I/O APICs (%d) exceeded, skipping\n",
 			MAX_IO_APICS);
-		return;
+		goto out;
 	}
 
 	ioapics[idx].mp_config.type = MP_IOAPIC;
@@ -3920,10 +3933,8 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 
 	set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
 
-	if (bad_ioapic_register(idx)) {
-		clear_fixmap(FIX_IO_APIC_BASE_0 + idx);
-		return;
-	}
+	if (bad_ioapic_register(idx))
+		goto clear_out;
 
 	ioapics[idx].mp_config.apicid = io_apic_unique_id(id);
 	ioapics[idx].mp_config.apicver = io_apic_get_version(idx);
@@ -3934,11 +3945,8 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 	 */
 	entries = io_apic_get_redir_entries(idx);
 
-	if (!entries || entries > MP_MAX_IOAPIC_PIN) {
-		clear_fixmap(FIX_IO_APIC_BASE_0 + idx);
-		memset(&ioapics[idx], 0, sizeof(struct ioapic));
-		return;
-	}
+	if (!entries || entries > MP_MAX_IOAPIC_PIN)
+		goto clear_out;
 
 	gsi_cfg = mp_ioapic_gsi_routing(idx);
 	gsi_cfg->gsi_base = gsi_base;
@@ -3949,8 +3957,21 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 	 */
 	ioapics[idx].nr_registers = entries;
 
-	if (gsi_cfg->gsi_end >= gsi_top)
-		gsi_top = gsi_cfg->gsi_end + 1;
+	if (!hotadd) {
+		/*
+		 * irqs will be reserved in arch_early_irq_init()
+		 * don't need to update gsi_top for hot add case
+		 */
+		if (gsi_cfg->gsi_end >= gsi_top)
+			gsi_top = gsi_cfg->gsi_end + 1;
+	} else {
+		int irq = reserve_ioapic_gsi_irq_base(idx);
+
+		if (irq < 0)
+			goto clear_out;
+
+		alloc_ioapic_saved_registers(idx);
+	}
 
 	pr_info("IOAPIC[%d]: apic_id %d, version %d, address 0x%x, GSI %d-%d\n",
 		idx, mpc_ioapic_id(idx),
@@ -3959,6 +3980,23 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 
 	set_bit(idx, ioapics_mask);
 	nr_ioapics = bitmap_weight(ioapics_mask, MAX_IO_APICS);
+
+	unlock_ioapics();
+
+	return 0;
+
+clear_out:
+	clear_fixmap(FIX_IO_APIC_BASE_0 + idx);
+	memset(&ioapics[idx], 0, sizeof(struct ioapic));
+out:
+	unlock_ioapics();
+
+	return ret;
+}
+
+void mp_register_ioapic(int id, u32 address, u32 gsi_base)
+{
+	__mp_register_ioapic(id, address, gsi_base, false);
 }
 
 /* Enable IOAPIC early just for system timer */
-- 
1.8.4


  parent reply	other threads:[~2014-01-03  0:05 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-03  0:05 [PATCH v5 00/33] x86, irq: Support ioapic controller hotplug Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 01/33] genirq: Split __irq_reserve_irqs from irq_alloc_descs Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 02/33] genirq: Add irq_alloc_reserved_desc() Yinghai Lu
2014-01-23  0:03   ` Thomas Gleixner
2014-02-18  0:59     ` Yinghai Lu
2014-02-22 10:08       ` Thomas Gleixner
2014-02-22 17:28         ` Yinghai Lu
2014-02-22 22:05           ` Yinghai Lu
2014-02-22 23:38             ` Thomas Gleixner
2014-02-25  1:31               ` Yinghai Lu
2014-02-21  6:45   ` Jiang Liu
2014-01-03  0:05 ` [PATCH v5 03/33] genirq: Do not free unallocated irq descriptors Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 04/33] x86, irq: Change irq_remap_modify_chip_defaults() to static Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 05/33] x86, irq: Modify irq chip once for irq remapping Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 06/33] x86, irq: Show MSI-X clearly in debug message Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 07/33] x86, irq: Show MSI-X in /proc/interrupt Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 08/33] x86, irq: Make dmar_msi/hpet_msi irq_chip name consistent Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 09/33] ia64, irq: Add dummy create_irq_nr() Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 10/33] iommu, irq: Allocate irq_desc for dmar_msi with local node Yinghai Lu
2014-02-21  7:43   ` Jiang Liu
2014-02-21 23:18     ` Yinghai Lu
2014-02-22  3:14       ` Jiang Liu
2014-02-22  7:44         ` Yinghai Lu
2014-02-22 15:33           ` Jiang Liu
2014-02-22 17:30             ` Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 11/33] x86, irq: Kill create_irq() Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 12/33] x86, irq: Convert irq_2_pin list to generic list Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 13/33] x86, irq: Add alloc_reserved_irq_and_cfg_at() Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 14/33] x86, irq: Move down arch_early_irq_init() Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 15/33] x86, irq: Split out alloc_ioapic_save_registers() Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 16/33] xen, irq: Call irq_alloc_reserved_desc_at() at first Yinghai Lu
2014-01-03 17:50   ` [Xen-devel] " Stefano Stabellini
2014-01-06 20:00     ` Yinghai Lu
2014-01-07 13:30       ` Stefano Stabellini
2014-01-03  0:05 ` [PATCH v5 17/33] x86, irq: Reserve irq range and alloc_reserved for booting path Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 18/33] x86, irq: Add ioapic_gsi_to_irq Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 19/33] x86, irq: Add for_each_ioapic helper Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 20/33] x86, irq: More strict checking about registering ioapic Yinghai Lu
2014-01-03  0:05 ` Yinghai Lu [this message]
2014-01-03  0:05 ` [PATCH v5 22/33] x86, irq: Add mp_unregister_ioapic to handle hot-remove ioapic Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 23/33] x86, ioapic: Find usable ioapic id for 64bit Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 24/33] x86: Move declaration for mp_register_ioapic() Yinghai Lu
2014-01-03 21:24   ` Bjorn Helgaas
2014-01-06 22:30     ` Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 25/33] PCI, x86: Make ioapic hotplug support built-in Yinghai Lu
2014-01-03 22:47   ` Bjorn Helgaas
2014-01-06 22:47     ` Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 26/33] ACPI: Make map_mat_entry handle x2apic entry Yinghai Lu
2014-01-03  0:05 ` [PATCH v5 27/33] ACPI: Move acpi_get_cpuid() to separated file Yinghai Lu
2014-01-03  0:06 ` [PATCH v5 28/33] ACPI, ioapic: Add acpi_get_ioapic_id() Yinghai Lu
2014-01-03  0:06 ` [PATCH v5 29/33] PCI, x86, ACPI: Link acpi ioapic register to ioapic Yinghai Lu
2014-01-03  0:06 ` [PATCH v5 30/33] PCI, x86, ACPI: Enable ioapic hotplug support with acpi host bridge Yinghai Lu
2014-01-03 22:39   ` Bjorn Helgaas
2014-01-03  0:06 ` [PATCH v5 31/33] ACPI, x86/PCI: Move resource_to_addr() to acpi generic Yinghai Lu
2014-01-03  0:06 ` [PATCH v5 32/33] PCI, x86, ACPI: get ioapic address from acpi device Yinghai Lu
2014-01-03  0:06 ` [PATCH v5 33/33] x86, ioapic: Hotadd of IOAPICs described in static MADT Yinghai Lu

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=1388707565-16535-22-git-send-email-yinghai@kernel.org \
    --to=yinghai@kernel.org \
    --cc=bhelgaas@google.com \
    --cc=hpa@zytor.com \
    --cc=joro@8bytes.org \
    --cc=konrad.wilk@oracle.com \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=paul.gortmaker@windriver.com \
    --cc=rjw@sisk.pl \
    --cc=sebastian@breakpoint.cc \
    --cc=tglx@linutronix.de \
    --cc=tony.luck@intel.com \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).