From 2224661494278bfc1c35b392cf6ee6f58e1d5e64 Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Tue, 6 May 2008 15:18:57 -0500 Subject: [IA64] machvec support for SGI UV platform This patch adds the basic IA64 machvec infrastructure to support the SGI "UV" platform. Signed-off-by: Jack Steiner Signed-off-by: Tony Luck --- arch/ia64/Kconfig | 13 ++++++ arch/ia64/Makefile | 2 +- arch/ia64/kernel/acpi.c | 7 +++- arch/ia64/uv/Makefile | 12 ++++++ arch/ia64/uv/kernel/Makefile | 13 ++++++ arch/ia64/uv/kernel/machvec.c | 11 +++++ arch/ia64/uv/kernel/setup.c | 98 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 arch/ia64/uv/Makefile create mode 100644 arch/ia64/uv/kernel/Makefile create mode 100644 arch/ia64/uv/kernel/machvec.c create mode 100644 arch/ia64/uv/kernel/setup.c (limited to 'arch') diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 0df5f6f75ed..16be41446b5 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -135,6 +135,7 @@ config IA64_GENERIC HP-zx1/sx1000 For HP systems HP-zx1/sx1000+swiotlb For HP systems with (broken) DMA-constrained devices. SGI-SN2 For SGI Altix systems + SGI-UV For SGI UV systems Ski-simulator For the HP simulator If you don't know what to do, choose "generic". @@ -170,6 +171,18 @@ config IA64_SGI_SN2 to select this option. If in doubt, select ia64 generic support instead. +config IA64_SGI_UV` + bool "SGI-UV`" + select NUMA + select ACPI_NUMA + select SWIOTLB + help + Selecting this option will optimize the kernel for use on UV based + systems, but the resulting kernel binary will not run on other + types of ia64 systems. If you have an SGI UV system, it's safe + to select this option. If in doubt, select ia64 generic support + instead. + config IA64_HP_SIM bool "Ski-simulator" select SWIOTLB diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index ec4cca477f4..88f1a55c6c9 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -63,7 +63,7 @@ drivers-$(CONFIG_PCI) += arch/ia64/pci/ drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/ drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ drivers-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ -drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ arch/ia64/sn/ +drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ arch/ia64/sn/ arch/ia64/uv/ drivers-$(CONFIG_OPROFILE) += arch/ia64/oprofile/ boot := arch/ia64/hp/sim/boot diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 19709a07963..6ff6815d34e 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -117,7 +117,10 @@ acpi_get_sysname(void) if (!strcmp(hdr->oem_id, "HP")) { return "hpzx1"; } else if (!strcmp(hdr->oem_id, "SGI")) { - return "sn2"; + if (!strcmp(hdr->oem_table_id + 4, "UV")) + return "uv"; + else + return "sn2"; } return "dig"; @@ -130,6 +133,8 @@ acpi_get_sysname(void) return "hpzx1_swiotlb"; # elif defined (CONFIG_IA64_SGI_SN2) return "sn2"; +# elif defined (CONFIG_IA64_SGI_UV) + return "uv"; # elif defined (CONFIG_IA64_DIG) return "dig"; # else diff --git a/arch/ia64/uv/Makefile b/arch/ia64/uv/Makefile new file mode 100644 index 00000000000..aa9f91947c4 --- /dev/null +++ b/arch/ia64/uv/Makefile @@ -0,0 +1,12 @@ +# arch/ia64/uv/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 2008 Silicon Graphics, Inc. All Rights Reserved. +# +# Makefile for the sn uv subplatform +# + +obj-y += kernel/ diff --git a/arch/ia64/uv/kernel/Makefile b/arch/ia64/uv/kernel/Makefile new file mode 100644 index 00000000000..8d92b4684d8 --- /dev/null +++ b/arch/ia64/uv/kernel/Makefile @@ -0,0 +1,13 @@ +# arch/ia64/uv/kernel/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 2008 Silicon Graphics, Inc. All Rights Reserved. +# + +EXTRA_CFLAGS += -Iarch/ia64/sn/include + +obj-y += setup.o +obj-$(CONFIG_IA64_GENERIC) += machvec.o diff --git a/arch/ia64/uv/kernel/machvec.c b/arch/ia64/uv/kernel/machvec.c new file mode 100644 index 00000000000..50737a9dca7 --- /dev/null +++ b/arch/ia64/uv/kernel/machvec.c @@ -0,0 +1,11 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved. + */ + +#define MACHVEC_PLATFORM_NAME uv +#define MACHVEC_PLATFORM_HEADER +#include diff --git a/arch/ia64/uv/kernel/setup.c b/arch/ia64/uv/kernel/setup.c new file mode 100644 index 00000000000..9aa743203c3 --- /dev/null +++ b/arch/ia64/uv/kernel/setup.c @@ -0,0 +1,98 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * SGI UV Core Functions + * + * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include + +DEFINE_PER_CPU(struct uv_hub_info_s, __uv_hub_info); +EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info); + + +struct redir_addr { + unsigned long redirect; + unsigned long alias; +}; + +#define DEST_SHIFT UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR_DEST_BASE_SHFT + +static __initdata struct redir_addr redir_addrs[] = { + {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_0_MMR, UVH_SI_ALIAS0_OVERLAY_CONFIG}, + {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_1_MMR, UVH_SI_ALIAS1_OVERLAY_CONFIG}, + {UVH_RH_GAM_ALIAS210_REDIRECT_CONFIG_2_MMR, UVH_SI_ALIAS2_OVERLAY_CONFIG}, +}; + +static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size) +{ + union uvh_si_alias0_overlay_config_u alias; + union uvh_rh_gam_alias210_redirect_config_2_mmr_u redirect; + int i; + + for (i = 0; i < ARRAY_SIZE(redir_addrs); i++) { + alias.v = uv_read_local_mmr(redir_addrs[i].alias); + if (alias.s.base == 0) { + *size = (1UL << alias.s.m_alias); + redirect.v = uv_read_local_mmr(redir_addrs[i].redirect); + *base = (unsigned long)redirect.s.dest_base << DEST_SHIFT; + return; + } + } + BUG(); +} + +void __init uv_setup(char **cmdline_p) +{ + union uvh_si_addr_map_config_u m_n_config; + union uvh_node_id_u node_id; + unsigned long gnode_upper; + int nid, cpu, m_val, n_val; + unsigned long mmr_base, lowmem_redir_base, lowmem_redir_size; + + if (IS_MEDUSA()) { + lowmem_redir_base = 0; + lowmem_redir_size = 0; + node_id.v = 0; + m_n_config.s.m_skt = 37; + m_n_config.s.n_skt = 0; + mmr_base = 0; + } else { + get_lowmem_redirect(&lowmem_redir_base, &lowmem_redir_size); + node_id.v = uv_read_local_mmr(UVH_NODE_ID); + m_n_config.v = uv_read_local_mmr(UVH_SI_ADDR_MAP_CONFIG); + mmr_base = + uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) & + ~UV_MMR_ENABLE; + } + + m_val = m_n_config.s.m_skt; + n_val = m_n_config.s.n_skt; + printk(KERN_DEBUG "UV: global MMR base 0x%lx\n", mmr_base); + + gnode_upper = (((unsigned long)node_id.s.node_id) & + ~((1 << n_val) - 1)) << m_val; + + for_each_present_cpu(cpu) { + nid = cpu_to_node(cpu); + uv_cpu_hub_info(cpu)->lowmem_remap_base = lowmem_redir_base; + uv_cpu_hub_info(cpu)->lowmem_remap_top = + lowmem_redir_base + lowmem_redir_size; + uv_cpu_hub_info(cpu)->m_val = m_val; + uv_cpu_hub_info(cpu)->n_val = m_val; + uv_cpu_hub_info(cpu)->pnode_mask = (1 << n_val) -1; + uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1; + uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper; + uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base; + uv_cpu_hub_info(cpu)->coherency_domain_number = 0;/* ZZZ */ + printk(KERN_DEBUG "UV cpu %d, nid %d\n", cpu, nid); + } +} + -- cgit v1.2.3 From 8a3360f06cd4d3b1d57f73e029f2f8b6057fdcba Mon Sep 17 00:00:00 2001 From: Bernhard Walle Date: Wed, 14 May 2008 15:40:40 -0700 Subject: [IA64] Don't reserve crashkernel memory > 4 GB Some IA64 machines map all cell-local memory above 4 GB (32 bit limit). However, in most cases, the kernel needs some memory below that limit that is DMA-capable. So in this machine configuration, the crashkernel will be reserved above 4 GB. For machines that use SWIOTLB implementation because they lack an I/O MMU the low memory is required by the SWIOTLB implementation. In that case, it doesn't make sense to reserve the crashkernel at all because it's unusable for kdump. A special case is the "hpzx1" machine vector. In theory, it has a I/O MMU, so it can be booted above 4 GB. However, in the kdump case that is not possible because of changeset 51b58e3e26ebfb8cd56825c4b396ed251f51dec9: On HP zx1 machines, the 'machvec=dig' parameter is needed for the kdump kernel to avoid problems with the HP sba iommu. The problem is that during the boot of the kdump kernel, the iommu is re-initialized, so in-flight DMA from improperly shutdown drivers causes an IOTLB miss which leads to an MCA. With kdump, the idea is to get into the kdump kernel with as little code as we can, so shutting down drivers properly is not an option. The workaround is to add 'machvec=dig' to the kdump kernel boot parameters. This makes the kdump kernel avoid using the sba iommu altogether, leaving the IOTLB intact. Any ongoing DMA falls harmlessly outside the kdump kernel. After the kdump kernel reboots, all devices will have been shutdown properly and DMA stopped. This patch pushes that functionality into the sba iommu initialization code, so that users won't have to find the obscure documentation telling them about 'machvec=dig'. This means that also for hpzx1 it's not possible to boot when all memory is above the 4 GB limit. So the only machine vectors that can handle this case are "sn2" and "uv". Signed-off-by: Bernhard Walle Signed-off-by: Tony Luck --- arch/ia64/kernel/setup.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'arch') diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 5015ca1275c..e9596cd0cda 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -239,6 +239,25 @@ __initcall(register_memory); #ifdef CONFIG_KEXEC + +/* + * This function checks if the reserved crashkernel is allowed on the specific + * IA64 machine flavour. Machines without an IO TLB use swiotlb and require + * some memory below 4 GB (i.e. in 32 bit area), see the implementation of + * lib/swiotlb.c. The hpzx1 architecture has an IO TLB but cannot use that + * in kdump case. See the comment in sba_init() in sba_iommu.c. + * + * So, the only machvec that really supports loading the kdump kernel + * over 4 GB is "sn2". + */ +static int __init check_crashkernel_memory(unsigned long pbase, size_t size) +{ + if (ia64_platform_is("sn2") || ia64_platform_is("uv")) + return 1; + else + return pbase < (1UL << 32); +} + static void __init setup_crashkernel(unsigned long total, int *n) { unsigned long long base = 0, size = 0; @@ -252,6 +271,16 @@ static void __init setup_crashkernel(unsigned long total, int *n) base = kdump_find_rsvd_region(size, rsvd_region, *n); } + + if (!check_crashkernel_memory(base, size)) { + pr_warning("crashkernel: There would be kdump memory " + "at %ld GB but this is unusable because it " + "must\nbe below 4 GB. Change the memory " + "configuration of the machine.\n", + (unsigned long)(base >> 30)); + return; + } + if (base != ~0UL) { printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " "for crashkernel (System RAM: %ldMB)\n", -- cgit v1.2.3 From f13ae30e1397e3bfb38feb3b6e889af5d021f13d Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Thu, 8 May 2008 14:03:23 -0600 Subject: [IA64] allow user to force_pal_cache_flush The sequence executed in check_sal_cache_flush: - pend a timer interrupt - call SAL_CACHE_FLUSH - see if interrupt is still pending can hang HP machines with buggy SAL_CACHE_FLUSH implementations. Provide a kernel command-line argument to allow users skip this check if desired. Using this parameter will force ia64_sal_cache_flush to call ia64_pal_cache_flush() instead of SAL_CACHE_FLUSH. Signed-off-by: Alex Chiang Signed-off-by: Tony Luck --- arch/ia64/kernel/sal.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch') diff --git a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c index a3022dc48ef..7e0259709c0 100644 --- a/arch/ia64/kernel/sal.c +++ b/arch/ia64/kernel/sal.c @@ -229,6 +229,14 @@ static void __init sal_desc_ap_wakeup(void *p) { } */ static int sal_cache_flush_drops_interrupts; +static int __init +force_pal_cache_flush(char *str) +{ + sal_cache_flush_drops_interrupts = 1; + return 0; +} +early_param("force_pal_cache_flush", force_pal_cache_flush); + void __init check_sal_cache_flush (void) { @@ -237,6 +245,9 @@ check_sal_cache_flush (void) u64 vector, cache_type = 3; struct ia64_sal_retval isrv; + if (sal_cache_flush_drops_interrupts) + return; + cpu = get_cpu(); local_irq_save(flags); -- cgit v1.2.3 From 3633c7308005e8c1dab594f69ef904424f8b639a Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Fri, 9 May 2008 15:26:35 +0900 Subject: [IA64] fix interrupt masking for pending works on kernel leave [Bug-fix for "[BUG?][2.6.25-mm1] sleeping during IRQ disabled"] This patch does: - enable interrupts before calling schedule() as same as others, ex. x86 - enable interrupts during ia64_do_signal() and ia64_sync_krbs() - do_notify_resume_user() is still called with interrupts disabled, since we can take short path of fsys_mode if-statement quickly. - pfm_handle_work() is also called with interrupts disabled, since it can deal interrupt mask within itself. - fix/add some comments/notes Reported-by: KOSAKI Motohiro Signed-off-by: Hidetoshi Seto Signed-off-by: Tony Luck --- arch/ia64/kernel/entry.S | 14 ++++++++++---- arch/ia64/kernel/process.c | 25 +++++++++++++++++++++---- 2 files changed, 31 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index e49ad8c5dc6..ef6b0313c85 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -1156,6 +1156,9 @@ skip_rbs_switch: * r31 = current->thread_info->flags * On exit: * p6 = TRUE if work-pending-check needs to be redone + * + * Interrupts are disabled on entry, reenabled depend on work, and + * disabled on exit. */ .work_pending_syscall: add r2=-8,r2 @@ -1170,8 +1173,8 @@ skip_rbs_switch: (pKStk) dep r21=-1,r0,PREEMPT_ACTIVE_BIT,1 ;; (pKStk) st4 [r20]=r21 - ssm psr.i // enable interrupts #endif + ssm psr.i // enable interrupts br.call.spnt.many rp=schedule .ret9: cmp.eq p6,p0=r0,r0 // p6 <- 1 rsm psr.i // disable interrupts @@ -1234,9 +1237,12 @@ GLOBAL_ENTRY(ia64_invoke_schedule_tail) END(ia64_invoke_schedule_tail) /* - * Setup stack and call do_notify_resume_user(). Note that pSys and pNonSys need to - * be set up by the caller. We declare 8 input registers so the system call - * args get preserved, in case we need to restart a system call. + * Setup stack and call do_notify_resume_user(), keeping interrupts + * disabled. + * + * Note that pSys and pNonSys need to be set up by the caller. + * We declare 8 input registers so the system call args get preserved, + * in case we need to restart a system call. */ ENTRY(notify_resume_user) .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8) diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 58dcfac5ea8..a3a34b4eb03 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c @@ -167,11 +167,18 @@ void tsk_clear_notify_resume(struct task_struct *tsk) clear_ti_thread_flag(task_thread_info(tsk), TIF_NOTIFY_RESUME); } +/* + * do_notify_resume_user(): + * Called from notify_resume_user at entry.S, with interrupts disabled. + */ void -do_notify_resume_user (sigset_t *unused, struct sigscratch *scr, long in_syscall) +do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall) { if (fsys_mode(current, &scr->pt)) { - /* defer signal-handling etc. until we return to privilege-level 0. */ + /* + * defer signal-handling etc. until we return to + * privilege-level 0. + */ if (!ia64_psr(&scr->pt)->lp) ia64_psr(&scr->pt)->lp = 1; return; @@ -179,16 +186,26 @@ do_notify_resume_user (sigset_t *unused, struct sigscratch *scr, long in_syscall #ifdef CONFIG_PERFMON if (current->thread.pfm_needs_checking) + /* + * Note: pfm_handle_work() allow us to call it with interrupts + * disabled, and may enable interrupts within the function. + */ pfm_handle_work(); #endif /* deal with pending signal delivery */ - if (test_thread_flag(TIF_SIGPENDING)) + if (test_thread_flag(TIF_SIGPENDING)) { + local_irq_enable(); /* force interrupt enable */ ia64_do_signal(scr, in_syscall); + } /* copy user rbs to kernel rbs */ - if (unlikely(test_thread_flag(TIF_RESTORE_RSE))) + if (unlikely(test_thread_flag(TIF_RESTORE_RSE))) { + local_irq_enable(); /* force interrupt enable */ ia64_sync_krbs(); + } + + local_irq_disable(); /* force interrupt disable */ } static int pal_halt = 1; -- cgit v1.2.3 From 2e513fe4903c62450a9f8c3759f75bc4cd7e4dfd Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Fri, 9 May 2008 15:26:51 +0900 Subject: [IA64] trivial cleanup for entry.S This patch does: - make comment at next to resched check more robust - move "re-check" comments to next to where change predicate regs Signed-off-by: Hidetoshi Seto Signed-off-by: Tony Luck --- arch/ia64/kernel/entry.S | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index ef6b0313c85..ca2bb95726d 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -1167,7 +1167,7 @@ skip_rbs_switch: st8 [r2]=r8 st8 [r3]=r10 .work_pending: - tbit.z p6,p0=r31,TIF_NEED_RESCHED // current_thread_info()->need_resched==0? + tbit.z p6,p0=r31,TIF_NEED_RESCHED // is resched not needed? (p6) br.cond.sptk.few .notify #ifdef CONFIG_PREEMPT (pKStk) dep r21=-1,r0,PREEMPT_ACTIVE_BIT,1 @@ -1176,7 +1176,7 @@ skip_rbs_switch: #endif ssm psr.i // enable interrupts br.call.spnt.many rp=schedule -.ret9: cmp.eq p6,p0=r0,r0 // p6 <- 1 +.ret9: cmp.eq p6,p0=r0,r0 // p6 <- 1 (re-check) rsm psr.i // disable interrupts ;; #ifdef CONFIG_PREEMPT @@ -1185,13 +1185,13 @@ skip_rbs_switch: (pKStk) st4 [r20]=r0 // preempt_count() <- 0 #endif (pLvSys)br.cond.sptk.few .work_pending_syscall_end - br.cond.sptk.many .work_processed_kernel // re-check + br.cond.sptk.many .work_processed_kernel .notify: (pUStk) br.call.spnt.many rp=notify_resume_user -.ret10: cmp.ne p6,p0=r0,r0 // p6 <- 0 +.ret10: cmp.ne p6,p0=r0,r0 // p6 <- 0 (don't re-check) (pLvSys)br.cond.sptk.few .work_pending_syscall_end - br.cond.sptk.many .work_processed_kernel // don't re-check + br.cond.sptk.many .work_processed_kernel .work_pending_syscall_end: adds r2=PT(R8)+16,r12 @@ -1199,7 +1199,7 @@ skip_rbs_switch: ;; ld8 r8=[r2] ld8 r10=[r3] - br.cond.sptk.many .work_processed_syscall // re-check + br.cond.sptk.many .work_processed_syscall END(ia64_leave_kernel) -- cgit v1.2.3 From 0fb232fdb2a2674003ef4b874034e872b7256aa9 Mon Sep 17 00:00:00 2001 From: Hidetoshi Seto Date: Fri, 9 May 2008 15:27:09 +0900 Subject: [IA64] trivial cleanup for perfmon.c Fix a typo, and coding style cleanups for pfm_handle_work(). Signed-off-by: Hidetoshi Seto Signed-off-by: Tony Luck --- arch/ia64/kernel/perfmon.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index c1ad27de2dd..71d05133f55 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -5013,12 +5013,13 @@ pfm_context_force_terminate(pfm_context_t *ctx, struct pt_regs *regs) } static int pfm_ovfl_notify_user(pfm_context_t *ctx, unsigned long ovfl_pmds); + /* * pfm_handle_work() can be called with interrupts enabled * (TIF_NEED_RESCHED) or disabled. The down_interruptible * call may sleep, therefore we must re-enable interrupts * to avoid deadlocks. It is safe to do so because this function - * is called ONLY when returning to user level (PUStk=1), in which case + * is called ONLY when returning to user level (pUStk=1), in which case * there is no risk of kernel stack overflow due to deep * interrupt nesting. */ @@ -5034,7 +5035,8 @@ pfm_handle_work(void) ctx = PFM_GET_CTX(current); if (ctx == NULL) { - printk(KERN_ERR "perfmon: [%d] has no PFM context\n", task_pid_nr(current)); + printk(KERN_ERR "perfmon: [%d] has no PFM context\n", + task_pid_nr(current)); return; } @@ -5058,11 +5060,12 @@ pfm_handle_work(void) /* * must be done before we check for simple-reset mode */ - if (ctx->ctx_fl_going_zombie || ctx->ctx_state == PFM_CTX_ZOMBIE) goto do_zombie; - + if (ctx->ctx_fl_going_zombie || ctx->ctx_state == PFM_CTX_ZOMBIE) + goto do_zombie; //if (CTX_OVFL_NOBLOCK(ctx)) goto skip_blocking; - if (reason == PFM_TRAP_REASON_RESET) goto skip_blocking; + if (reason == PFM_TRAP_REASON_RESET) + goto skip_blocking; /* * restore interrupt mask to what it was on entry. @@ -5110,7 +5113,8 @@ do_zombie: /* * in case of interruption of down() we don't restart anything */ - if (ret < 0) goto nothing_to_do; + if (ret < 0) + goto nothing_to_do; skip_blocking: pfm_resume_after_ovfl(ctx, ovfl_regs, regs); -- cgit v1.2.3 From 7af1d7532b6cf905230c72c67ad85a480b122374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Holm=20Th=C3=B8gersen?= Date: Mon, 12 May 2008 17:40:50 +0200 Subject: [IA64] Remove NULL pointer check for argument never passed as NULL. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is only palinfo_handle_smp as (indirect) user of palinfo_smp_call (by way of smp_call_function_single) and surely palinfo_handle_smp never pass NULL as parameter for info. Signed-off-by: Simon Holm Thøgersen Signed-off-by: Tony Luck --- arch/ia64/kernel/palinfo.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index 4547a2092af..9dc00f7fe10 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c @@ -900,12 +900,6 @@ static void palinfo_smp_call(void *info) { palinfo_smp_data_t *data = (palinfo_smp_data_t *)info; - if (data == NULL) { - printk(KERN_ERR "palinfo: data pointer is NULL\n"); - data->ret = 0; /* no output */ - return; - } - /* does this actual call */ data->ret = (*data->func)(data->page); } -- cgit v1.2.3 From 3fb2c74ee20b77affd494c6b8ce7928d0ebbb62e Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Wed, 14 May 2008 12:00:24 -0400 Subject: [IA64] Properly unregister legacy interrupts acpi_unregister_gsi() should "undo" what acpi_register_gsi() does. On systems that have legacy interrupts, acpi_unregister_gsi erroneously calls iosapci_unregister_intr() which is wrong to do and causes a loud warning. acpi_unregister_gsi() should just return in these cases. Signed-off-by: Prarit Bhargava Signed-off-by: Tony Luck --- arch/ia64/kernel/acpi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 6ff6815d34e..853d1f11be0 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -627,6 +627,9 @@ void acpi_unregister_gsi(u32 gsi) if (acpi_irq_model == ACPI_IRQ_MODEL_PLATFORM) return; + if (has_8259 && gsi < 16) + return; + iosapic_unregister_intr(gsi); } -- cgit v1.2.3 From 839052d27e8db0c1545256fe5827abcd00fb51c5 Mon Sep 17 00:00:00 2001 From: "Huang, Xiaolan" Date: Thu, 15 May 2008 10:18:41 +0800 Subject: [IA64] fix personality(PER_LINUX32) performance issue The patch aims to fix a performance issue for the syscall personality(PER_LINUX32). On IA-64 box, the syscall personality (PER_LINUX32) has poor performance because it failed to find the Linux/x86 execution domain. Then it tried to load the kernel module however it failed always and it used the default execution domain PER_LINUX instead. Requesting kernel modules is very expensive. It caused the performance issue. (see the function lookup_exec_domain in kernel/exec_domain.c). To resolve the issue, execution domain Linux/x86 is always registered in initialization time for IA-64 architecture. Signed-off-by: Xiaolan Huang Signed-off-by: Tony Luck --- arch/ia64/ia32/ia32_support.c | 10 ---------- arch/ia64/mm/init.c | 25 +++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/ia64/ia32/ia32_support.c b/arch/ia64/ia32/ia32_support.c index 896b1ebbfb2..a6965ddafc4 100644 --- a/arch/ia64/ia32/ia32_support.c +++ b/arch/ia64/ia32/ia32_support.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -29,7 +28,6 @@ extern int die_if_kernel (char *str, struct pt_regs *regs, long err); -struct exec_domain ia32_exec_domain; struct page *ia32_shared_page[NR_CPUS]; unsigned long *ia32_boot_gdt; unsigned long *cpu_gdt_table[NR_CPUS]; @@ -240,14 +238,6 @@ ia32_cpu_init (void) static int __init ia32_init (void) { - ia32_exec_domain.name = "Linux/x86"; - ia32_exec_domain.handler = NULL; - ia32_exec_domain.pers_low = PER_LINUX32; - ia32_exec_domain.pers_high = PER_LINUX32; - ia32_exec_domain.signal_map = default_exec_domain.signal_map; - ia32_exec_domain.signal_invmap = default_exec_domain.signal_invmap; - register_exec_domain(&ia32_exec_domain); - #if PAGE_SHIFT > IA32_PAGE_SHIFT { extern struct kmem_cache *ia64_partial_page_cachep; diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index fc6c6636ffd..200100ea761 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -719,3 +719,28 @@ out: EXPORT_SYMBOL_GPL(remove_memory); #endif /* CONFIG_MEMORY_HOTREMOVE */ #endif + +/* + * Even when CONFIG_IA32_SUPPORT is not enabled it is + * useful to have the Linux/x86 domain registered to + * avoid an attempted module load when emulators call + * personality(PER_LINUX32). This saves several milliseconds + * on each such call. + */ +static struct exec_domain ia32_exec_domain; + +static int __init +per_linux32_init(void) +{ + ia32_exec_domain.name = "Linux/x86"; + ia32_exec_domain.handler = NULL; + ia32_exec_domain.pers_low = PER_LINUX32; + ia32_exec_domain.pers_high = PER_LINUX32; + ia32_exec_domain.signal_map = default_exec_domain.signal_map; + ia32_exec_domain.signal_invmap = default_exec_domain.signal_invmap; + register_exec_domain(&ia32_exec_domain); + + return 0; +} + +__initcall(per_linux32_init); -- cgit v1.2.3