From e617fce64e5faea149fcf3bffc1b42e4ba29e7e5 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Fri, 25 Apr 2008 23:13:09 +0900 Subject: [IA64] bugfix: nptcg breaks cpu-hotadd If "max_purges" from PAL is 0, it actually means 1. However it was not handled later when a hot-added cpu pass the max_purges from PAL. This makes systems easy to go BUG_ON(). Signed-off-by: Hidetoshi Seto Signed-off-by: Tony Luck --- arch/ia64/mm/tlb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c index d52ec4e83409..8caf42471f0d 100644 --- a/arch/ia64/mm/tlb.c +++ b/arch/ia64/mm/tlb.c @@ -168,7 +168,10 @@ setup_ptcg_sem(int max_purges, int nptcg_from) static int firstcpu = 1; if (toolatetochangeptcgsem) { - BUG_ON(max_purges < nptcg); + if (nptcg_from == NPTCG_FROM_PAL && max_purges == 0) + BUG_ON(1 < nptcg); + else + BUG_ON(max_purges < nptcg); return; } -- cgit v1.2.3 From e4a064dfa2b242519a9f06f9a1e58c27bf0c371b Mon Sep 17 00:00:00 2001 From: Dean Nelson Date: Fri, 25 Apr 2008 15:22:19 -0500 Subject: [IA64] allocate multiple contiguous pages via uncached allocator Enable the uncached allocator to allocate multiple pages of contiguous uncached memory. Signed-off-by: Dean Nelson Signed-off-by: Tony Luck --- arch/ia64/kernel/uncached.c | 23 +++++++++++++---------- drivers/char/mspec.c | 12 ++++++------ drivers/misc/sgi-xp/xpc_partition.c | 4 ++-- include/asm-ia64/uncached.h | 6 +++--- 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c index 2a90c32024f4..e77995a6e3ed 100644 --- a/arch/ia64/kernel/uncached.c +++ b/arch/ia64/kernel/uncached.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2006 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2008 Silicon Graphics, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License @@ -177,12 +177,13 @@ failed: * uncached_alloc_page * * @starting_nid: node id of node to start with, or -1 + * @n_pages: number of contiguous pages to allocate * - * Allocate 1 uncached page. Allocates on the requested node. If no - * uncached pages are available on the requested node, roundrobin starting - * with the next higher node. + * Allocate the specified number of contiguous uncached pages on the + * the requested node. If not enough contiguous uncached pages are available + * on the requested node, roundrobin starting with the next higher node. */ -unsigned long uncached_alloc_page(int starting_nid) +unsigned long uncached_alloc_page(int starting_nid, int n_pages) { unsigned long uc_addr; struct uncached_pool *uc_pool; @@ -202,7 +203,8 @@ unsigned long uncached_alloc_page(int starting_nid) if (uc_pool->pool == NULL) continue; do { - uc_addr = gen_pool_alloc(uc_pool->pool, PAGE_SIZE); + uc_addr = gen_pool_alloc(uc_pool->pool, + n_pages * PAGE_SIZE); if (uc_addr != 0) return uc_addr; } while (uncached_add_chunk(uc_pool, nid) == 0); @@ -217,11 +219,12 @@ EXPORT_SYMBOL(uncached_alloc_page); /* * uncached_free_page * - * @uc_addr: uncached address of page to free + * @uc_addr: uncached address of first page to free + * @n_pages: number of contiguous pages to free * - * Free a single uncached page. + * Free the specified number of uncached pages. */ -void uncached_free_page(unsigned long uc_addr) +void uncached_free_page(unsigned long uc_addr, int n_pages) { int nid = paddr_to_nid(uc_addr - __IA64_UNCACHED_OFFSET); struct gen_pool *pool = uncached_pools[nid].pool; @@ -232,7 +235,7 @@ void uncached_free_page(unsigned long uc_addr) if ((uc_addr & (0XFUL << 60)) != __IA64_UNCACHED_OFFSET) panic("uncached_free_page invalid address %lx\n", uc_addr); - gen_pool_free(pool, uc_addr, PAGE_SIZE); + gen_pool_free(pool, uc_addr, n_pages * PAGE_SIZE); } EXPORT_SYMBOL(uncached_free_page); diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c index ff146c2b08fd..fe2a95b5d3c0 100644 --- a/drivers/char/mspec.c +++ b/drivers/char/mspec.c @@ -180,7 +180,7 @@ mspec_close(struct vm_area_struct *vma) my_page = vdata->maddr[index]; vdata->maddr[index] = 0; if (!mspec_zero_block(my_page, PAGE_SIZE)) - uncached_free_page(my_page); + uncached_free_page(my_page, 1); else printk(KERN_WARNING "mspec_close(): " "failed to zero page %ld\n", my_page); @@ -209,7 +209,7 @@ mspec_nopfn(struct vm_area_struct *vma, unsigned long address) index = (address - vdata->vm_start) >> PAGE_SHIFT; maddr = (volatile unsigned long) vdata->maddr[index]; if (maddr == 0) { - maddr = uncached_alloc_page(numa_node_id()); + maddr = uncached_alloc_page(numa_node_id(), 1); if (maddr == 0) return NOPFN_OOM; @@ -218,7 +218,7 @@ mspec_nopfn(struct vm_area_struct *vma, unsigned long address) vdata->count++; vdata->maddr[index] = maddr; } else { - uncached_free_page(maddr); + uncached_free_page(maddr, 1); maddr = vdata->maddr[index]; } spin_unlock(&vdata->lock); @@ -367,7 +367,7 @@ mspec_init(void) int nasid; unsigned long phys; - scratch_page[nid] = uncached_alloc_page(nid); + scratch_page[nid] = uncached_alloc_page(nid, 1); if (scratch_page[nid] == 0) goto free_scratch_pages; phys = __pa(scratch_page[nid]); @@ -414,7 +414,7 @@ mspec_init(void) free_scratch_pages: for_each_node(nid) { if (scratch_page[nid] != 0) - uncached_free_page(scratch_page[nid]); + uncached_free_page(scratch_page[nid], 1); } return ret; } @@ -431,7 +431,7 @@ mspec_exit(void) for_each_node(nid) { if (scratch_page[nid] != 0) - uncached_free_page(scratch_page[nid]); + uncached_free_page(scratch_page[nid], 1); } } } diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c index 27e200ec5826..acd3fd4285d7 100644 --- a/drivers/misc/sgi-xp/xpc_partition.c +++ b/drivers/misc/sgi-xp/xpc_partition.c @@ -211,7 +211,7 @@ xpc_rsvd_page_init(void) */ amos_page = xpc_vars->amos_page; if (amos_page == NULL) { - amos_page = (AMO_t *)TO_AMO(uncached_alloc_page(0)); + amos_page = (AMO_t *)TO_AMO(uncached_alloc_page(0, 1)); if (amos_page == NULL) { dev_err(xpc_part, "can't allocate page of AMOs\n"); return NULL; @@ -230,7 +230,7 @@ xpc_rsvd_page_init(void) dev_err(xpc_part, "can't change memory " "protections\n"); uncached_free_page(__IA64_UNCACHED_OFFSET | - TO_PHYS((u64)amos_page)); + TO_PHYS((u64)amos_page), 1); return NULL; } } diff --git a/include/asm-ia64/uncached.h b/include/asm-ia64/uncached.h index b82d923b73c1..13d7e65ca3cc 100644 --- a/include/asm-ia64/uncached.h +++ b/include/asm-ia64/uncached.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2005 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2008 Silicon Graphics, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License @@ -8,5 +8,5 @@ * Prototypes for the uncached page allocator */ -extern unsigned long uncached_alloc_page(int nid); -extern void uncached_free_page(unsigned long); +extern unsigned long uncached_alloc_page(int starting_nid, int n_pages); +extern void uncached_free_page(unsigned long uc_addr, int n_pages); -- cgit v1.2.3 From 6ff0bc94eee96fe45e5caa338c8b03cb99431fa9 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Thu, 24 Apr 2008 12:57:08 -0600 Subject: [IA64] Remove printk noise on unimplemented SAL_PHYSICAL_ID_INFO Commit 113134fcbca83619be4c68d0ca66db6093777b5d changed the flow of control when calling PAL_LOGICAL_TO_PHYSICAL and SAL_PHYSICAL_ID_INFO. With the change, if a platform did not implement the latter, a useless printk would appear in the boot log: ia64_sal_pltid failed with -1 So let's check the return code and only printk on a true error, and do not print anything in the unimplemented case. While we're in there, clean up some stylistic issues too. Signed-off-by: Alex Chiang Signed-off-by: Tony Luck --- arch/ia64/kernel/smpboot.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 16483be18c0b..d7ad42b77d41 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -873,7 +873,8 @@ identify_siblings(struct cpuinfo_ia64 *c) u16 pltid; pal_logical_to_physical_t info; - if ((status = ia64_pal_logical_to_phys(-1, &info)) != PAL_STATUS_SUCCESS) { + status = ia64_pal_logical_to_phys(-1, &info); + if (status != PAL_STATUS_SUCCESS) { if (status != PAL_STATUS_UNIMPLEMENTED) { printk(KERN_ERR "ia64_pal_logical_to_phys failed with %ld\n", @@ -885,8 +886,13 @@ identify_siblings(struct cpuinfo_ia64 *c) info.overview_cpp = 1; info.overview_tpc = 1; } - if ((status = ia64_sal_physical_id_info(&pltid)) != PAL_STATUS_SUCCESS) { - printk(KERN_ERR "ia64_sal_pltid failed with %ld\n", status); + + status = ia64_sal_physical_id_info(&pltid); + if (status != PAL_STATUS_SUCCESS) { + if (status != PAL_STATUS_UNIMPLEMENTED) + printk(KERN_ERR + "ia64_sal_pltid failed with %ld\n", + status); return; } -- cgit v1.2.3 From fe086a7bea7ab714930bd48addba961ceeef7634 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Tue, 29 Apr 2008 15:05:29 -0700 Subject: [IA64] Provide ACPI fixup for /proc/cpuinfo/physical_id Legacy HP ia64 platforms currently cannot provide /proc/cpuinfo/physical_id due to legacy SAL/PAL implementations. However, that physical topology information can be obtained via ACPI. Provide an interface that gives ACPI one last chance to provide physical_id for these legacy platforms. This logic only comes into play iff: - ACPI actually provides slot information for the CPU - we lack a valid socket_id Otherwise, we don't do anything. Since x86 uses the ACPI processor driver as well, we provide a nop stub function for arch_fix_phys_package_id() in asm-x86/topology.h Signed-off-by: Alex Chiang Signed-off-by: Tony Luck --- arch/ia64/kernel/topology.c | 9 +++++++++ drivers/acpi/processor_core.c | 9 +++++++++ include/asm-ia64/topology.h | 2 ++ include/asm-x86/topology.h | 4 ++++ 4 files changed, 24 insertions(+) diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c index a2484fc1a06c..abb17a613b17 100644 --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c @@ -27,6 +27,15 @@ static struct ia64_cpu *sysfs_cpus; +void arch_fix_phys_package_id(int num, u32 slot) +{ +#ifdef CONFIG_SMP + if (cpu_data(num)->socket_id == -1) + cpu_data(num)->socket_id = slot; +#endif +} +EXPORT_SYMBOL_GPL(arch_fix_phys_package_id); + int arch_register_cpu(int num) { #if defined (CONFIG_ACPI) && defined (CONFIG_HOTPLUG_CPU) diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index dd28c912e84f..5241e3ff5080 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -603,6 +603,15 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) request_region(pr->throttling.address, 6, "ACPI CPU throttle"); } + /* + * If ACPI describes a slot number for this CPU, we can use it + * ensure we get the right value in the "physical id" field + * of /proc/cpuinfo + */ + status = acpi_evaluate_object(pr->handle, "_SUN", NULL, &buffer); + if (ACPI_SUCCESS(status)) + arch_fix_phys_package_id(pr->id, object.integer.value); + return 0; } diff --git a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h index f2f72ef2a897..32863b3bb1d3 100644 --- a/include/asm-ia64/topology.h +++ b/include/asm-ia64/topology.h @@ -116,6 +116,8 @@ void build_cpu_to_node_map(void); #define smt_capable() (smp_num_siblings > 1) #endif +extern void arch_fix_phys_package_id(int num, u32 slot); + #define pcibus_to_cpumask(bus) (pcibus_to_node(bus) == -1 ? \ CPU_MASK_ALL : \ node_to_cpumask(pcibus_to_node(bus)) \ diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h index 0e6d6b03affe..4f35a0fb4f22 100644 --- a/include/asm-x86/topology.h +++ b/include/asm-x86/topology.h @@ -193,6 +193,10 @@ extern cpumask_t cpu_coregroup_map(int cpu); #define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu)) #endif +static inline void arch_fix_phys_package_id(int num, u32 slot) +{ +} + struct pci_bus; void set_pci_bus_resources_arch_default(struct pci_bus *b); -- cgit v1.2.3