From 5e48521e869de7d904bb5ffe9739258ffa026927 Mon Sep 17 00:00:00 2001 From: "Zhang, Yanmin" Date: Thu, 23 Feb 2006 11:07:20 +0800 Subject: [IA64] lazy_mmu_prot_update needs to be aware of huge pages Function lazy_mmu_prot_update is also used on huge pages when it is called by set_huge_ptep_writable, but it isn't aware of huge pages. Signed-off-by: Zhang Yanmin Acked-by: Ken Chen Signed-off-by: Tony Luck --- arch/ia64/mm/init.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index ff4f31fcd33..674736129b8 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -109,6 +109,7 @@ lazy_mmu_prot_update (pte_t pte) { unsigned long addr; struct page *page; + unsigned long order; if (!pte_exec(pte)) return; /* not an executable page... */ @@ -119,7 +120,12 @@ lazy_mmu_prot_update (pte_t pte) if (test_bit(PG_arch_1, &page->flags)) return; /* i-cache is already coherent with d-cache */ - flush_icache_range(addr, addr + PAGE_SIZE); + if (PageCompound(page)) { + order = (unsigned long) (page[1].lru.prev); + flush_icache_range(addr, addr + (1UL << order << PAGE_SHIFT)); + } + else + flush_icache_range(addr, addr + PAGE_SIZE); set_bit(PG_arch_1, &page->flags); /* mark page as clean */ } -- cgit v1.2.3 From ce9eed5a98efacb896551d3470d9d46826caaee5 Mon Sep 17 00:00:00 2001 From: "Chen, Kenneth W" Date: Mon, 6 Mar 2006 14:12:54 -0800 Subject: [IA64] optimize flush_tlb_range on large numa box It was reported from a field customer that global spin lock ptcg_lock is giving a lot of grief on munmap performance running on a large numa machine. What appears to be a problem coming from flush_tlb_range(), which currently unconditionally calls platform_global_tlb_purge(). For some of the numa machines in existence today, this function is mapped into ia64_global_tlb_purge(), which holds ptcg_lock spin lock while executing ptc.ga instruction. Here is a patch that attempt to avoid global tlb purge whenever possible. It will use local tlb purge as much as possible. Though the conditions to use local tlb purge is pretty restrictive. One of the side effect of having flush tlb range instruction on ia64 is that kernel don't get a chance to clear out cpu_vm_mask. On ia64, this mask is sticky and it will accumulate if process bounces around. Thus diminishing the possible use of ptc.l. Thoughts? Signed-off-by: Ken Chen Acked-by: Jack Steiner Acked-by: KAMEZAWA Hiroyuki Signed-off-by: Tony Luck --- arch/ia64/mm/tlb.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index 6a4eec9113e..4dbbca0b5e9 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c @@ -156,17 +156,19 @@ flush_tlb_range (struct vm_area_struct *vma, unsigned long start, nbits = purge.max_bits; start &= ~((1UL << nbits) - 1); -# ifdef CONFIG_SMP - platform_global_tlb_purge(mm, start, end, nbits); -# else preempt_disable(); +#ifdef CONFIG_SMP + if (mm != current->active_mm || cpus_weight(mm->cpu_vm_mask) != 1) { + platform_global_tlb_purge(mm, start, end, nbits); + preempt_enable(); + return; + } +#endif do { ia64_ptcl(start, (nbits<<2)); start += (1UL << nbits); } while (start < end); preempt_enable(); -# endif - ia64_srlz_i(); /* srlz.i implies srlz.d */ } EXPORT_SYMBOL(flush_tlb_range); -- cgit v1.2.3 From e6ef0fca2c61f7e773178be8c3833a709a47e022 Mon Sep 17 00:00:00 2001 From: "hawkes@sgi.com" Date: Mon, 27 Mar 2006 13:18:17 -0800 Subject: [IA64-SGI] sn_hwperf use of num_online_cpus() Eliminate an unnecessary -- and flawed -- use of the expensive num_online_cpus(). Signed-off-by: John Hawkes Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/sn2/sn_hwperf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c index 70db21f3df2..6ff34fc05c8 100644 --- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c @@ -605,7 +605,7 @@ static int sn_hwperf_op_cpu(struct sn_hwperf_op_info *op_info) op_info->a->arg &= SN_HWPERF_ARG_OBJID_MASK; if (cpu != SN_HWPERF_ARG_ANY_CPU) { - if (cpu >= num_online_cpus() || !cpu_online(cpu)) { + if (cpu >= NR_CPUS || !cpu_online(cpu)) { r = -EINVAL; goto out; } -- cgit v1.2.3 From 769ebc66dec24770ea1e99019099d2bc636a61d3 Mon Sep 17 00:00:00 2001 From: Dean Roe Date: Mon, 6 Mar 2006 10:32:05 -0600 Subject: [IA64-SGI] fix for-loop in sn_hwperf_geoid_to_cnode() Fix a for-loop in sn_hwperf_geoid_to_cnode(). It needs to loop over num_cnodes to ensure it can still process TIO nodes in addition to compute nodes on systems with many nodes. Interim fix until better support for many (>265) nodes is complete. Signed-off-by: Dean Roe Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/sn2/sn_hwperf.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c index 6ff34fc05c8..d917afa30b2 100644 --- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c @@ -110,7 +110,11 @@ static int sn_hwperf_geoid_to_cnode(char *location) if (sn_hwperf_location_to_bpos(location, &rack, &bay, &slot, &slab)) return -1; - for_each_node(cnode) { + /* + * FIXME: replace with cleaner for_each_XXX macro which addresses + * both compute and IO nodes once ACPI3.0 is available. + */ + for (cnode = 0; cnode < num_cnodes; cnode++) { geoid = cnodeid_get_geoid(cnode); module_id = geo_module(geoid); this_rack = MODULE_GET_RACK(module_id); -- cgit v1.2.3 From 46cba3dcaea4eb51b28fac78d15542a90619a6ef Mon Sep 17 00:00:00 2001 From: Satoru Takeuchi Date: Mon, 27 Mar 2006 17:12:19 +0900 Subject: [IA64] correct some messages and fixes some minor things This patch corrects some wrong comments and a printk message. It also fixes some minor things, and makes all lines fit in 80 columns. Signed-off-by: Satoru Takeuchi Signed-off-by: Tony Luck --- arch/ia64/kernel/iosapic.c | 260 ++++++++++++++++++++++++++++----------------- 1 file changed, 161 insertions(+), 99 deletions(-) diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 8832c553230..22d845f8536 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -9,54 +9,65 @@ * Copyright (C) 1999 VA Linux Systems * Copyright (C) 1999,2000 Walt Drummond * - * 00/04/19 D. Mosberger Rewritten to mirror more closely the x86 I/O APIC code. - * In particular, we now have separate handlers for edge - * and level triggered interrupts. - * 00/10/27 Asit Mallick, Goutham Rao IRQ vector allocation - * PCI to vector mapping, shared PCI interrupts. - * 00/10/27 D. Mosberger Document things a bit more to make them more understandable. - * Clean up much of the old IOSAPIC cruft. - * 01/07/27 J.I. Lee PCI irq routing, Platform/Legacy interrupts and fixes for - * ACPI S5(SoftOff) support. + * 00/04/19 D. Mosberger Rewritten to mirror more closely the x86 I/O + * APIC code. In particular, we now have separate + * handlers for edge and level triggered + * interrupts. + * 00/10/27 Asit Mallick, Goutham Rao IRQ vector + * allocation PCI to vector mapping, shared PCI + * interrupts. + * 00/10/27 D. Mosberger Document things a bit more to make them more + * understandable. Clean up much of the old + * IOSAPIC cruft. + * 01/07/27 J.I. Lee PCI irq routing, Platform/Legacy interrupts + * and fixes for ACPI S5(SoftOff) support. * 02/01/23 J.I. Lee iosapic pgm fixes for PCI irq routing from _PRT - * 02/01/07 E. Focht Redirectable interrupt vectors in - * iosapic_set_affinity(), initializations for - * /proc/irq/#/smp_affinity + * 02/01/07 E. Focht Redirectable interrupt + * vectors in iosapic_set_affinity(), + * initializations for /proc/irq/#/smp_affinity * 02/04/02 P. Diefenbaugh Cleaned up ACPI PCI IRQ routing. * 02/04/18 J.I. Lee bug fix in iosapic_init_pci_irq - * 02/04/30 J.I. Lee bug fix in find_iosapic to fix ACPI PCI IRQ to IOSAPIC mapping - * error + * 02/04/30 J.I. Lee bug fix in find_iosapic to fix ACPI PCI IRQ to + * IOSAPIC mapping error * 02/07/29 T. Kochi Allocate interrupt vectors dynamically - * 02/08/04 T. Kochi Cleaned up terminology (irq, global system interrupt, vector, etc.) - * 02/09/20 D. Mosberger Simplified by taking advantage of ACPI's pci_irq code. + * 02/08/04 T. Kochi Cleaned up terminology (irq, global system + * interrupt, vector, etc.) + * 02/09/20 D. Mosberger Simplified by taking advantage of ACPI's + * pci_irq code. * 03/02/19 B. Helgaas Make pcat_compat system-wide, not per-IOSAPIC. - * Remove iosapic_address & gsi_base from external interfaces. - * Rationalize __init/__devinit attributes. + * Remove iosapic_address & gsi_base from + * external interfaces. Rationalize + * __init/__devinit attributes. * 04/12/04 Ashok Raj Intel Corporation 2004 - * Updated to work with irq migration necessary for CPU Hotplug + * Updated to work with irq migration necessary + * for CPU Hotplug */ /* - * Here is what the interrupt logic between a PCI device and the kernel looks like: + * Here is what the interrupt logic between a PCI device and the kernel looks + * like: * - * (1) A PCI device raises one of the four interrupt pins (INTA, INTB, INTC, INTD). The - * device is uniquely identified by its bus--, and slot-number (the function - * number does not matter here because all functions share the same interrupt - * lines). + * (1) A PCI device raises one of the four interrupt pins (INTA, INTB, INTC, + * INTD). The device is uniquely identified by its bus-, and slot-number + * (the function number does not matter here because all functions share + * the same interrupt lines). * - * (2) The motherboard routes the interrupt line to a pin on a IOSAPIC controller. - * Multiple interrupt lines may have to share the same IOSAPIC pin (if they're level - * triggered and use the same polarity). Each interrupt line has a unique Global - * System Interrupt (GSI) number which can be calculated as the sum of the controller's - * base GSI number and the IOSAPIC pin number to which the line connects. + * (2) The motherboard routes the interrupt line to a pin on a IOSAPIC + * controller. Multiple interrupt lines may have to share the same + * IOSAPIC pin (if they're level triggered and use the same polarity). + * Each interrupt line has a unique Global System Interrupt (GSI) number + * which can be calculated as the sum of the controller's base GSI number + * and the IOSAPIC pin number to which the line connects. * - * (3) The IOSAPIC uses an internal routing table entries (RTEs) to map the IOSAPIC pin - * into the IA-64 interrupt vector. This interrupt vector is then sent to the CPU. + * (3) The IOSAPIC uses an internal routing table entries (RTEs) to map the + * IOSAPIC pin into the IA-64 interrupt vector. This interrupt vector is then + * sent to the CPU. * - * (4) The kernel recognizes an interrupt as an IRQ. The IRQ interface is used as - * architecture-independent interrupt handling mechanism in Linux. As an - * IRQ is a number, we have to have IA-64 interrupt vector number <-> IRQ number - * mapping. On smaller systems, we use one-to-one mapping between IA-64 vector and - * IRQ. A platform can implement platform_irq_to_vector(irq) and + * (4) The kernel recognizes an interrupt as an IRQ. The IRQ interface is + * used as architecture-independent interrupt handling mechanism in Linux. + * As an IRQ is a number, we have to have + * IA-64 interrupt vector number <-> IRQ number mapping. On smaller + * systems, we use one-to-one mapping between IA-64 vector and IRQ. A + * platform can implement platform_irq_to_vector(irq) and * platform_local_vector_to_irq(vector) APIs to differentiate the mapping. * Please see also include/asm-ia64/hw_irq.h for those APIs. * @@ -64,9 +75,9 @@ * * PCI pin -> global system interrupt (GSI) -> IA-64 vector <-> IRQ * - * Note: The term "IRQ" is loosely used everywhere in Linux kernel to describe interrupts. - * Now we use "IRQ" only for Linux IRQ's. ISA IRQ (isa_irq) is the only exception in this - * source code. + * Note: The term "IRQ" is loosely used everywhere in Linux kernel to + * describeinterrupts. Now we use "IRQ" only for Linux IRQ's. ISA IRQ + * (isa_irq) is the only exception in this source code. */ #include @@ -90,7 +101,6 @@ #include #include - #undef DEBUG_INTERRUPT_ROUTING #ifdef DEBUG_INTERRUPT_ROUTING @@ -99,36 +109,46 @@ #define DBG(fmt...) #endif -#define NR_PREALLOCATE_RTE_ENTRIES (PAGE_SIZE / sizeof(struct iosapic_rte_info)) +#define NR_PREALLOCATE_RTE_ENTRIES \ + (PAGE_SIZE / sizeof(struct iosapic_rte_info)) #define RTE_PREALLOCATED (1) static DEFINE_SPINLOCK(iosapic_lock); -/* These tables map IA-64 vectors to the IOSAPIC pin that generates this vector. */ +/* + * These tables map IA-64 vectors to the IOSAPIC pin that generates this + * vector. + */ struct iosapic_rte_info { - struct list_head rte_list; /* node in list of RTEs sharing the same vector */ + struct list_head rte_list; /* node in list of RTEs sharing the + * same vector */ char __iomem *addr; /* base address of IOSAPIC */ - unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ + unsigned int gsi_base; /* first GSI assigned to this + * IOSAPIC */ char rte_index; /* IOSAPIC RTE index */ int refcnt; /* reference counter */ unsigned int flags; /* flags */ } ____cacheline_aligned; static struct iosapic_intr_info { - struct list_head rtes; /* RTEs using this vector (empty => not an IOSAPIC interrupt) */ + struct list_head rtes; /* RTEs using this vector (empty => + * not an IOSAPIC interrupt) */ int count; /* # of RTEs that shares this vector */ - u32 low32; /* current value of low word of Redirection table entry */ + u32 low32; /* current value of low word of + * Redirection table entry */ unsigned int dest; /* destination CPU physical ID */ unsigned char dmode : 3; /* delivery mode (see iosapic.h) */ - unsigned char polarity: 1; /* interrupt polarity (see iosapic.h) */ + unsigned char polarity: 1; /* interrupt polarity + * (see iosapic.h) */ unsigned char trigger : 1; /* trigger mode (see iosapic.h) */ } iosapic_intr_info[IA64_NUM_VECTORS]; static struct iosapic { char __iomem *addr; /* base address of IOSAPIC */ - unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ - unsigned short num_rte; /* number of RTE in this IOSAPIC */ + unsigned int gsi_base; /* first GSI assigned to this + * IOSAPIC */ + unsigned short num_rte; /* # of RTEs on this IOSAPIC */ int rtes_inuse; /* # of RTEs in use on this IOSAPIC */ #ifdef CONFIG_NUMA unsigned short node; /* numa node association via pxm */ @@ -149,7 +169,8 @@ find_iosapic (unsigned int gsi) int i; for (i = 0; i < NR_IOSAPICS; i++) { - if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte) + if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < + iosapic_lists[i].num_rte) return i; } @@ -162,7 +183,8 @@ _gsi_to_vector (unsigned int gsi) struct iosapic_intr_info *info; struct iosapic_rte_info *rte; - for (info = iosapic_intr_info; info < iosapic_intr_info + IA64_NUM_VECTORS; ++info) + for (info = iosapic_intr_info; info < + iosapic_intr_info + IA64_NUM_VECTORS; ++info) list_for_each_entry(rte, &info->rtes, rte_list) if (rte->gsi_base + rte->rte_index == gsi) return info - iosapic_intr_info; @@ -185,8 +207,8 @@ gsi_to_irq (unsigned int gsi) unsigned long flags; int irq; /* - * XXX fix me: this assumes an identity mapping vetween IA-64 vector and Linux irq - * numbers... + * XXX fix me: this assumes an identity mapping between IA-64 vector + * and Linux irq numbers... */ spin_lock_irqsave(&iosapic_lock, flags); { @@ -197,7 +219,8 @@ gsi_to_irq (unsigned int gsi) return irq; } -static struct iosapic_rte_info *gsi_vector_to_rte(unsigned int gsi, unsigned int vec) +static struct iosapic_rte_info *gsi_vector_to_rte(unsigned int gsi, + unsigned int vec) { struct iosapic_rte_info *rte; @@ -237,7 +260,9 @@ set_rte (unsigned int gsi, unsigned int vector, unsigned int dest, int mask) for (irq = 0; irq < NR_IRQS; ++irq) if (irq_to_vector(irq) == vector) { - set_irq_affinity_info(irq, (int)(dest & 0xffff), redir); + set_irq_affinity_info(irq, + (int)(dest & 0xffff), + redir); break; } } @@ -259,7 +284,7 @@ set_rte (unsigned int gsi, unsigned int vector, unsigned int dest, int mask) } static void -nop (unsigned int vector) +nop (unsigned int irq) { /* do nothing... */ } @@ -281,7 +306,8 @@ mask_irq (unsigned int irq) { /* set only the mask bit */ low32 = iosapic_intr_info[vec].low32 |= IOSAPIC_MASK; - list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) { + list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, + rte_list) { addr = rte->addr; rte_index = rte->rte_index; iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32); @@ -306,7 +332,8 @@ unmask_irq (unsigned int irq) spin_lock_irqsave(&iosapic_lock, flags); { low32 = iosapic_intr_info[vec].low32 &= ~IOSAPIC_MASK; - list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) { + list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, + rte_list) { addr = rte->addr; rte_index = rte->rte_index; iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32); @@ -346,21 +373,25 @@ iosapic_set_affinity (unsigned int irq, cpumask_t mask) spin_lock_irqsave(&iosapic_lock, flags); { - low32 = iosapic_intr_info[vec].low32 & ~(7 << IOSAPIC_DELIVERY_SHIFT); + low32 = iosapic_intr_info[vec].low32 & + ~(7 << IOSAPIC_DELIVERY_SHIFT); if (redir) /* change delivery mode to lowest priority */ - low32 |= (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT); + low32 |= (IOSAPIC_LOWEST_PRIORITY << + IOSAPIC_DELIVERY_SHIFT); else /* change delivery mode to fixed */ low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT); iosapic_intr_info[vec].low32 = low32; iosapic_intr_info[vec].dest = dest; - list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, rte_list) { + list_for_each_entry(rte, &iosapic_intr_info[vec].rtes, + rte_list) { addr = rte->addr; rte_index = rte->rte_index; - iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index), high32); + iosapic_write(addr, IOSAPIC_RTE_HIGH(rte_index), + high32); iosapic_write(addr, IOSAPIC_RTE_LOW(rte_index), low32); } } @@ -433,7 +464,8 @@ iosapic_ack_edge_irq (unsigned int irq) * interrupt for real. This prevents IRQ storms from unhandled * devices. */ - if ((idesc->status & (IRQ_PENDING|IRQ_DISABLED)) == (IRQ_PENDING|IRQ_DISABLED)) + if ((idesc->status & (IRQ_PENDING|IRQ_DISABLED)) == + (IRQ_PENDING|IRQ_DISABLED)) mask_irq(irq); } @@ -467,7 +499,8 @@ iosapic_version (char __iomem *addr) return iosapic_read(addr, IOSAPIC_VERSION); } -static int iosapic_find_sharable_vector (unsigned long trigger, unsigned long pol) +static int iosapic_find_sharable_vector (unsigned long trigger, + unsigned long pol) { int i, vector = -1, min_count = -1; struct iosapic_intr_info *info; @@ -482,7 +515,8 @@ static int iosapic_find_sharable_vector (unsigned long trigger, unsigned long po for (i = IA64_FIRST_DEVICE_VECTOR; i <= IA64_LAST_DEVICE_VECTOR; i++) { info = &iosapic_intr_info[i]; if (info->trigger == trigger && info->polarity == pol && - (info->dmode == IOSAPIC_FIXED || info->dmode == IOSAPIC_LOWEST_PRIORITY)) { + (info->dmode == IOSAPIC_FIXED || info->dmode == + IOSAPIC_LOWEST_PRIORITY)) { if (min_count == -1 || info->count < min_count) { vector = i; min_count = info->count; @@ -506,12 +540,15 @@ iosapic_reassign_vector (int vector) new_vector = assign_irq_vector(AUTO_ASSIGN); if (new_vector < 0) panic("%s: out of interrupt vectors!\n", __FUNCTION__); - printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector); + printk(KERN_INFO "Reassigning vector %d to %d\n", + vector, new_vector); memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector], sizeof(struct iosapic_intr_info)); INIT_LIST_HEAD(&iosapic_intr_info[new_vector].rtes); - list_move(iosapic_intr_info[vector].rtes.next, &iosapic_intr_info[new_vector].rtes); - memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info)); + list_move(iosapic_intr_info[vector].rtes.next, + &iosapic_intr_info[new_vector].rtes); + memset(&iosapic_intr_info[vector], 0, + sizeof(struct iosapic_intr_info)); iosapic_intr_info[vector].low32 = IOSAPIC_MASK; INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); } @@ -524,7 +561,8 @@ static struct iosapic_rte_info *iosapic_alloc_rte (void) int preallocated = 0; if (!iosapic_kmalloc_ok && list_empty(&free_rte_list)) { - rte = alloc_bootmem(sizeof(struct iosapic_rte_info) * NR_PREALLOCATE_RTE_ENTRIES); + rte = alloc_bootmem(sizeof(struct iosapic_rte_info) * + NR_PREALLOCATE_RTE_ENTRIES); if (!rte) return NULL; for (i = 0; i < NR_PREALLOCATE_RTE_ENTRIES; i++, rte++) @@ -532,7 +570,8 @@ static struct iosapic_rte_info *iosapic_alloc_rte (void) } if (!list_empty(&free_rte_list)) { - rte = list_entry(free_rte_list.next, struct iosapic_rte_info, rte_list); + rte = list_entry(free_rte_list.next, struct iosapic_rte_info, + rte_list); list_del(&rte->rte_list); preallocated++; } else { @@ -575,7 +614,8 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery, index = find_iosapic(gsi); if (index < 0) { - printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n", __FUNCTION__, gsi); + printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n", + __FUNCTION__, gsi); return -ENODEV; } @@ -586,7 +626,8 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery, if (!rte) { rte = iosapic_alloc_rte(); if (!rte) { - printk(KERN_WARNING "%s: cannot allocate memory\n", __FUNCTION__); + printk(KERN_WARNING "%s: cannot allocate memory\n", + __FUNCTION__); return -ENOMEM; } @@ -602,7 +643,9 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery, else if (vector_is_shared(vector)) { struct iosapic_intr_info *info = &iosapic_intr_info[vector]; if (info->trigger != trigger || info->polarity != polarity) { - printk (KERN_WARNING "%s: cannot override the interrupt\n", __FUNCTION__); + printk (KERN_WARNING + "%s: cannot override the interrupt\n", + __FUNCTION__); return -EINVAL; } } @@ -619,8 +662,10 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery, idesc = irq_descp(vector); if (idesc->handler != irq_type) { if (idesc->handler != &no_irq_type) - printk(KERN_WARNING "%s: changing vector %d from %s to %s\n", - __FUNCTION__, vector, idesc->handler->typename, irq_type->typename); + printk(KERN_WARNING + "%s: changing vector %d from %s to %s\n", + __FUNCTION__, vector, + idesc->handler->typename, irq_type->typename); idesc->handler = irq_type; } return 0; @@ -681,7 +726,7 @@ get_target_cpu (unsigned int gsi, int vector) if (!num_cpus) goto skip_numa_setup; - /* Use vector assigment to distribute across cpus in node */ + /* Use vector assignment to distribute across cpus in node */ cpu_index = vector % num_cpus; for (numa_cpu = first_cpu(cpu_mask) ; i < cpu_index ; i++) @@ -703,7 +748,7 @@ skip_numa_setup: } while (!cpu_online(cpu)); return cpu_physical_id(cpu); -#else +#else /* CONFIG_SMP */ return cpu_physical_id(smp_processor_id()); #endif } @@ -755,7 +800,8 @@ again: if (list_empty(&iosapic_intr_info[vector].rtes)) free_irq_vector(vector); spin_unlock(&iosapic_lock); - spin_unlock_irqrestore(&irq_descp(vector)->lock, flags); + spin_unlock_irqrestore(&irq_descp(vector)->lock, + flags); goto again; } @@ -764,7 +810,8 @@ again: polarity, trigger); if (err < 0) { spin_unlock(&iosapic_lock); - spin_unlock_irqrestore(&irq_descp(vector)->lock, flags); + spin_unlock_irqrestore(&irq_descp(vector)->lock, + flags); return err; } @@ -806,7 +853,8 @@ iosapic_unregister_intr (unsigned int gsi) */ irq = gsi_to_irq(gsi); if (irq < 0) { - printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n", gsi); + printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n", + gsi); WARN_ON(1); return; } @@ -817,7 +865,9 @@ iosapic_unregister_intr (unsigned int gsi) spin_lock(&iosapic_lock); { if ((rte = gsi_vector_to_rte(gsi, vector)) == NULL) { - printk(KERN_ERR "iosapic_unregister_intr(%u) unbalanced\n", gsi); + printk(KERN_ERR + "iosapic_unregister_intr(%u) unbalanced\n", + gsi); WARN_ON(1); goto out; } @@ -827,7 +877,8 @@ iosapic_unregister_intr (unsigned int gsi) /* Mask the interrupt */ low32 = iosapic_intr_info[vector].low32 | IOSAPIC_MASK; - iosapic_write(rte->addr, IOSAPIC_RTE_LOW(rte->rte_index), low32); + iosapic_write(rte->addr, IOSAPIC_RTE_LOW(rte->rte_index), + low32); /* Remove the rte entry from the list */ list_del(&rte->rte_list); @@ -840,7 +891,9 @@ iosapic_unregister_intr (unsigned int gsi) trigger = iosapic_intr_info[vector].trigger; polarity = iosapic_intr_info[vector].polarity; dest = iosapic_intr_info[vector].dest; - printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d unregistered\n", + printk(KERN_INFO + "GSI %u (%s, %s) -> CPU %d (0x%04x)" + " vector %d unregistered\n", gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), cpu_logical_id(dest), dest, vector); @@ -853,12 +906,15 @@ iosapic_unregister_intr (unsigned int gsi) idesc->handler = &no_irq_type; /* Clear the interrupt information */ - memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info)); + memset(&iosapic_intr_info[vector], 0, + sizeof(struct iosapic_intr_info)); iosapic_intr_info[vector].low32 |= IOSAPIC_MASK; INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); if (idesc->action) { - printk(KERN_ERR "interrupt handlers still exist on IRQ %u\n", irq); + printk(KERN_ERR + "interrupt handlers still exist on" + "IRQ %u\n", irq); WARN_ON(1); } @@ -873,7 +929,6 @@ iosapic_unregister_intr (unsigned int gsi) /* * ACPI calls this when it finds an entry for a platform interrupt. - * Note that the irq_base and IOSAPIC address must be set in iosapic_init(). */ int __init iosapic_register_platform_intr (u32 int_type, unsigned int gsi, @@ -907,13 +962,16 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi, mask = 1; break; default: - printk(KERN_ERR "iosapic_register_platform_irq(): invalid int type 0x%x\n", int_type); + printk(KERN_ERR "%s: invalid int type 0x%x\n", __FUNCTION__, + int_type); return -1; } register_intr(gsi, vector, delivery, polarity, trigger); - printk(KERN_INFO "PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n", + printk(KERN_INFO + "PLATFORM int %s (0x%x): GSI %u (%s, %s) -> CPU %d (0x%04x)" + " vector %d\n", int_type < ARRAY_SIZE(name) ? name[int_type] : "unknown", int_type, gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), (polarity == IOSAPIC_POL_HIGH ? "high" : "low"), @@ -923,10 +981,8 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi, return vector; } - /* * ACPI calls this when it finds an entry for a legacy ISA IRQ override. - * Note that the gsi_base and IOSAPIC address must be set in iosapic_init(). */ void __init iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi, @@ -955,16 +1011,19 @@ iosapic_system_init (int system_pcat_compat) for (vector = 0; vector < IA64_NUM_VECTORS; ++vector) { iosapic_intr_info[vector].low32 = IOSAPIC_MASK; - INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); /* mark as unused */ + /* mark as unused */ + INIT_LIST_HEAD(&iosapic_intr_info[vector].rtes); } pcat_compat = system_pcat_compat; if (pcat_compat) { /* - * Disable the compatibility mode interrupts (8259 style), needs IN/OUT support - * enabled. + * Disable the compatibility mode interrupts (8259 style), + * needs IN/OUT support enabled. */ - printk(KERN_INFO "%s: Disabling PC-AT compatible 8259 interrupts\n", __FUNCTION__); + printk(KERN_INFO + "%s: Disabling PC-AT compatible 8259 interrupts\n", + __FUNCTION__); outb(0xff, 0xA1); outb(0xff, 0x21); } @@ -1053,12 +1112,14 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base) if ((gsi_base == 0) && pcat_compat) { /* - * Map the legacy ISA devices into the IOSAPIC data. Some of these may - * get reprogrammed later on with data from the ACPI Interrupt Source - * Override table. + * Map the legacy ISA devices into the IOSAPIC data. Some of + * these may get reprogrammed later on with data from the ACPI + * Interrupt Source Override table. */ for (isa_irq = 0; isa_irq < 16; ++isa_irq) - iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE); + iosapic_override_isa_irq(isa_irq, isa_irq, + IOSAPIC_POL_HIGH, + IOSAPIC_EDGE); } return 0; } @@ -1081,7 +1142,8 @@ iosapic_remove (unsigned int gsi_base) if (iosapic_lists[index].rtes_inuse) { err = -EBUSY; - printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n", + printk(KERN_WARNING + "%s: IOSAPIC for GSI base %u is busy\n", __FUNCTION__, gsi_base); goto out; } -- cgit v1.2.3 From e6d1ba5cd9954e7c15538aaef7585b235a69e0e1 Mon Sep 17 00:00:00 2001 From: Satoru Takeuchi Date: Mon, 27 Mar 2006 17:13:46 +0900 Subject: [IA64] simplify some condition checks in iosapic_check_gsi_range Some condition checks on iosapic_check_gsi_range() can be omitted because always `base <= end' is assured. This patch simplifies those checks. Signed-off-by: Satoru Takeuchi Signed-off-by: Tony Luck --- arch/ia64/kernel/iosapic.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 22d845f8536..7956eb9058f 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -1063,10 +1063,7 @@ iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver) base = iosapic_lists[index].gsi_base; end = base + iosapic_lists[index].num_rte - 1; - if (gsi_base < base && gsi_end < base) - continue;/* OK */ - - if (gsi_base > end && gsi_end > end) + if (gsi_end < base || end < gsi_base) continue; /* OK */ return -EBUSY; -- cgit v1.2.3 From d89cfe7f1e82d758a7983584c1593795d4e2c098 Mon Sep 17 00:00:00 2001 From: Russ Anderson Date: Wed, 29 Mar 2006 11:31:23 -0600 Subject: [IA64] Move __mca_table out of the __init section Move __mca_table out of the __init section. Signed-off-by: Tony Luck --- arch/ia64/kernel/vmlinux.lds.S | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index 0b9e56dd7f0..783600fe52b 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S @@ -70,6 +70,15 @@ SECTIONS __stop___ex_table = .; } + /* MCA table */ + . = ALIGN(16); + __mca_table : AT(ADDR(__mca_table) - LOAD_OFFSET) + { + __start___mca_table = .; + *(__mca_table) + __stop___mca_table = .; + } + /* Global data */ _data = .; @@ -130,15 +139,6 @@ SECTIONS __initcall_end = .; } - /* MCA table */ - . = ALIGN(16); - __mca_table : AT(ADDR(__mca_table) - LOAD_OFFSET) - { - __start___mca_table = .; - *(__mca_table) - __stop___mca_table = .; - } - .data.patch.vtop : AT(ADDR(.data.patch.vtop) - LOAD_OFFSET) { __start___vtop_patchlist = .; -- cgit v1.2.3 From 3283a67d8618c9a292eced23e8753ab64adc6dba Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Thu, 30 Mar 2006 10:13:22 -0500 Subject: [IA64] Add __mca_table to the DISCARD list in gate.lds Add __mca_table to the DISCARD list for the gate.lds linker script to avoid broken linker references when linking the final vmlinux file. Also add comment to include/asm-ia64/asmmacros.h to avoid anyone else hitting this problem in the future. Credits to James Bottomley for spotting the DISCARD list in gate.lds.S Signed-off-by: Jes Sorensen Signed-off-by: Tony Luck --- arch/ia64/kernel/gate.lds.S | 1 + include/asm-ia64/asmmacro.h | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/arch/ia64/kernel/gate.lds.S b/arch/ia64/kernel/gate.lds.S index e1e4aba9ecd..7c99e6ec3da 100644 --- a/arch/ia64/kernel/gate.lds.S +++ b/arch/ia64/kernel/gate.lds.S @@ -59,6 +59,7 @@ SECTIONS *(.dynbss) *(.bss .bss.* .gnu.linkonce.b.*) *(__ex_table) + *(__mca_table) } } diff --git a/include/asm-ia64/asmmacro.h b/include/asm-ia64/asmmacro.h index d4cec32083d..edf2cebb296 100644 --- a/include/asm-ia64/asmmacro.h +++ b/include/asm-ia64/asmmacro.h @@ -38,6 +38,10 @@ name: /* * Helper macros for accessing user memory. + * + * When adding any new .section/.previous entries here, make sure to + * also add it to the DISCARD section in arch/ia64/kernel/gate.lds.S or + * unpleasant things will happen. */ .section "__ex_table", "a" // declare section & section attributes -- cgit v1.2.3 From c1c57d767100417f63c18da52d7e96f82b2b9e1a Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 30 Mar 2006 09:53:39 -0700 Subject: [IA64] ioremap() should prefer WB over UC efi_memmap_init() collects full granules of WB memory, without regard for whether they also support UC. So in order for ioremap() to work for main memory, it must prefer WB mappings when possible. Signed-off-by: Bjorn Helgaas Signed-off-by: Tony Luck --- arch/ia64/mm/ioremap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/ia64/mm/ioremap.c b/arch/ia64/mm/ioremap.c index 62328621f99..643ccc6960c 100644 --- a/arch/ia64/mm/ioremap.c +++ b/arch/ia64/mm/ioremap.c @@ -21,12 +21,12 @@ __ioremap (unsigned long offset, unsigned long size) void __iomem * ioremap (unsigned long offset, unsigned long size) { - if (efi_mem_attribute_range(offset, size, EFI_MEMORY_UC)) - return __ioremap(offset, size); - if (efi_mem_attribute_range(offset, size, EFI_MEMORY_WB)) return phys_to_virt(offset); + if (efi_mem_attribute_range(offset, size, EFI_MEMORY_UC)) + return __ioremap(offset, size); + /* * Someday this should check ACPI resources so we * can do the right thing for hot-plugged regions. -- cgit v1.2.3