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