Skip to contentSkip to conversation

: SN Hotplug Driver - SN IRQ fixes

PATCH New Prarit Bhargava 1 participant 1 message May 2, 2005

lore
Share & tools
lore
#0 lore raw

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.

 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
diff -urNp linux-2.5-pristine/arch/ia64/sn/include/pci/pcidev.h sn_fixup/arch/ia64/sn/include/pci/pcidev.h
@@ -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
diff -urNp linux-2.5-pristine/arch/ia64/sn/kernel/io_init.c sn_fixup/arch/ia64/sn/kernel/io_init.c
@@ -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 pci
 		SN_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
diff -urNp linux-2.5-pristine/include/asm-ia64/sn/intr.h sn_fixup/include/asm-ia64/sn/intr.h
@@ -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);