: SN Hotplug Driver - SN IRQ fixes
PATCH 1/6 : SN Hotplug Driver - SN IRQ fixes
This patch fixes the SN IRQ code such that cpu affinity and Hotplug can modify IRQ values. The sn_irq_info structures are now locked using a RCU lock mechanism to avoid lock contention in the lost interrupt WAR code.
Signed-off-by Prarit Bhargava <[email protected]>
arch/ia64/sn/include/pci/pcidev.h | 3 arch/ia64/sn/kernel/io_init.c | 37 +++-- arch/ia64/sn/kernel/irq.c | 246 ++++++++++++++++++++------------------ include/asm-ia64/sn/intr.h | 6 4 files changed, 158 insertions(+), 134 deletions(-)
arch/ia64/sn/include/pci/pcidev.h +1 -2
@@ -10,8 +10,6 @@#include <linux/pci.h> -extern struct sn_irq_info **sn_irq; -#define SN_PCIDEV_INFO (pci_dev) \ ((struct pcidev_info *)(pci_dev)->sysdata)
@@ -51,4 +49,5 @@ struct pcidev_info {extern void sn_irq_fixup (struct pci_dev *pci_dev,struct sn_irq_info *sn_irq_info); +extern void sn_irq_lh_init (void );#endif /* _ASM_IA64_SN_PCI_PCIDEV_H */
arch/ia64/sn/kernel/io_init.c +21 -16
@@ -20,7 +20,6 @@#include <asm/sn/io.h> #include <asm/sn/simulator.h> -char master_baseio_wid;nasid_t master_nasid =INVALID_NASID ;/* Partition Master */ struct slab_info {
@@ -197,10 +196,12 @@ static void sn_pci_fixup_slot(struct pci {int idx;int segment =0 ; -uint64_t size; -struct sn_irq_info *sn_irq_info; -struct pci_dev *host_pci_dev;int status =0 ; +struct pci_bus *host_pci_bus; +struct pci_dev *host_pci_dev; +struct sn_irq_info *sn_irq_info; +unsigned long size; +unsigned int bus_no, devfn; dev->sysdata =kmalloc (sizeof (struct pcidev_info ),GFP_KERNEL );if (SN_PCIDEV_INFO (dev) <=0 )
@@ -218,7 +219,7 @@ static void sn_pci_fixup_slot(struct pci (u64 )__pa (SN_PCIDEV_INFO (dev)), (u64) __pa(sn_irq_info));if (status) -BUG ();/* Cannot get platform pci device information information */ +BUG ();/* Cannot get platform pci device information */ /* Copy over PIO Mapped Addresses */ for (idx =0 ; idx <=PCI_ROM_RESOURCE ; idx++) {
@@ -240,13 +241,18 @@ static void sn_pci_fixup_slot(struct pci dev->resource[idx].parent = &iomem_resource; } -/* set up host bus linkages */ - host_pci_dev = -pci_find_slot (SN_PCIDEV_INFO (dev)->pdi_slot_host_handle >>32 , -SN_PCIDEV_INFO (dev)-> - pdi_slot_host_handle &0xffffffff ); +/* Using the PROMs values for the PCI host bus, get the Linux +* PCI host_pci_dev struct and set up host bus linkages +*/ + + bus_no =SN_PCIDEV_INFO (dev)->pdi_slot_host_handle >>32 ; + devfn =SN_PCIDEV_INFO (dev)->pdi_slot_host_handle &0xffffffff ; + host_pci_bus =pci_find_bus (pci_domain_nr (dev->bus), bus_no); + host_pci_dev =pci_get_slot (host_pci_bus, devfn); + +SN_PCIDEV_INFO (dev)->host_pci_dev = host_pci_dev;SN_PCIDEV_INFO (dev)->pdi_host_pcidev_info = -SN_PCIDEV_INFO (host_pci_dev); +SN_PCIDEV_INFO (host_pci_dev);SN_PCIDEV_INFO (dev)->pdi_linux_pcidev = dev;SN_PCIDEV_INFO (dev)->pdi_pcibus_info =SN_PCIBUS_BUSSOFT (dev->bus);
@@ -255,6 +261,9 @@ static void sn_pci_fixup_slot(struct pciSN_PCIDEV_INFO (dev)->pdi_sn_irq_info = sn_irq_info; dev->irq =SN_PCIDEV_INFO (dev)->pdi_sn_irq_info->irq_irq;sn_irq_fixup (dev, sn_irq_info); + }else { +SN_PCIDEV_INFO (dev)->pdi_sn_irq_info =NULL ; +kfree (sn_irq_info); } }
@@ -343,11 +352,7 @@ static int __init sn_pci_init(void)*/ ia64_max_iommu_merge_mask = ~PAGE_MASK ;sn_fixup_ionodes (); - sn_irq =kmalloc (sizeof (struct sn_irq_info *) *NR_IRQS ,GFP_KERNEL ); -if (sn_irq <=0 ) -BUG ();/* Canno afford to run out of memory. */ -memset (sn_irq,0 ,sizeof (struct sn_irq_info *) *NR_IRQS ); - +sn_irq_lh_init ();sn_init_cpei_timer ();#ifdef CONFIG_PROC_FS
arch/ia64/sn/kernel/irq.c +131 -115
361 lines not on this page · raw message
include/asm-ia64/sn/intr.h +5 -1
@@ -9,6 +9,8 @@#ifndef _ASM_IA64_SN_INTR_H#define _ASM_IA64_SN_INTR_H +#include <linux/rcupdate.h> +#define SGI_UART_VECTOR (0xe9)#define SGI_PCIBR_ERROR (0x33)
@@ -33,7 +35,7 @@// The SN PROM irq struct struct sn_irq_info { -struct sn_irq_info *irq_next;/* sharing irq list */ +struct sn_irq_info *irq_next;/* deprecated DO NOT USE */ short irq_nasid;/* Nasid IRQ is assigned to */ int irq_slice;/* slice IRQ is assigned to */ int irq_cpuid;/* kernel logical cpuid */
@@ -47,6 +49,8 @@ struct sn_irq_info {int irq_cookie;/* unique cookie */ int irq_flags;/* flags */ int irq_share_cnt;/* num devices sharing IRQ */ +struct list_head list;/* list of sn_irq_info structs */ +struct rcu_head rcu;/* rcu callback list */ };extern void sn_send_IPI_phys (int ,long ,int ,int );