enhance IOAPIC core to support hotplug
cover enhance IOAPIC core to support hotplug
This patch set enhances IOAPIC core to support IOAPIC hotplug on x86 platforms. It's based on another patch set "use irqdomain to dynamically allocate IRQ for IOAPIC" at https://lkml.org/lkml/2014/5/27/86
You may pull from
https://github.com/jiangliu/linux.git ioapic/hotplug
Once passed review, we will use Yinghai's patches to glue IOAPIC driver and ACPI PCI root driver to handle hotplug events.
Jiang Liu (4):
x86, irq: refine mp_register_ioapic() to prepare for IOAPIC hotplug x86, irq, ACPI: introduce a rwsem to protect IOAPIC operations from
hotplug
x86, irq, ACPI: implement interface to support ACPI based IOAPIC
hot-addition
x86, irq, ACPI: implement interface to support ACPI based IOAPIC
hot-removal
arch/x86/include/asm/io_apic.h | 5 +- arch/x86/kernel/acpi/boot.c | 44 +++++++-- arch/x86/kernel/apic/io_apic.c | 207 ++++++++++++++++++++++++++++++---------- 3 files changed, 196 insertions(+), 60 deletions(-)
Signature · 1 line
1.7.10.4
RFC PATCH 1/4 x86, irq: refine mp_register_ioapic() to prepare for IOAPIC hotplug
--- arch/x86/include/asm/io_apic.h | 4 +- arch/x86/kernel/apic/io_apic.c | 143 ++++++++++++++++++++++++++-------------- 2 files changed, 94 insertions(+), 53 deletions(-)
arch/x86/include/asm/io_apic.h +2 -2
@@ -181,8 +181,8 @@ extern int mp_find_ioapic_pin(int ioapic, u32 gsi);extern u32 mp_pin_to_gsi (int ioapic,int pin);extern int mp_map_gsi_to_irq (u32 gsi,unsigned int flags);extern void mp_unmap_irq (int irq); -extern void __init mp_register_ioapic (int id,u32 address,u32 gsi_base, -ioapic_create_domain_fn cb,void *arg); +extern int mp_register_ioapic (int id,u32 address,u32 gsi_base, +ioapic_create_domain_fn cb,void *arg);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,
arch/x86/kernel/apic/io_apic.c +92 -51
241 lines not on this page · raw message
Signature · 1 line
1.7.10.4
Re: [RFC Patch V1 1/4] x86, irq: refine mp_register_ioapic() to prepare for IOAPIC hotplug
Quoted 2 lines · Jiang Liu
arch/x86/kernel/apic/io_apic.c +1
-1-static void ioapic_create_irqdomains (void ) +static int ioapic_create_irqdomain (int idx)
...
arch/x86/kernel/apic/io_apic.c io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr) · line 3435
Quoted 2 lines
arch/x86/kernel/apic/io_apic.c +1
-1-static int __init io_apic_get_redir_entries (int ioapic) +static int io_apic_get_redir_entries (int ioapic)
Can you please split the functional changes from the trivial __init removal ones?
Thanks,
tglx
RFC PATCH 2/4 x86, irq, ACPI: introduce a rwsem to protect IOAPIC operations from hotplug
In reply to Jiang LiuWe 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.
--- arch/x86/kernel/acpi/boot.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
arch/x86/kernel/acpi/boot.c +12 -1
@@ -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 ();
Signature · 1 line
1.7.10.4
RFC PATCH 3/4 x86, irq, ACPI: implement interface to support ACPI based IOAPIC hot-addition
In reply to Jiang LiuImplement acpi_register_ioapic() and enhance mp_register_ioapic() to support ACPI based IOAPIC hot-addition.
--- arch/x86/kernel/acpi/boot.c | 18 ++++++++++++++++-- arch/x86/kernel/apic/io_apic.c | 24 +++++++++++++++++++++--- 2 files changed, 37 insertions(+), 5 deletions(-)
arch/x86/kernel/acpi/boot.c +16 -2
@@ -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);
arch/x86/kernel/apic/io_apic.c +21 -3
@@ -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;
Signature · 1 line
1.7.10.4
RFC PATCH 4/4 x86, irq, ACPI: implement interface to support ACPI based IOAPIC hot-removal
In reply to Jiang LiuImplement acpi_unregister_ioapic() to support ACPI based IOAPIC hot-removal. An IOAPIC could only be removed when all its pins are unused.
--- 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(-)
arch/x86/include/asm/io_apic.h +1 -0
@@ -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,
arch/x86/kernel/acpi/boot.c +9 -4
@@ -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)
arch/x86/kernel/apic/io_apic.c +46 -0
58 lines not on this page · raw message
Signature · 1 line
1.7.10.4