linux-pm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC Patch V1 2/4] x86, irq, ACPI: introduce a rwsem to protect IOAPIC operations from hotplug
       [not found] <1401179077-2020-1-git-send-email-jiang.liu@linux.intel.com>
@ 2014-05-27  8:24 ` Jiang Liu
  2014-05-27  8:24 ` [RFC Patch V1 3/4] x86, irq, ACPI: implement interface to support ACPI based IOAPIC hot-addition Jiang Liu
  2014-05-27  8:24 ` [RFC Patch V1 4/4] x86, irq, ACPI: implement interface to support ACPI based IOAPIC hot-removal Jiang Liu
  2 siblings, 0 replies; 3+ messages in thread
From: Jiang Liu @ 2014-05-27  8:24 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, Len Brown, Pavel Machek, x86
  Cc: Jiang Liu, Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck,
	Joerg Roedel, Paul Gortmaker, Greg Kroah-Hartman, linux-kernel,
	linux-pci, linux-acpi, linux-pm

We are going to support ACPI based IOAPIC hotplug, so introduce a rwsem
to protect IOAPIC data structures from IOAPIC hotplug. We choose to
serialize in ACPI instead of in the IOAPIC core because:
1) currently we are only plan to support ACPI based IOAPIC hotplug
2) it's much more clean and easy
3) It does't affect IOAPIC discovered by devicetree, SFI and mppparse.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/kernel/acpi/boot.c |   13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index c8e8fe67bbc8..a1b388e88bcb 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -75,6 +75,8 @@ int acpi_fix_pin2_polarity __initdata;
 static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
 #endif
 
+static DECLARE_RWSEM(acpi_ioapic_rwsem);
+
 #ifndef __HAVE_ARCH_CMPXCHG
 #warning ACPI uses CMPXCHG, i486 and later hardware
 #endif
@@ -495,8 +497,11 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
 
 int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp)
 {
-	int irq = mp_map_gsi_to_irq(gsi, IOAPIC_MAP_ALLOC | IOAPIC_MAP_CHECK);
+	int irq;
 
+	down_read(&acpi_ioapic_rwsem);
+	irq = mp_map_gsi_to_irq(gsi, IOAPIC_MAP_ALLOC | IOAPIC_MAP_CHECK);
+	up_read(&acpi_ioapic_rwsem);
 	if (irq >= 0) {
 		*irqp = irq;
 		return 0;
@@ -537,7 +542,9 @@ static int acpi_register_gsi_ioapic(struct device *dev, u32 gsi,
 	int irq = gsi;
 
 #ifdef CONFIG_X86_IO_APIC
+	down_read(&acpi_ioapic_rwsem);
 	irq = mp_register_gsi(dev, gsi, trigger, polarity);
+	up_read(&acpi_ioapic_rwsem);
 #endif
 
 	return irq;
@@ -546,7 +553,9 @@ static int acpi_register_gsi_ioapic(struct device *dev, u32 gsi,
 static void acpi_unregister_gsi_ioapic(u32 gsi)
 {
 #ifdef CONFIG_X86_IO_APIC
+	down_read(&acpi_ioapic_rwsem);
 	mp_unregister_gsi(gsi);
+	up_read(&acpi_ioapic_rwsem);
 #endif
 }
 
@@ -1198,7 +1207,9 @@ static void __init acpi_process_madt(void)
 			/*
 			 * Parse MADT IO-APIC entries
 			 */
+			down_write(&acpi_ioapic_rwsem);
 			error = acpi_parse_madt_ioapic_entries();
+			up_write(&acpi_ioapic_rwsem);
 			if (!error) {
 				acpi_set_irq_model_ioapic();
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [RFC Patch V1 3/4] x86, irq, ACPI: implement interface to support ACPI based IOAPIC hot-addition
       [not found] <1401179077-2020-1-git-send-email-jiang.liu@linux.intel.com>
  2014-05-27  8:24 ` [RFC Patch V1 2/4] x86, irq, ACPI: introduce a rwsem to protect IOAPIC operations from hotplug Jiang Liu
@ 2014-05-27  8:24 ` Jiang Liu
  2014-05-27  8:24 ` [RFC Patch V1 4/4] x86, irq, ACPI: implement interface to support ACPI based IOAPIC hot-removal Jiang Liu
  2 siblings, 0 replies; 3+ messages in thread
From: Jiang Liu @ 2014-05-27  8:24 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, Len Brown, Pavel Machek, x86, Jiang Liu
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi, Ingo Molnar, linux-pm

Implement acpi_register_ioapic() and enhance mp_register_ioapic()
to support ACPI based IOAPIC hot-addition.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/kernel/acpi/boot.c    |   18 ++++++++++++++++--
 arch/x86/kernel/apic/io_apic.c |   24 +++++++++++++++++++++---
 2 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index a1b388e88bcb..d807e16f8fec 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -655,8 +655,22 @@ EXPORT_SYMBOL(acpi_unmap_lsapic);
 
 int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
 {
-	/* TBD */
-	return -EINVAL;
+	int ret = -ENOSYS;
+#ifdef CONFIG_X86_IO_APIC
+	unsigned long long uid;
+	acpi_status status;
+
+	status = acpi_evaluate_integer(handle, METHOD_NAME__UID, NULL, &uid);
+	if (ACPI_FAILURE(status))
+		uid = 0;
+
+	down_write(&acpi_ioapic_rwsem);
+	ret  = mp_register_ioapic((int)uid, phys_addr, gsi_base,
+				  acpi_create_irqdomain, NULL);
+	up_write(&acpi_ioapic_rwsem);
+#endif
+
+	return ret;
 }
 
 EXPORT_SYMBOL(acpi_register_ioapic);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index f70fa239f34b..4bddff760ff4 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3802,7 +3802,13 @@ static int bad_ioapic_register(int idx)
 
 static int find_free_ioapic_entry(void)
 {
-	return nr_ioapics;
+	int idx;
+
+	for (idx = 0; idx < MAX_IO_APICS; idx++)
+		if (ioapics[idx].nr_registers == 0)
+			return idx;
+
+	return MAX_IO_APICS;
 }
 
 int mp_register_ioapic(int id, u32 address, u32 gsi_base,
@@ -3818,8 +3824,15 @@ int mp_register_ioapic(int id, u32 address, u32 gsi_base,
 	}
 	for_each_ioapic(ioapic)
 		if (ioapics[ioapic].mp_config.apicaddr == address) {
-			pr_warn("address 0x%x conflicts with IOAPIC%d\n",
-				address, ioapic);
+			/*
+			 * IOAPIC unit may also be visible in PCI scope.
+			 * When ioapic PCI driver's probe() is called,
+			 * the IOAPIC unit may have already been initialized
+			 * at boot time.
+			 */
+			if (!ioapic_initialized)
+				pr_warn("address 0x%x conflicts with IOAPIC%d\n",
+					address, ioapic);
 			return -EEXIST;
 		}
 
@@ -3875,6 +3888,11 @@ int mp_register_ioapic(int id, u32 address, u32 gsi_base,
 	if (nr_ioapics <= idx)
 		nr_ioapics = idx + 1;
 
+	if (ioapic_initialized && ioapic_create_irqdomain(idx)) {
+		clear_fixmap(FIX_IO_APIC_BASE_0 + idx);
+		return -ENOMEM;
+	}
+
 	/* Set nr_registers to mark entry present */
 	ioapics[idx].nr_registers = entries;
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [RFC Patch V1 4/4] x86, irq, ACPI: implement interface to support ACPI based IOAPIC hot-removal
       [not found] <1401179077-2020-1-git-send-email-jiang.liu@linux.intel.com>
  2014-05-27  8:24 ` [RFC Patch V1 2/4] x86, irq, ACPI: introduce a rwsem to protect IOAPIC operations from hotplug Jiang Liu
  2014-05-27  8:24 ` [RFC Patch V1 3/4] x86, irq, ACPI: implement interface to support ACPI based IOAPIC hot-addition Jiang Liu
@ 2014-05-27  8:24 ` Jiang Liu
  2 siblings, 0 replies; 3+ messages in thread
From: Jiang Liu @ 2014-05-27  8:24 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Thomas Gleixner, Grant Likely,
	Ingo Molnar, H. Peter Anvin, Rafael J. Wysocki, Bjorn Helgaas,
	Randy Dunlap, Yinghai Lu, x86, Len Brown, Pavel Machek, Jiang Liu
  Cc: Konrad Rzeszutek Wilk, Andrew Morton, Tony Luck, Joerg Roedel,
	Paul Gortmaker, Greg Kroah-Hartman, linux-kernel, linux-pci,
	linux-acpi, Ingo Molnar, linux-pm

Implement acpi_unregister_ioapic() to support ACPI based IOAPIC hot-removal.
An IOAPIC could only be removed when all its pins are unused.

Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
---
 arch/x86/include/asm/io_apic.h |    1 +
 arch/x86/kernel/acpi/boot.c    |   13 ++++++++----
 arch/x86/kernel/apic/io_apic.c |   46 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 64379c285435..256ec8d9050c 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -183,6 +183,7 @@ extern int mp_map_gsi_to_irq(u32 gsi, unsigned int flags);
 extern void mp_unmap_irq(int irq);
 extern int mp_register_ioapic(int id, u32 address, u32 gsi_base,
 			      ioapic_create_domain_fn cb, void *arg);
+extern int mp_unregister_ioapic(u32 gsi_base);
 extern struct irq_domain *mp_irqdomain_create(int ioapic,
 		struct device_node *np, const struct irq_domain_ops *ops);
 extern int mp_irqdomain_map(struct irq_domain *domain, unsigned int virq,
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index d807e16f8fec..c17cc0510040 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -672,15 +672,20 @@ int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base)
 
 	return ret;
 }
-
 EXPORT_SYMBOL(acpi_register_ioapic);
 
 int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base)
 {
-	/* TBD */
-	return -EINVAL;
-}
+	int ret = -ENOSYS;
+
+#ifdef CONFIG_X86_IO_APIC
+	down_write(&acpi_ioapic_rwsem);
+	ret  = mp_unregister_ioapic(gsi_base);
+	up_write(&acpi_ioapic_rwsem);
+#endif
 
+	return ret;
+}
 EXPORT_SYMBOL(acpi_unregister_ioapic);
 
 static int __init acpi_parse_sbf(struct acpi_table_header *table)
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 4bddff760ff4..4343247d15b1 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2949,6 +2949,18 @@ static int ioapic_create_irqdomain(int idx)
 	return 0;
 }
 
+static void ioapic_destroy_irqdomain(int idx)
+{
+	if (ioapics[idx].irqdomain) {
+		irq_domain_remove(ioapics[idx].irqdomain);
+		ioapics[idx].irqdomain = NULL;
+	}
+	if (ioapics[idx].pin_info) {
+		kfree(ioapics[idx].pin_info);
+		ioapics[idx].pin_info = NULL;
+	}
+}
+
 static void ioapic_create_irqdomains(void)
 {
 	int idx;
@@ -3904,6 +3916,40 @@ int mp_register_ioapic(int id, u32 address, u32 gsi_base,
 	return 0;
 }
 
+int mp_unregister_ioapic(u32 gsi_base)
+{
+	int ioapic, pin;
+	int found = 0;
+	struct mp_pin_info *pin_info;
+
+	for_each_ioapic(ioapic)
+		if (ioapics[ioapic].gsi_config.gsi_base == gsi_base) {
+			found = 1;
+			break;
+		}
+	if (!found) {
+		pr_warn("can't find IOAPIC for GSI %d\n", gsi_base);
+		return -ENODEV;
+	}
+
+	for_each_pin(ioapic, pin) {
+		pin_info = mp_pin_info(ioapic, pin);
+		if (pin_info->count) {
+			pr_warn("pin%d on IOAPIC%d is still in use.\n",
+				pin, ioapic);
+			return -EBUSY;
+		}
+	}
+
+	/* Mark entry not present */
+	ioapics[ioapic].nr_registers  = 0;
+	ioapic_destroy_irqdomain(ioapic);
+	clear_fixmap(FIX_IO_APIC_BASE_0 + ioapic);
+	memset(&ioapics[ioapic], 0, sizeof(ioapics[ioapic]));
+
+	return 0;
+}
+
 struct irq_domain *mp_irqdomain_create(int ioapic, struct device_node *np,
 				       const struct irq_domain_ops *ops)
 {
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2014-05-27  8:24 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <1401179077-2020-1-git-send-email-jiang.liu@linux.intel.com>
2014-05-27  8:24 ` [RFC Patch V1 2/4] x86, irq, ACPI: introduce a rwsem to protect IOAPIC operations from hotplug Jiang Liu
2014-05-27  8:24 ` [RFC Patch V1 3/4] x86, irq, ACPI: implement interface to support ACPI based IOAPIC hot-addition Jiang Liu
2014-05-27  8:24 ` [RFC Patch V1 4/4] x86, irq, ACPI: implement interface to support ACPI based IOAPIC hot-removal Jiang Liu

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).