Prepare for enabling hierarchy irqdomain on x86
v2 cover Prepare for enabling hierarchy irqdomain on x86
We plan to restructure x86 interrupt code based on hierarchy irqdomain, that is to build irqdomains for CPU vector, interrupt remapping unit, IOAPIC, MSI and HPET etc and orgonize those irqdomains in hierarchy mode.
This patchset is preparation work to enable hierarchy irqdomain on x86 platforms. It splits out code for vector management, MSI, HTIRQ from ioapic.c into separate files. It also introduces some helper functions to access irq_cfg, which will ease transition to hierarchy irqdomain later.
It's based on patchset at:
https://lkml.org/lkml/2014/9/24/206
And you may access it at:
https://github.com/jiangliu/linux.git irqdomain/p1v2
V1->V2:
1) fix a building failure found by 0day test bed
2) rebase to latest upstream kernel
Jiang Liu (17):
x86, irq, ACPI: Fix building warning of unused code x86, irq: Kill fourth parameter of IO_APIC_get_PCI_irq_vector() x86, irq: Refine hw_irq.h to prepare for irqdomain support x86, irq: Rename local APIC related functions in io_apic.c as
apic_xxx()
x86, irq: Protect __clear_irq_vector() with vector_lock x86, irq: Introduce helpers to access struct irq_cfg x86, irq: Move local APIC related code from io_apic.c into vector.c x86, irq: Replace printk(KERN_LVL) with pr_lvl() utilities x86, irq: Move PCI MSI related code from io_apic.c into msi.c x86, irq: Move HT IRQ related code from io_apic.c into htirq.c x86, irq: Move IOAPIC related declarations from hw_irq.h into
io_apic.h
x86, irq: Move IRQ initialization routines from io_apic.c into
vector.c
x86, irq: Make MSI and HT_IRQ indepenent of X86_IO_APIC x86, irq: Use helpers to access irq_cfg data structure associated
with IRQ
x86: irq_remapping: Use helpers to access irq_cfg data structure
associated with IRQ
iommu/vt-d: Use helpers to access irq_cfg data structure associated
with IRQ
iommu/amd: Use helpers to access irq_cfg data structure associated
with IRQ
Yinghai Lu (1):
x86, irq: Convert irq_2_pin list to generic list
arch/x86/Kconfig | 6 +- arch/x86/include/asm/hw_irq.h | 76 +-- arch/x86/include/asm/io_apic.h | 29 +- arch/x86/include/asm/pci.h | 3 + arch/x86/kernel/acpi/boot.c | 2 + arch/x86/kernel/apic/Makefile | 4 +- arch/x86/kernel/apic/htirq.c | 106 ++++ arch/x86/kernel/apic/io_apic.c | 1096 ++--------------------------------- arch/x86/kernel/apic/msi.c | 283 +++++++++ arch/x86/kernel/apic/vector.c | 716 +++++++++++++++++++++++ arch/x86/kernel/crash.c | 1 + arch/x86/kernel/irqinit.c | 22 - arch/x86/kernel/machine_kexec_32.c | 1 + arch/x86/kernel/machine_kexec_64.c | 1 + arch/x86/kernel/reboot.c | 1 + arch/x86/pci/irq.c | 6 +- arch/x86/platform/uv/uv_irq.c | 6 +- drivers/iommu/amd_iommu.c | 14 +- drivers/iommu/intel_irq_remapping.c | 10 +- drivers/iommu/irq_remapping.c | 6 +- drivers/pci/Kconfig | 2 +- drivers/pci/hotplug/ibmphp_core.c | 5 +- 22 files changed, 1230 insertions(+), 1166 deletions(-) create mode 100644 arch/x86/kernel/apic/htirq.c create mode 100644 arch/x86/kernel/apic/msi.c create mode 100644 arch/x86/kernel/apic/vector.c
Signature · 1 line
1.7.10.4
PATCH v2 1/18 x86, irq, ACPI: Fix building warning of unused code
Fix building warning when CONFIG_X86_LOCAL_APIC is disabled. arch/x86/kernel/acpi/boot.c:699:20: warning: ‘acpi_set_irq_model_ioapic’ defined but not used [-Wunused-function]
--- arch/x86/kernel/acpi/boot.c | 2 ++ 1 file changed, 2 insertions(+)
arch/x86/kernel/acpi/boot.c +2 -0
@@ -706,6 +706,7 @@ void acpi_unregister_gsi(u32 gsi) }EXPORT_SYMBOL_GPL (acpi_unregister_gsi); +#ifdef CONFIG_X86_LOCAL_APIC static void __init acpi_set_irq_model_ioapic (void ) { acpi_irq_model =ACPI_IRQ_MODEL_IOAPIC ;
@@ -713,6 +714,7 @@ static void __init acpi_set_irq_model_ioapic(void) __acpi_unregister_gsi = acpi_unregister_gsi_ioapic; acpi_ioapic = 1; } +#endif /* * ACPI based hotplug support for CPU
Signature · 1 line
1.7.10.4
PATCH v2 2/18 x86, irq: Kill fourth parameter of IO_APIC_get_PCI_irq_vector()
In reply to Jiang LiuNow the fourth parameter of IO_APIC_get_PCI_irq_vector() is useless, so kill it. Assume it's only used by ibmphp PCI hotplug driver though IO_APIC_get_PCI_irq_vector() has been exported,
--- arch/x86/include/asm/hw_irq.h | 2 +- arch/x86/kernel/apic/io_apic.c | 13 +++---------- arch/x86/pci/irq.c | 6 ++---- drivers/pci/hotplug/ibmphp_core.c | 5 +---- 4 files changed, 7 insertions(+), 19 deletions(-)
arch/x86/include/asm/hw_irq.h +1 -1
@@ -158,7 +158,7 @@ extern void send_cleanup_vector(struct irq_cfg *);struct irq_data ;int __ioapic_set_affinity (struct irq_data *,const struct cpumask *,unsigned int *dest_id); -extern int IO_APIC_get_PCI_irq_vector (int bus,int devfn,int pin,struct io_apic_irq_attr *irq_attr); +extern int IO_APIC_get_PCI_irq_vector (int bus,int devfn,int pin);extern void setup_ioapic_dest (void );extern void enable_IO_APIC (void );
arch/x86/kernel/apic/io_apic.c +3 -10
@@ -1179,8 +1179,7 @@ void mp_unmap_irq(int irq)* Find a specific PCI IRQ entry. * Not an __init, possibly needed by modules */ -int IO_APIC_get_PCI_irq_vector (int bus,int slot,int pin, -struct io_apic_irq_attr *irq_attr) +int IO_APIC_get_PCI_irq_vector (int bus,int slot,int pin) {int irq, i, best_ioapic =-1 , best_idx =-1 ;
@@ -1234,14 +1233,8 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,return -1 ; out: - irq =pin_2_irq (best_idx, best_ioapic, mp_irqs[best_idx].dstirq, -IOAPIC_MAP_ALLOC ); -if (irq >0 ) -set_io_apic_irq_attr (irq_attr, best_ioapic, - mp_irqs[best_idx].dstirq, -irq_trigger (best_idx), -irq_polarity (best_idx)); -return irq; +return pin_2_irq (best_idx, best_ioapic, mp_irqs[best_idx].dstirq, +IOAPIC_MAP_ALLOC ); }EXPORT_SYMBOL (IO_APIC_get_PCI_irq_vector);
arch/x86/pci/irq.c +2 -4
@@ -1200,14 +1200,12 @@ static int pirq_enable_irq(struct pci_dev *dev)#ifdef CONFIG_X86_IO_APIC struct pci_dev *temp_dev;int irq; -struct io_apic_irq_attr irq_attr;if (dev->irq_managed && dev->irq >0 )return 0 ; irq =IO_APIC_get_PCI_irq_vector (dev->bus->number, -PCI_SLOT (dev->devfn), - pin -1 , &irq_attr); +PCI_SLOT (dev->devfn), pin -1 );/* * Busses behind bridges are typically not listed in the MP-table. * In this case we have to look up the IRQ based on the parent bus,
@@ -1221,7 +1219,7 @@ static int pirq_enable_irq(struct pci_dev *dev) pin =pci_swizzle_interrupt_pin (dev, pin); irq =IO_APIC_get_PCI_irq_vector (bridge->bus->number,PCI_SLOT (bridge->devfn), - pin -1 , &irq_attr); + pin -1 );if (irq >=0 ) dev_warn(&dev->dev, "using bridge %s " "INT %c to get IRQ %d\n",
drivers/pci/hotplug/ibmphp_core.c +1 -4
@@ -155,13 +155,10 @@ int ibmphp_init_devno(struct slot **cur_slot)for (loop =0 ; loop < len; loop++) {if ((*cur_slot)->number == rtable->slots[loop].slot && (*cur_slot)->bus == rtable->slots[loop].bus) { -struct io_apic_irq_attr irq_attr; - (*cur_slot)->device =PCI_SLOT (rtable->slots[loop].devfn);for (i =0 ; i <4 ; i++) (*cur_slot)->irq[i] =IO_APIC_get_PCI_irq_vector ((int ) (*cur_slot)->bus, - (int ) (*cur_slot)->device, i, - &irq_attr); + (int ) (*cur_slot)->device, i);debug ("(*cur_slot)->irq[0] = %x\n" , (*cur_slot)->irq[0 ]);
Signature · 1 line
1.7.10.4
PATCH v2 3/18 x86, irq: Convert irq_2_pin list to generic list
In reply to Jiang LiuFrom: Yinghai Lu <[email protected]>
Use generic list to replace private list implementation so we could use generic helper functions to operate it.
--- arch/x86/include/asm/hw_irq.h | 2 +- arch/x86/kernel/apic/io_apic.c | 28 +++++++++++----------------- 2 files changed, 12 insertions(+), 18 deletions(-)
arch/x86/include/asm/hw_irq.h +1 -1
@@ -138,7 +138,7 @@ struct irq_2_irte {* Most irqs are mapped 1:1 with pins. */ struct irq_cfg { -struct irq_pin_list *irq_2_pin; +struct list_head irq_2_pin;cpumask_var_t domain;cpumask_var_t old_domain;u8 vector;
arch/x86/kernel/apic/io_apic.c +11 -17
@@ -74,7 +74,7 @@ for_each_pin((idx), (pin))#define for_each_irq_pin (entry, head) \ - for (entry = head; entry; entry = entry->next) + list_for_each_entry(entry, &head, list)/* * Is the SiS APIC rmw bug present ?
@@ -229,8 +229,8 @@ void mp_save_irq(struct mpc_intsrc *m) }struct irq_pin_list { +struct list_head list;int apic, pin; -struct irq_pin_list *next; };static struct irq_pin_list *alloc_irq_pin_list (int node)
@@ -297,6 +297,7 @@ static struct irq_cfg *alloc_irq_cfg(unsigned int irq, int node) goto out_cfg;if (!zalloc_cpumask_var_node (&cfg->old_domain,GFP_KERNEL , node)) goto out_domain; +INIT_LIST_HEAD (&cfg->irq_2_pin);return cfg; out_domain:free_cpumask_var (cfg->domain);
@@ -460,15 +461,12 @@ static void ioapic_mask_entry(int apic, int pin)*/ static int __add_pin_to_irq_node (struct irq_cfg *cfg,int node,int apic,int pin) { -struct irq_pin_list **last, *entry; +struct irq_pin_list *entry;/* don't allow duplicates */ - last = &cfg->irq_2_pin; -for_each_irq_pin (entry, cfg->irq_2_pin) { +for_each_irq_pin (entry, cfg->irq_2_pin)if (entry->apic == apic && entry->pin == pin)return 0 ; - last = &entry->next; - } entry =alloc_irq_pin_list (node);if (!entry) {
@@ -479,22 +477,19 @@ static int __add_pin_to_irq_node(struct irq_cfg *cfg, int node, int apic, int pi entry->apic = apic; entry->pin = pin; - *last = entry; +list_add_tail (&entry->list, &cfg->irq_2_pin);return 0 ; }static void __remove_pin_from_irq (struct irq_cfg *cfg,int apic,int pin) { -struct irq_pin_list **last, *entry; +struct irq_pin_list *tmp, *entry; - last = &cfg->irq_2_pin; -for_each_irq_pin (entry, cfg->irq_2_pin) +list_for_each_entry_safe (entry, tmp, &cfg->irq_2_pin, list)if (entry->apic == apic && entry->pin == pin) { - *last = entry->next; +list_del (&entry->list);kfree (entry);return ; - }else { - last = &entry->next; } }
@@ -1739,8 +1734,7 @@ __apicdebuginit(void) print_IO_APICs(void) cfg =irq_cfg (irq);if (!cfg)continue ; - entry = cfg->irq_2_pin; -if (!entry) +if (list_empty (&cfg->irq_2_pin))continue ;printk (KERN_DEBUG "IRQ%d " , irq);for_each_irq_pin (entry, cfg->irq_2_pin)
@@ -4063,7 +4057,7 @@ void mp_irqdomain_unmap(struct irq_domain *domain, unsigned int virq)ioapic_mask_entry (ioapic, pin);__remove_pin_from_irq (cfg, ioapic, pin); -WARN_ON (cfg->irq_2_pin !=NULL ); +WARN_ON (!list_empty (&cfg->irq_2_pin));arch_teardown_hwirq (virq); }
Signature · 1 line
1.7.10.4
PATCH v2 4/18 x86, irq: Refine hw_irq.h to prepare for irqdomain support
In reply to Jiang LiuRefine hw_irq.h to prepare for irqdomain support by:
1) guarding common APIC related interfaces with CONFIG_X86_LOCAL_APIC
2) guarding interrupt remapping related interfaces with CONFIG_IRQ_REMAP
3) guarding IOAPIC related interfaces with CONFIG_X86_IO_APIC
There should be no functional changes.
--- arch/x86/include/asm/hw_irq.h | 94 ++++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 43 deletions(-)
arch/x86/include/asm/hw_irq.h +51 -43
@@ -94,30 +94,7 @@ extern void trace_call_function_single_interrupt(void);#define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi#endif /* CONFIG_TRACING */ -/* IOAPIC */ -#define IO_APIC_IRQ (x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs)) -extern unsigned long io_apic_irqs; - -extern void setup_IO_APIC (void ); -extern void disable_IO_APIC (void ); - -struct io_apic_irq_attr { -int ioapic; -int ioapic_pin; -int trigger; -int polarity; -}; - -static inline void set_io_apic_irq_attr (struct io_apic_irq_attr *irq_attr, -int ioapic,int ioapic_pin, -int trigger,int polarity) -{ - irq_attr->ioapic = ioapic; - irq_attr->ioapic_pin = ioapic_pin; - irq_attr->trigger = trigger; - irq_attr->polarity = polarity; -} - +#ifdef CONFIG_IRQ_REMAP /* Intel specific interrupt remapping information */ struct irq_2_iommu { struct intel_iommu *iommu;
@@ -131,14 +108,10 @@ struct irq_2_irte {u16 devid;/* Device ID for IRTE table */ u16 index;/* Index into IRTE table*/ }; +#endif /* CONFIG_IRQ_REMAP */ -/* -* This is performance-critical, we want to do it O(1) -* -* Most irqs are mapped 1:1 with pins. -*/ +#ifdef CONFIG_X86_LOCAL_APIC struct irq_cfg { -struct list_head irq_2_pin; cpumask_var_t domain; cpumask_var_t old_domain; u8 vector;
@@ -150,18 +123,64 @@ struct irq_cfg {struct irq_2_irte irq_2_irte; };#endif +union { +#ifdef CONFIG_X86_IO_APIC +struct { +struct list_head irq_2_pin; + }; +#endif + }; }; +extern void setup_vector_irq (int cpu);extern int assign_irq_vector (int ,struct irq_cfg *,const struct cpumask *);extern void send_cleanup_vector (struct irq_cfg *);struct irq_data ;int __ioapic_set_affinity (struct irq_data *,const struct cpumask *,unsigned int *dest_id); -extern int IO_APIC_get_PCI_irq_vector (int bus,int devfn,int pin); -extern void setup_ioapic_dest (void ); +#endif /* CONFIG_X86_LOCAL_APIC */ + +#ifdef CONFIG_X86_IO_APIC +extern void lock_vector_lock (void ); +extern void unlock_vector_lock (void ); +extern void __setup_vector_irq (int cpu); +#else +static inline void lock_vector_lock (void ) {} +static inline void unlock_vector_lock (void ) {} +static inline void __setup_vector_irq (int cpu) {} +#endif + +/* IOAPIC */ +#ifdef CONFIG_X86_IO_APIC +struct io_apic_irq_attr { +int ioapic; +int ioapic_pin; +int trigger; +int polarity; +}; + +static inline void set_io_apic_irq_attr (struct io_apic_irq_attr *irq_attr, +int ioapic,int ioapic_pin, +int trigger,int polarity) +{ + irq_attr->ioapic = ioapic; + irq_attr->ioapic_pin = ioapic_pin; + irq_attr->trigger = trigger; + irq_attr->polarity = polarity; +} +extern void setup_IO_APIC (void );extern void enable_IO_APIC (void ); +extern void disable_IO_APIC (void ); +extern void setup_ioapic_dest (void ); +extern int IO_APIC_get_PCI_irq_vector (int bus,int devfn,int pin); + +extern unsigned long io_apic_irqs; +#define IO_APIC_IRQ (x) (((x) >= NR_IRQS_LEGACY) || ((1 << (x)) & io_apic_irqs)) +#else /* CONFIG_X86_IO_APIC */ +#define IO_APIC_IRQ (x) 0 +#endif /* CONFIG_X86_IO_APIC */ /* Statistics */ extern atomic_t irq_err_count;
@@ -195,17 +214,6 @@ extern void (*__initconst interrupt[NR_VECTORS-FIRST_EXTERNAL_VECTOR])(void);typedef int vector_irq_t [NR_VECTORS ];DECLARE_PER_CPU (vector_irq_t, vector_irq); -extern void setup_vector_irq (int cpu); - -#ifdef CONFIG_X86_IO_APIC -extern void lock_vector_lock (void ); -extern void unlock_vector_lock (void ); -extern void __setup_vector_irq (int cpu); -#else -static inline void lock_vector_lock (void ) {} -static inline void unlock_vector_lock (void ) {} -static inline void __setup_vector_irq (int cpu) {} -#endif #endif /* !ASSEMBLY_ */
Signature · 1 line
1.7.10.4
PATCH v2 5/18 x86, irq: Rename local APIC related functions in io_apic.c as apic_xxx()
In reply to Jiang LiuRename local APIC related functions in io_apic.c as apic_xxx() instead of ioapic_xxx(), later they will be moved into separate file.
--- arch/x86/include/asm/hw_irq.h | 4 ++-- arch/x86/kernel/apic/io_apic.c | 42 ++++++++++++++++++++-------------------- arch/x86/platform/uv/uv_irq.c | 2 +- 3 files changed, 24 insertions(+), 24 deletions(-)
arch/x86/include/asm/hw_irq.h +2 -2
@@ -137,8 +137,8 @@ extern int assign_irq_vector(int, struct irq_cfg *, const struct cpumask *);extern void send_cleanup_vector (struct irq_cfg *);struct irq_data ; -int __ioapic_set_affinity (struct irq_data *,const struct cpumask *, -unsigned int *dest_id); +int apic_set_affinity (struct irq_data *,const struct cpumask *, +unsigned int *dest_id);#endif /* CONFIG_X86_LOCAL_APIC */ #ifdef CONFIG_X86_IO_APIC
arch/x86/kernel/apic/io_apic.c +21 -21
131 lines not on this page · raw message
arch/x86/platform/uv/uv_irq.c +1 -1
@@ -204,7 +204,7 @@ uv_set_irq_affinity(struct irq_data *data, const struct cpumask *mask,struct uv_IO_APIC_route_entry *entry;int mmr_pnode; -if (__ioapic_set_affinity (data, mask, &dest)) +if (apic_set_affinity (data, mask, &dest))return -1 ; mmr_value =0 ;
Signature · 1 line
1.7.10.4
PATCH v2 6/18 x86, irq: Protect __clear_irq_vector() with vector_lock
In reply to Jiang LiuFunction __clear_irq_vector() accesses vector related data structure, so protect it with vector_lock. Also rename it as clear_irq_vector().
--- arch/x86/kernel/apic/io_apic.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-)
arch/x86/kernel/apic/io_apic.c +11 -8
@@ -1349,10 +1349,12 @@ int assign_irq_vector(int irq, struct irq_cfg *cfg, const struct cpumask *mask)return err; } -static void __clear_irq_vector (int irq,struct irq_cfg *cfg) +static void clear_irq_vector (int irq,struct irq_cfg *cfg) {int cpu, vector; +unsigned long flags; +raw_spin_lock_irqsave (&vector_lock, flags);BUG_ON (!cfg->vector); vector = cfg->vector;
@@ -1362,8 +1364,11 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg) cfg->vector =0 ;cpumask_clear (cfg->domain); -if (likely (!cfg->move_in_progress)) +if (likely (!cfg->move_in_progress)) { +raw_spin_unlock_irqrestore (&vector_lock, flags);return ; + } +for_each_cpu_and (cpu, cfg->old_domain, cpu_online_mask) {for (vector =FIRST_EXTERNAL_VECTOR ; vector <NR_VECTORS ; vector++) {if (per_cpu (vector_irq, cpu)[vector] != irq)
@@ -1373,6 +1378,7 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg) } } cfg->move_in_progress =0 ; +raw_spin_unlock_irqrestore (&vector_lock, flags); }void __setup_vector_irq (int cpu)
@@ -1499,7 +1505,7 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg, &dest)) {pr_warn ("Failed to obtain apicid for ioapic %d, pin %d\n" ,mpc_ioapic_id (attr->ioapic), attr->ioapic_pin); -__clear_irq_vector (irq, cfg); +clear_irq_vector (irq, cfg);return ; }
@@ -1513,7 +1519,7 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg,if (x86_io_apic_ops.setup_entry (irq, &entry, dest, cfg->vector, attr)) {pr_warn ("Failed to setup ioapic entry for ioapic %d, pin %d\n" ,mpc_ioapic_id (attr->ioapic), attr->ioapic_pin); -__clear_irq_vector (irq, cfg); +clear_irq_vector (irq, cfg);return ; }
@@ -3082,12 +3088,9 @@ int arch_setup_hwirq(unsigned int irq, int node)void arch_teardown_hwirq (unsigned int irq) {struct irq_cfg *cfg =irq_cfg (irq); -unsigned long flags;free_remapped_irq (irq); -raw_spin_lock_irqsave (&vector_lock, flags); -__clear_irq_vector (irq, cfg); -raw_spin_unlock_irqrestore (&vector_lock, flags); +clear_irq_vector (irq, cfg);free_irq_cfg (irq, cfg); }
Signature · 1 line
1.7.10.4
PATCH v2 7/18 x86, irq: Introduce helpers to access struct irq_cfg
In reply to Jiang LiuChange irq_cfg() from static to extern, also introduce helper function irqd_cfg(). Later we could rewrite these two helpers when enabling hierarchy irqdomain.
--- arch/x86/include/asm/hw_irq.h | 2 ++ arch/x86/kernel/apic/io_apic.c | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-)
arch/x86/include/asm/hw_irq.h +2 -0
@@ -132,6 +132,8 @@ struct irq_cfg { }; }; +extern struct irq_cfg *irq_cfg (unsigned int irq); +extern struct irq_cfg *irqd_cfg (struct irq_data *irq_data);extern void setup_vector_irq (int cpu);extern int assign_irq_vector (int ,struct irq_cfg *,const struct cpumask *);extern void send_cleanup_vector (struct irq_cfg *);
arch/x86/kernel/apic/io_apic.c +6 -1
@@ -281,11 +281,16 @@ int __init arch_early_irq_init(void)return 0 ; } -static inline struct irq_cfg *irq_cfg (unsigned int irq) +struct irq_cfg *irq_cfg (unsigned int irq) {return irq_get_chip_data (irq); } +struct irq_cfg *irqd_cfg (struct irq_data *irq_data) +{ +return irq_data->chip_data; +} +static struct irq_cfg *alloc_irq_cfg (unsigned int irq,int node) {struct irq_cfg *cfg;
Signature · 1 line
1.7.10.4
PATCH v2 8/18 x86, irq: Move local APIC related code from io_apic.c into vector.c
In reply to Jiang LiuCreate arch/x86/kernel/apic/vector.c to host local APIC related code, prepare for making MSI/HT_IRQ independent of IOAPIC.
--- arch/x86/Kconfig | 2 +- arch/x86/include/asm/hw_irq.h | 29 +- arch/x86/kernel/apic/Makefile | 2 +- arch/x86/kernel/apic/io_apic.c | 649 +------------------------------------ arch/x86/kernel/apic/vector.c | 689 ++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/irqinit.c | 22 -- 6 files changed, 709 insertions(+), 684 deletions(-) create mode 100644 arch/x86/kernel/apic/vector.c
arch/x86/Kconfig +1 -1
@@ -837,11 +837,11 @@ config X86_UP_IOAPIC config X86_LOCAL_APIC def_bool y depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC || PCI_MSI + select GENERIC_IRQ_LEGACY_ALLOC_HWIRQ config X86_IO_APIC def_bool y depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_IOAPIC || PCI_MSI - select GENERIC_IRQ_LEGACY_ALLOC_HWIRQ select IRQ_DOMAIN config X86_REROUTE_FOR_BROKEN_BOOT_IRQS
arch/x86/include/asm/hw_irq.h +16 -13
@@ -111,6 +111,8 @@ struct irq_2_irte {#endif /* CONFIG_IRQ_REMAP */ #ifdef CONFIG_X86_LOCAL_APIC +struct irq_data; + struct irq_cfg { cpumask_var_t domain; cpumask_var_t old_domain;
@@ -134,24 +136,23 @@ struct irq_cfg {extern struct irq_cfg *irq_cfg (unsigned int irq);extern struct irq_cfg *irqd_cfg (struct irq_data *irq_data); -extern void setup_vector_irq (int cpu); +extern struct irq_cfg *alloc_irq_and_cfg_at (unsigned int at,int node); +extern void lock_vector_lock (void ); +extern void unlock_vector_lock (void );extern int assign_irq_vector (int ,struct irq_cfg *,const struct cpumask *); +extern void clear_irq_vector (int irq,struct irq_cfg *cfg); +extern void setup_vector_irq (int cpu);extern void send_cleanup_vector (struct irq_cfg *); +extern void irq_complete_move (struct irq_cfg *cfg); -struct irq_data ; -int apic_set_affinity (struct irq_data *,const struct cpumask *, -unsigned int *dest_id); -#endif /* CONFIG_X86_LOCAL_APIC */ - -#ifdef CONFIG_X86_IO_APIC -extern void lock_vector_lock (void ); -extern void unlock_vector_lock (void ); -extern void __setup_vector_irq (int cpu); -#else +extern int apic_retrigger_irq (struct irq_data *data); +extern void apic_ack_edge (struct irq_data *data); +extern int apic_set_affinity (struct irq_data *data,const struct cpumask *mask, +unsigned int *dest_id); +#else /* CONFIG_X86_LOCAL_APIC */ static inline void lock_vector_lock (void ) {}static inline void unlock_vector_lock (void ) {} -static inline void __setup_vector_irq (int cpu) {} -#endif +#endif /* CONFIG_X86_LOCAL_APIC */ /* IOAPIC */ #ifdef CONFIG_X86_IO_APIC
@@ -177,11 +178,13 @@ extern void enable_IO_APIC(void);extern void disable_IO_APIC (void );extern void setup_ioapic_dest (void );extern int IO_APIC_get_PCI_irq_vector (int bus,int devfn,int pin); +extern void print_IO_APICs (void );extern unsigned long io_apic_irqs;#define IO_APIC_IRQ (x) (((x) >= NR_IRQS_LEGACY) || ((1 << (x)) & io_apic_irqs))#else /* CONFIG_X86_IO_APIC */ #define IO_APIC_IRQ (x) 0 +static inline void print_IO_APICs (void ) {}#endif /* CONFIG_X86_IO_APIC */ /* Statistics */
arch/x86/kernel/apic/Makefile +1 -1
@@ -2,7 +2,7 @@ # Makefile for local APIC drivers and for the IO-APIC code # -obj-$(CONFIG_X86_LOCAL_APIC) += apic.o apic_noop.o ipi.o +obj-$(CONFIG_X86_LOCAL_APIC) += apic.o apic_noop.o ipi.o vector.o obj-y += hw_nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o
arch/x86/kernel/apic/io_apic.c +2 -647
727 lines not on this page · raw message
arch/x86/kernel/apic/vector.c new file +689 -0
689 lines not on this page · raw message
arch/x86/kernel/irqinit.c +0 -22
@@ -100,28 +100,6 @@ void __init init_IRQ(void) x86_init.irqs.intr_init (); } -/* -* Setup the vector to irq mappings. -*/ -void setup_vector_irq (int cpu) -{ -#ifndef CONFIG_X86_IO_APIC -int irq; - -/* -* On most of the platforms, legacy PIC delivers the interrupts on the -* boot cpu. But there are certain platforms where PIC interrupts are -* delivered to multiple cpu's. If the legacy IRQ is handled by the -* legacy PIC, for the new cpu that is coming online, setup the static -* legacy vector to irq mapping: -*/ -for (irq =0 ; irq <nr_legacy_irqs (); irq++) -per_cpu (vector_irq, cpu)[IRQ0_VECTOR + irq] = irq; -#endif - -__setup_vector_irq (cpu); -} -static void __init smp_intr_init (void ) {#ifdef CONFIG_SMP
Signature · 1 line
1.7.10.4
PATCH v2 9/18 x86, irq: Replace printk(KERN_LVL) with pr_lvl() utilities
In reply to Jiang LiuReplace printk(KENR_LVL) with pr_lvl() to keep checkpatch script silent.
--- arch/x86/kernel/apic/vector.c | 69 ++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 35 deletions(-)
arch/x86/kernel/apic/vector.c +34 -35
@@ -506,27 +506,26 @@ static void __init print_local_APIC(void *dummy)unsigned int i, v, ver, maxlvt;u64 icr; -printk (KERN_DEBUG "printing local APIC contents on CPU#%d/%d:\n" , -smp_processor_id (),hard_smp_processor_id ()); +pr_debug ("printing local APIC contents on CPU#%d/%d:\n" , +smp_processor_id (),hard_smp_processor_id ()); v =apic_read (APIC_ID ); -printk (KERN_INFO "... APIC ID: %08x (%01x)\n" , v,read_apic_id ()); +pr_info ("... APIC ID: %08x (%01x)\n" , v,read_apic_id ()); v =apic_read (APIC_LVR ); -printk (KERN_INFO "... APIC VERSION: %08x\n" , v); +pr_info ("... APIC VERSION: %08x\n" , v); ver =GET_APIC_VERSION (v); maxlvt =lapic_get_maxlvt (); v =apic_read (APIC_TASKPRI ); -printk (KERN_DEBUG "... APIC TASKPRI: %08x (%02x)\n" , - v, v &APIC_TPRI_MASK ); +pr_debug ("... APIC TASKPRI: %08x (%02x)\n" , v, v &APIC_TPRI_MASK );if (APIC_INTEGRATED (ver)) {/* !82489DX */ if (!APIC_XAPIC (ver)) { v =apic_read (APIC_ARBPRI ); -printk (KERN_DEBUG "... APIC ARBPRI: %08x (%02x)\n" , v, - v &APIC_ARBPRI_MASK ); +pr_debug ("... APIC ARBPRI: %08x (%02x)\n" , + v, v &APIC_ARBPRI_MASK ); } v =apic_read (APIC_PROCPRI ); -printk (KERN_DEBUG "... APIC PROCPRI: %08x\n" , v); +pr_debug ("... APIC PROCPRI: %08x\n" , v); }/*
@@ -535,23 +534,23 @@ static void __init print_local_APIC(void *dummy)*/ if (!APIC_INTEGRATED (ver) || maxlvt ==3 ) { v =apic_read (APIC_RRR ); -printk (KERN_DEBUG "... APIC RRR: %08x\n" , v); +pr_debug ("... APIC RRR: %08x\n" , v); } v =apic_read (APIC_LDR ); -printk (KERN_DEBUG "... APIC LDR: %08x\n" , v); +pr_debug ("... APIC LDR: %08x\n" , v);if (!x2apic_enabled ()) { v =apic_read (APIC_DFR ); -printk (KERN_DEBUG "... APIC DFR: %08x\n" , v); +pr_debug ("... APIC DFR: %08x\n" , v); } v =apic_read (APIC_SPIV ); -printk (KERN_DEBUG "... APIC SPIV: %08x\n" , v); +pr_debug ("... APIC SPIV: %08x\n" , v); -printk (KERN_DEBUG "... APIC ISR field:\n" ); +pr_debug ("... APIC ISR field:\n" );print_APIC_field (APIC_ISR ); -printk (KERN_DEBUG "... APIC TMR field:\n" ); +pr_debug ("... APIC TMR field:\n" );print_APIC_field (APIC_TMR ); -printk (KERN_DEBUG "... APIC IRR field:\n" ); +pr_debug ("... APIC IRR field:\n" );print_APIC_field (APIC_IRR );if (APIC_INTEGRATED (ver)) {/* !82489DX */
@@ -559,46 +558,46 @@ static void __init print_local_APIC(void *dummy)apic_write (APIC_ESR ,0 ); v =apic_read (APIC_ESR ); -printk (KERN_DEBUG "... APIC ESR: %08x\n" , v); +pr_debug ("... APIC ESR: %08x\n" , v); } icr =apic_icr_read (); -printk (KERN_DEBUG "... APIC ICR: %08x\n" , (u32 )icr); -printk (KERN_DEBUG "... APIC ICR2: %08x\n" , (u32)(icr >>32 )); +pr_debug ("... APIC ICR: %08x\n" , (u32 )icr); +pr_debug ("... APIC ICR2: %08x\n" , (u32)(icr >>32 )); v =apic_read (APIC_LVTT ); -printk (KERN_DEBUG "... APIC LVTT: %08x\n" , v); +pr_debug ("... APIC LVTT: %08x\n" , v);if (maxlvt >3 ) {/* PC is LVT#4. */ v =apic_read (APIC_LVTPC ); -printk (KERN_DEBUG "... APIC LVTPC: %08x\n" , v); +pr_debug ("... APIC LVTPC: %08x\n" , v); } v =apic_read (APIC_LVT0 ); -printk (KERN_DEBUG "... APIC LVT0: %08x\n" , v); +pr_debug ("... APIC LVT0: %08x\n" , v); v =apic_read (APIC_LVT1 ); -printk (KERN_DEBUG "... APIC LVT1: %08x\n" , v); +pr_debug ("... APIC LVT1: %08x\n" , v);if (maxlvt >2 ) {/* ERR is LVT#3. */ v =apic_read (APIC_LVTERR ); -printk (KERN_DEBUG "... APIC LVTERR: %08x\n" , v); +pr_debug ("... APIC LVTERR: %08x\n" , v); } v =apic_read (APIC_TMICT ); -printk (KERN_DEBUG "... APIC TMICT: %08x\n" , v); +pr_debug ("... APIC TMICT: %08x\n" , v); v =apic_read (APIC_TMCCT ); -printk (KERN_DEBUG "... APIC TMCCT: %08x\n" , v); +pr_debug ("... APIC TMCCT: %08x\n" , v); v =apic_read (APIC_TDCR ); -printk (KERN_DEBUG "... APIC TDCR: %08x\n" , v); +pr_debug ("... APIC TDCR: %08x\n" , v);if (boot_cpu_has (X86_FEATURE_EXTAPIC )) { v =apic_read (APIC_EFEAT ); maxlvt = (v >>16 ) &0xff ; -printk (KERN_DEBUG "... APIC EFEAT: %08x\n" , v); +pr_debug ("... APIC EFEAT: %08x\n" , v); v =apic_read (APIC_ECTRL ); -printk (KERN_DEBUG "... APIC ECTRL: %08x\n" , v); +pr_debug ("... APIC ECTRL: %08x\n" , v);for (i =0 ; i < maxlvt; i++) { v =apic_read (APIC_EILVTn (i)); -printk (KERN_DEBUG "... APIC EILVT%d: %08x\n" , i, v); +pr_debug ("... APIC EILVT%d: %08x\n" , i, v); } }pr_cont ("\n" );
@@ -628,15 +627,15 @@ static void __init print_PIC(void)if (!nr_legacy_irqs ())return ; -printk (KERN_DEBUG "\nprinting PIC contents\n" ); +pr_debug ("\nprinting PIC contents\n" );raw_spin_lock_irqsave (&i8259A_lock, flags); v =inb (0xa1 ) <<8 |inb (0x21 ); -printk (KERN_DEBUG "... PIC IMR: %04x\n" , v); +pr_debug ("... PIC IMR: %04x\n" , v); v =inb (0xa0 ) <<8 |inb (0x20 ); -printk (KERN_DEBUG "... PIC IRR: %04x\n" , v); +pr_debug ("... PIC IRR: %04x\n" , v);outb (0x0b ,0xa0 );outb (0x0b ,0x20 );
@@ -646,10 +645,10 @@ static void __init print_PIC(void)raw_spin_unlock_irqrestore (&i8259A_lock, flags); -printk (KERN_DEBUG "... PIC ISR: %04x\n" , v); +pr_debug ("... PIC ISR: %04x\n" , v); v =inb (0x4d1 ) <<8 |inb (0x4d0 ); -printk (KERN_DEBUG "... PIC ELCR: %04x\n" , v); +pr_debug ("... PIC ELCR: %04x\n" , v); }static int show_lapic__initdata =1 ;
Signature · 1 line
1.7.10.4
PATCH v2 10/18 x86, irq: Move PCI MSI related code from io_apic.c into msi.c
In reply to Jiang LiuCreate arch/x86/kernel/apic/msi.c to host MSI related code, preparing for enabling hierarchy irqdomain.
--- arch/x86/include/asm/io_apic.h | 4 - arch/x86/include/asm/pci.h | 3 + arch/x86/kernel/apic/Makefile | 1 + arch/x86/kernel/apic/io_apic.c | 269 -------------------------------------- arch/x86/kernel/apic/msi.c | 283 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 287 insertions(+), 273 deletions(-) create mode 100644 arch/x86/kernel/apic/msi.c
arch/x86/include/asm/io_apic.h +0 -4
@@ -148,9 +148,6 @@ extern int native_setup_ioapic_entry(int, struct IO_APIC_route_entry *, struct io_apic_irq_attr *);extern void eoi_ioapic_irq (unsigned int irq,struct irq_cfg *cfg); -extern void native_compose_msi_msg (struct pci_dev *pdev, -unsigned int irq,unsigned int dest, -struct msi_msg *msg,u8 hpet_id);extern void native_eoi_ioapic_pin (int apic,int pin,int vector);extern int save_ioapic_entries (void );
@@ -264,7 +261,6 @@ static inline void disable_ioapic_support(void) { }#define native_io_apic_print_entries NULL#define native_ioapic_set_affinity NULL#define native_setup_ioapic_entry NULL -#define native_compose_msi_msg NULL#define native_eoi_ioapic_pin NULL#endif
arch/x86/include/asm/pci.h +3 -0
@@ -96,12 +96,15 @@ extern void pci_iommu_alloc(void);#ifdef CONFIG_PCI_MSI /* implemented in arch/x86/kernel/apic/io_apic. */ struct msi_desc ; +void native_compose_msi_msg (struct pci_dev *pdev,unsigned int irq, +unsigned int dest,struct msi_msg *msg,u8 hpet_id);int native_setup_msi_irqs (struct pci_dev *dev,int nvec,int type);void native_teardown_msi_irq (unsigned int irq);void native_restore_msi_irqs (struct pci_dev *dev);int setup_msi_irq (struct pci_dev *dev,struct msi_desc *msidesc,unsigned int irq_base,unsigned int irq_offset);#else +#define native_compose_msi_msg NULL#define native_setup_msi_irqs NULL#define native_teardown_msi_irq NULL#endif
arch/x86/kernel/apic/Makefile +1 -0
@@ -6,6 +6,7 @@ obj-$(CONFIG_X86_LOCAL_APIC) += apic.o apic_noop.o ipi.o vector.o obj-y += hw_nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o +obj-$(CONFIG_PCI_MSI) += msi.o obj-$(CONFIG_SMP) += ipi.o ifeq ($(CONFIG_X86_64),y)
arch/x86/kernel/apic/io_apic.c +0 -269
296 lines not on this page · raw message
arch/x86/kernel/apic/msi.c new file +283 -0
283 lines not on this page · raw message
Signature · 1 line
1.7.10.4
PATCH v2 11/18 x86, irq: Move HT IRQ related code from io_apic.c into htirq.c
In reply to Jiang LiuCreate arch/x86/kernel/apic/htirq.c to host Hypertransport IRQ related code, preparing for enabling hierarchy irqdomain.
--- arch/x86/kernel/apic/Makefile | 1 + arch/x86/kernel/apic/htirq.c | 106 ++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/apic/io_apic.c | 91 ---------------------------------- 3 files changed, 107 insertions(+), 91 deletions(-) create mode 100644 arch/x86/kernel/apic/htirq.c
arch/x86/kernel/apic/Makefile +1 -0
@@ -7,6 +7,7 @@ obj-y += hw_nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o obj-$(CONFIG_PCI_MSI) += msi.o +obj-$(CONFIG_HT_IRQ) += htirq.o obj-$(CONFIG_SMP) += ipi.o ifeq ($(CONFIG_X86_64),y)
arch/x86/kernel/apic/htirq.c new file +106 -0
106 lines not on this page · raw message
arch/x86/kernel/apic/io_apic.c +0 -91
109 lines not on this page · raw message
Signature · 1 line
1.7.10.4
PATCH v2 12/18 x86, irq: Move IOAPIC related declarations from hw_irq.h into io_apic.h
In reply to Jiang LiuClean up code by moving IOAPIC related declarations from hw_irq.h into io_apic.h.
--- arch/x86/include/asm/hw_irq.h | 33 --------------------------------- arch/x86/include/asm/io_apic.h | 23 ++++++++++++++++++++--- arch/x86/kernel/apic/io_apic.c | 10 ++++++++++ arch/x86/kernel/crash.c | 1 + arch/x86/kernel/machine_kexec_32.c | 1 + arch/x86/kernel/machine_kexec_64.c | 1 + arch/x86/kernel/reboot.c | 1 + 7 files changed, 34 insertions(+), 36 deletions(-)
arch/x86/include/asm/hw_irq.h +0 -33
@@ -154,39 +154,6 @@ static inline void lock_vector_lock(void) {}static inline void unlock_vector_lock (void ) {}#endif /* CONFIG_X86_LOCAL_APIC */ -/* IOAPIC */ -#ifdef CONFIG_X86_IO_APIC -struct io_apic_irq_attr { -int ioapic; -int ioapic_pin; -int trigger; -int polarity; -}; - -static inline void set_io_apic_irq_attr (struct io_apic_irq_attr *irq_attr, -int ioapic,int ioapic_pin, -int trigger,int polarity) -{ - irq_attr->ioapic = ioapic; - irq_attr->ioapic_pin = ioapic_pin; - irq_attr->trigger = trigger; - irq_attr->polarity = polarity; -} - -extern void setup_IO_APIC (void ); -extern void enable_IO_APIC (void ); -extern void disable_IO_APIC (void ); -extern void setup_ioapic_dest (void ); -extern int IO_APIC_get_PCI_irq_vector (int bus,int devfn,int pin); -extern void print_IO_APICs (void ); - -extern unsigned long io_apic_irqs; -#define IO_APIC_IRQ (x) (((x) >= NR_IRQS_LEGACY) || ((1 << (x)) & io_apic_irqs)) -#else /* CONFIG_X86_IO_APIC */ -#define IO_APIC_IRQ (x) 0 -static inline void print_IO_APICs (void ) {} -#endif /* CONFIG_X86_IO_APIC */ -/* Statistics */ extern atomic_t irq_err_count;extern atomic_t irq_mis_count;
arch/x86/include/asm/io_apic.h +20 -3
@@ -132,6 +132,10 @@ extern int noioapicquirk;/* -1 if "noapic" boot option passed */ extern int noioapicreroute; +extern unsigned long io_apic_irqs; + +#define IO_APIC_IRQ (x) (((x) >= NR_IRQS_LEGACY) || ((1 << (x)) & io_apic_irqs)) +/* * If we use the IO-APIC for IRQ routing, disable automatic * assignment of PCI IRQ's.
@@ -139,7 +143,6 @@ extern int noioapicreroute;#define io_apic_assign_pci_irqs \ (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs) -struct io_apic_irq_attr ;struct irq_cfg ;extern void ioapic_insert_resources (void );
@@ -157,6 +160,13 @@ extern int restore_ioapic_entries(void);extern void setup_ioapic_ids_from_mpc (void );extern void setup_ioapic_ids_from_mpc_nocheck (void ); +struct io_apic_irq_attr { +int ioapic; +int ioapic_pin; +int trigger; +int polarity; +}; +enum ioapic_domain_type {IOAPIC_DOMAIN_INVALID ,IOAPIC_DOMAIN_LEGACY ,
@@ -196,6 +206,7 @@ extern int mp_set_gsi_attr(u32 gsi, int trigger, int polarity, int node);extern void __init pre_init_apic_IRQ0 (void );extern void mp_save_irq (struct mpc_intsrc *m); +extern bool mp_should_keep_irq (struct device *dev);extern void disable_ioapic_support (void );
@@ -226,13 +237,19 @@ static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsignedextern void io_apic_eoi (unsigned int apic,unsigned int vector); -extern bool mp_should_keep_irq (struct device *dev); - +extern void setup_IO_APIC (void ); +extern void enable_IO_APIC (void ); +extern void disable_IO_APIC (void ); +extern void setup_ioapic_dest (void ); +extern int IO_APIC_get_PCI_irq_vector (int bus,int devfn,int pin); +extern void print_IO_APICs (void );#else /* !CONFIG_X86_IO_APIC */ +#define IO_APIC_IRQ (x) 0#define io_apic_assign_pci_irqs 0#define setup_ioapic_ids_from_mpc x86_init_noopstatic inline void ioapic_insert_resources (void ) { } +static inline void print_IO_APICs (void ) {}#define gsi_top (NR_IRQS_LEGACY)static inline int mp_find_ioapic (u32 gsi) {return 0 ; }static inline u32 mp_pin_to_gsi (int ioapic,int pin) {return UINT_MAX ; }
arch/x86/kernel/apic/io_apic.c +10 -0
@@ -3014,6 +3014,16 @@ int mp_ioapic_registered(u32 gsi_base)return 0 ; } +static inline void set_io_apic_irq_attr (struct io_apic_irq_attr *irq_attr, +int ioapic,int ioapic_pin, +int trigger,int polarity) +{ + irq_attr->ioapic = ioapic; + irq_attr->ioapic_pin = ioapic_pin; + irq_attr->trigger = trigger; + irq_attr->polarity = polarity; +} +int mp_irqdomain_map (struct irq_domain *domain,unsigned int virq,irq_hw_number_t hwirq) {
arch/x86/kernel/crash.c +1 -0
@@ -28,6 +28,7 @@#include <asm/nmi.h> #include <asm/hw_irq.h> #include <asm/apic.h> +#include <asm/io_apic.h> #include <asm/hpet.h> #include <linux/kdebug.h> #include <asm/cpu.h>
arch/x86/kernel/machine_kexec_32.c +1 -0
@@ -20,6 +20,7 @@#include <asm/tlbflush.h> #include <asm/mmu_context.h> #include <asm/apic.h> +#include <asm/io_apic.h> #include <asm/cpufeature.h> #include <asm/desc.h> #include <asm/cacheflush.h>
arch/x86/kernel/machine_kexec_64.c +1 -0
@@ -22,6 +22,7 @@#include <asm/pgtable.h> #include <asm/tlbflush.h> #include <asm/mmu_context.h> +#include <asm/io_apic.h> #include <asm/debugreg.h> #include <asm/kexec-bzimage64.h>
arch/x86/kernel/reboot.c +1 -0
@@ -12,6 +12,7 @@#include <acpi/reboot.h> #include <asm/io.h> #include <asm/apic.h> +#include <asm/io_apic.h> #include <asm/desc.h> #include <asm/hpet.h> #include <asm/pgtable.h>
Signature · 1 line
1.7.10.4
PATCH v2 13/18 x86, irq: Move IRQ initialization routines from io_apic.c into vector.c
In reply to Jiang LiuMove IRQ initialization routines from io_apic.c into vector.c, preparing for enabling hierarchy irqdomain.
--- arch/x86/include/asm/io_apic.h | 2 ++ arch/x86/kernel/apic/io_apic.c | 22 +--------------------- arch/x86/kernel/apic/vector.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 21 deletions(-)
arch/x86/include/asm/io_apic.h +2 -0
@@ -145,6 +145,7 @@ extern unsigned long io_apic_irqs;struct irq_cfg ;extern void ioapic_insert_resources (void ); +extern int arch_early_ioapic_init (void ); extern int native_setup_ioapic_entry(int, struct IO_APIC_route_entry *, unsigned int, int,
@@ -249,6 +250,7 @@ extern void print_IO_APICs(void);#define io_apic_assign_pci_irqs 0#define setup_ioapic_ids_from_mpc x86_init_noopstatic inline void ioapic_insert_resources (void ) { } +static inline int arch_early_ioapic_init (void ) {return 0 ; }static inline void print_IO_APICs (void ) {}#define gsi_top (NR_IRQS_LEGACY)static inline int mp_find_ioapic (u32 gsi) {return 0 ; }
arch/x86/kernel/apic/io_apic.c +1 -21
@@ -245,7 +245,7 @@ static void free_ioapic_saved_registers(int idx) ioapics[idx].saved_registers =NULL ; } -int __init arch_early_irq_init (void ) +int __init arch_early_ioapic_init (void ) {struct irq_cfg *cfg;int i, node =cpu_to_node (0 );
@@ -2486,26 +2486,6 @@ unsigned int arch_dynirq_lower_bound(unsigned int from)return ioapic_initialized ? ioapic_dynirq_base : gsi_top; } -int __init arch_probe_nr_irqs (void ) -{ -int nr; - -if (nr_irqs > (NR_VECTORS * nr_cpu_ids)) - nr_irqs =NR_VECTORS * nr_cpu_ids; - - nr = (gsi_top +nr_legacy_irqs ()) +8 * nr_cpu_ids; -#if defined(CONFIG_PCI_MSI ) || defined(CONFIG_HT_IRQ ) -/* -* for MSI and HT dyn irq -*/ - nr += gsi_top *16 ; -#endif -if (nr < nr_irqs) - nr_irqs = nr; - -return 0 ; -} -#ifdef CONFIG_X86_32 static int io_apic_get_unique_id (int ioapic,int apic_id) {
arch/x86/kernel/apic/vector.c +28 -0
@@ -235,6 +235,34 @@ void clear_irq_vector(int irq, struct irq_cfg *cfg)raw_spin_unlock_irqrestore (&vector_lock, flags); } +int __init arch_probe_nr_irqs (void ) +{ +int nr; + +if (nr_irqs > (NR_VECTORS * nr_cpu_ids)) + nr_irqs =NR_VECTORS * nr_cpu_ids; + + nr = (gsi_top +nr_legacy_irqs ()) +8 * nr_cpu_ids; +#if defined(CONFIG_PCI_MSI ) || defined(CONFIG_HT_IRQ ) +/* +* for MSI and HT dyn irq +*/ +if (gsi_top <=NR_IRQS_LEGACY ) + nr +=8 * nr_cpu_ids; +else + nr += gsi_top *16 ; +#endif +if (nr < nr_irqs) + nr_irqs = nr; + +return 0 ; +} + +int __init arch_early_irq_init (void ) +{ +return arch_early_ioapic_init (); +} +static void __setup_vector_irq (int cpu) {/* Initialize vector_irq on a new cpu */
Signature · 1 line
1.7.10.4
PATCH v2 14/18 x86, irq: Make MSI and HT_IRQ indepenent of X86_IO_APIC
In reply to Jiang LiuNow we have splitted functions to support MSI and HT_IRQ into vector.c, and they have no dependency on IOAPIC any more. So change Kconfig files to make MSI and HT_IRQ independent of X86_IO_APIC.
--- arch/x86/Kconfig | 4 ++-- drivers/pci/Kconfig | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
arch/x86/Kconfig +2 -2
@@ -840,8 +840,8 @@ config X86_LOCAL_APIC select GENERIC_IRQ_LEGACY_ALLOC_HWIRQ config X86_IO_APIC - def_bool y - depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_IOAPIC || PCI_MSI + def_bool X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_IOAPIC + depends on X86_LOCAL_APIC select IRQ_DOMAIN config X86_REROUTE_FOR_BROKEN_BOOT_IRQS
drivers/pci/Kconfig +1 -1
@@ -61,7 +61,7 @@ config XEN_PCIDEV_FRONTEND config HT_IRQ bool "Interrupts on hypertransport devices" default y - depends on PCI && X86_LOCAL_APIC && X86_IO_APIC + depends on PCI && X86_LOCAL_APIC help This allows native hypertransport devices to use interrupts.
Signature · 1 line
1.7.10.4
PATCH v2 15/18 x86, irq: Use helpers to access irq_cfg data structure associated with IRQ
In reply to Jiang LiuUse helpers to access irq_cfg data structure associated with IRQ, instead of accessing irq_data->chip_data directly. Later we could rewrite those helpers to support hierarchy irqdomain.
--- arch/x86/kernel/apic/htirq.c | 2 +- arch/x86/kernel/apic/io_apic.c | 10 +++++----- arch/x86/kernel/apic/msi.c | 6 +++--- arch/x86/kernel/apic/vector.c | 6 +++--- arch/x86/platform/uv/uv_irq.c | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-)
arch/x86/kernel/apic/htirq.c +1 -1
@@ -39,7 +39,7 @@ static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector)static int ht_set_affinity (struct irq_data *data,const struct cpumask *mask,bool force) { -struct irq_cfg *cfg = data->chip_data; +struct irq_cfg *cfg =irqd_cfg (data);unsigned int dest;int ret;
arch/x86/kernel/apic/io_apic.c +5 -5
@@ -501,7 +501,7 @@ static void mask_ioapic(struct irq_cfg *cfg)static void mask_ioapic_irq (struct irq_data *data) { -mask_ioapic (data->chip_data); +mask_ioapic (irqd_cfg (data)); }static void __unmask_ioapic (struct irq_cfg *cfg)
@@ -520,7 +520,7 @@ static void unmask_ioapic(struct irq_cfg *cfg)static void unmask_ioapic_irq (struct irq_data *data) { -unmask_ioapic (data->chip_data); +unmask_ioapic (irqd_cfg (data)); }/*
@@ -1801,7 +1801,7 @@ static unsigned int startup_ioapic_irq(struct irq_data *data)if (legacy_pic->irq_pending (irq)) was_pending =1 ; } -__unmask_ioapic (data->chip_data); +__unmask_ioapic (irqd_cfg (data));raw_spin_unlock_irqrestore (&ioapic_lock, flags);return was_pending;
@@ -1852,7 +1852,7 @@ int native_ioapic_set_affinity(struct irq_data *data,if (!ret) {/* Only the high 8 bits are valid. */ dest =SET_APIC_LOGICAL_ID (dest); -__target_IO_APIC_irq (irq, dest, data->chip_data); +__target_IO_APIC_irq (irq, dest,irqd_cfg (data)); ret =IRQ_SET_MASK_OK_NOCOPY ; }raw_spin_unlock_irqrestore (&ioapic_lock, flags);
@@ -1943,7 +1943,7 @@ static inline void ioapic_irqd_unmask(struct irq_data *data,static void ack_ioapic_level (struct irq_data *data) { -struct irq_cfg *cfg = data->chip_data; +struct irq_cfg *cfg =irqd_cfg (data);int i, irq = data->irq;unsigned long v;bool masked;
arch/x86/kernel/apic/msi.c +3 -3
@@ -78,7 +78,7 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq,static int msi_set_affinity (struct irq_data *data,const struct cpumask *mask,bool force) { -struct irq_cfg *cfg = data->chip_data; +struct irq_cfg *cfg =irqd_cfg (data);struct msi_msg msg;unsigned int dest;int ret;
@@ -179,7 +179,7 @@ static int dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) { - struct irq_cfg *cfg = data->chip_data; + struct irq_cfg *cfg = irqd_cfg(data);unsigned int dest, irq = data->irq;struct msi_msg msg;int ret;
@@ -233,7 +233,7 @@ int arch_setup_dmar_msi(unsigned int irq)static int hpet_msi_set_affinity (struct irq_data *data,const struct cpumask *mask,bool force) { -struct irq_cfg *cfg = data->chip_data; +struct irq_cfg *cfg =irqd_cfg (data);struct msi_msg msg;unsigned int dest;int ret;
arch/x86/kernel/apic/vector.c +3 -3
@@ -321,7 +321,7 @@ void setup_vector_irq(int cpu)int apic_retrigger_irq (struct irq_data *data) { -struct irq_cfg *cfg = data->chip_data; +struct irq_cfg *cfg =irqd_cfg (data);unsigned long flags;int cpu;
@@ -335,7 +335,7 @@ int apic_retrigger_irq(struct irq_data *data)void apic_ack_edge (struct irq_data *data) { -irq_complete_move (data->chip_data); +irq_complete_move (irqd_cfg (data));irq_move_irq (data);ack_APIC_irq (); }
@@ -348,7 +348,7 @@ void apic_ack_edge(struct irq_data *data)int apic_set_affinity (struct irq_data *data,const struct cpumask *mask,unsigned int *dest_id) { -struct irq_cfg *cfg = data->chip_data; +struct irq_cfg *cfg =irqd_cfg (data);unsigned int irq = data->irq;int err;
arch/x86/platform/uv/uv_irq.c +2 -2
@@ -131,7 +131,7 @@ arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade, unsigned long mmr_offset, int limit) {const struct cpumask *eligible_cpu =cpumask_of (cpu); -struct irq_cfg *cfg =irq_get_chip_data (irq); +struct irq_cfg *cfg =irq_cfg (irq);unsigned long mmr_value;struct uv_IO_APIC_route_entry *entry;int mmr_pnode, err;
@@ -198,7 +198,7 @@ static int uv_set_irq_affinity(struct irq_data *data, const struct cpumask *mask, bool force) { - struct irq_cfg *cfg = data->chip_data; + struct irq_cfg *cfg = irqd_cfg(data);unsigned int dest;unsigned long mmr_value, mmr_offset;struct uv_IO_APIC_route_entry *entry;
Signature · 1 line
1.7.10.4
PATCH v2 16/18 x86: irq_remapping: Use helpers to access irq_cfg data structure associated with IRQ
In reply to Jiang LiuUse helpers to access irq_cfg data structure associated with IRQ, instead of accessing irq_data->chip_data directly. Later we could rewrite those helpers to support hierarchy irqdomain.
--- drivers/iommu/irq_remapping.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/iommu/irq_remapping.c +3 -3
@@ -305,7 +305,7 @@ static int set_remapped_irq_affinity(struct irq_data *data,void free_remapped_irq (int irq) { -struct irq_cfg *cfg =irq_get_chip_data (irq); +struct irq_cfg *cfg =irq_cfg (irq);if (!remap_ops || !remap_ops->free_irq)return ;
@@ -318,7 +318,7 @@ void compose_remapped_msi_msg(struct pci_dev *pdev, unsigned int irq, unsigned int dest, struct msi_msg *msg, u8 hpet_id) { - struct irq_cfg *cfg = irq_get_chip_data(irq); + struct irq_cfg *cfg = irq_cfg(irq);if (!irq_remapped (cfg))native_compose_msi_msg (pdev, irq, dest, msg, hpet_id);
@@ -365,7 +365,7 @@ static void ir_ack_apic_edge(struct irq_data *data)static void ir_ack_apic_level (struct irq_data *data) {ack_APIC_irq (); -eoi_ioapic_irq (data->irq, data->chip_data); +eoi_ioapic_irq (data->irq,irqd_cfg (data)); }static void ir_print_prefix (struct irq_data *data,struct seq_file *p)
Signature · 1 line
1.7.10.4
PATCH v2 17/18 iommu/vt-d: Use helpers to access irq_cfg data structure associated with IRQ
In reply to Jiang LiuUse helpers to access irq_cfg data structure associated with IRQ, instead of accessing irq_data->chip_data directly. Later we could rewrite those helpers to support hierarchy irqdomain.
--- drivers/iommu/intel_irq_remapping.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/iommu/intel_irq_remapping.c +5 -5
@@ -55,7 +55,7 @@ static int __init parse_ioapics_under_ir(void);static struct irq_2_iommu *irq_2_iommu (unsigned int irq) { -struct irq_cfg *cfg =irq_get_chip_data (irq); +struct irq_cfg *cfg =irq_cfg (irq);return cfg ? &cfg->irq_2_iommu :NULL ; }
@@ -86,7 +86,7 @@ static int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) {struct ir_table *table = iommu->ir_table;struct irq_2_iommu *irq_iommu =irq_2_iommu (irq); -struct irq_cfg *cfg =irq_get_chip_data (irq); +struct irq_cfg *cfg =irq_cfg (irq);unsigned int mask =0 ;unsigned long flags;int index;
@@ -154,7 +154,7 @@ static int map_irq_to_irte_handle(int irq, u16 *sub_handle)static int set_irte_irq (int irq,struct intel_iommu *iommu,u16 index,u16 subhandle) {struct irq_2_iommu *irq_iommu =irq_2_iommu (irq); -struct irq_cfg *cfg =irq_get_chip_data (irq); +struct irq_cfg *cfg =irq_cfg (irq);unsigned long flags;if (!irq_iommu)
@@ -1009,7 +1009,7 @@ static int intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) { - struct irq_cfg *cfg = data->chip_data; + struct irq_cfg *cfg = irqd_cfg(data);unsigned int dest, irq = data->irq;struct irte irte;int err;
@@ -1064,7 +1064,7 @@ static void intel_compose_msi_msg(struct pci_dev *pdev,u16 sub_handle =0 ;int ir_index; - cfg =irq_get_chip_data (irq); + cfg =irq_cfg (irq); ir_index =map_irq_to_irte_handle (irq, &sub_handle);BUG_ON (ir_index ==-1 );
Signature · 1 line
1.7.10.4
PATCH v2 18/18 iommu/amd: Use helpers to access irq_cfg data structure associated with IRQ
In reply to Jiang LiuUse helpers to access irq_cfg data structure associated with IRQ, instead of accessing irq_data->chip_data directly. Later we could rewrite those helpers to support hierarchy irqdomain.
--- drivers/iommu/amd_iommu.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/iommu/amd_iommu.c +7 -7
@@ -4049,7 +4049,7 @@ static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry,int devid;int ret; - cfg =irq_get_chip_data (irq); + cfg =irq_cfg (irq);if (!cfg)return -EINVAL ;
@@ -4112,7 +4112,7 @@ static int set_affinity(struct irq_data *data, const struct cpumask *mask,if (!config_enabled (CONFIG_SMP ))return -1 ; - cfg = data->chip_data; + cfg =irqd_cfg (data); irq = data->irq; irte_info = &cfg->irq_2_irte;
@@ -4150,7 +4150,7 @@ static int free_irq(int irq)struct irq_2_irte *irte_info;struct irq_cfg *cfg; - cfg =irq_get_chip_data (irq); + cfg =irq_cfg (irq);if (!cfg)return -EINVAL ;
@@ -4169,7 +4169,7 @@ static void compose_msi_msg(struct pci_dev *pdev,struct irq_cfg *cfg;union irte irte; - cfg =irq_get_chip_data (irq); + cfg =irq_cfg (irq);if (!cfg)return ;
@@ -4198,7 +4198,7 @@ static int msi_alloc_irq(struct pci_dev *pdev, int irq, int nvec)if (!pdev)return -EINVAL ; - cfg =irq_get_chip_data (irq); + cfg =irq_cfg (irq);if (!cfg)return -EINVAL ;
@@ -4218,7 +4218,7 @@ static int msi_setup_irq(struct pci_dev *pdev, unsigned int irq,if (!pdev)return -EINVAL ; - cfg =irq_get_chip_data (irq); + cfg =irq_cfg (irq);if (!cfg)return -EINVAL ;
@@ -4241,7 +4241,7 @@ static int setup_hpet_msi(unsigned int irq, unsigned int id)struct irq_cfg *cfg;int index, devid; - cfg =irq_get_chip_data (irq); + cfg =irq_cfg (irq);if (!cfg)return -EINVAL ;
Signature · 1 line
1.7.10.4