patch-2.4.19 linux-2.4.19/arch/ia64/kernel/process.c
Next file: linux-2.4.19/arch/ia64/kernel/ptrace.c
Previous file: linux-2.4.19/arch/ia64/kernel/perfmon.c
Back to the patch index
Back to the overall index
- Lines: 222
- Date:
Fri Aug 2 17:39:42 2002
- Orig file:
linux-2.4.18/arch/ia64/kernel/process.c
- Orig date:
Fri Nov 9 14:26:17 2001
diff -urN linux-2.4.18/arch/ia64/kernel/process.c linux-2.4.19/arch/ia64/kernel/process.c
@@ -1,8 +1,8 @@
/*
* Architecture-specific setup.
*
- * Copyright (C) 1998-2001 Hewlett-Packard Co
- * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2002 Hewlett-Packard Co
+ * David Mosberger-Tang <davidm@hpl.hp.com>
*/
#define __KERNEL_SYSCALLS__ /* see <asm/unistd.h> */
#include <linux/config.h>
@@ -12,6 +12,7 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/personality.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
@@ -28,6 +29,10 @@
#include <asm/unwind.h>
#include <asm/user.h>
+#ifdef CONFIG_IA64_SGI_SN
+#include <asm/sn/idle.h>
+#endif
+
static void
do_show_stack (struct unw_frame_info *info, void *arg)
{
@@ -46,6 +51,15 @@
}
void
+show_trace_task (struct task_struct *task)
+{
+ struct unw_frame_info info;
+
+ unw_init_from_blocked_task(&info, task);
+ do_show_stack(&info, 0);
+}
+
+void
show_stack (struct task_struct *task)
{
if (!task)
@@ -90,8 +104,8 @@
printk("r26 : %016lx r27 : %016lx r28 : %016lx\n", regs->r26, regs->r27, regs->r28);
printk("r29 : %016lx r30 : %016lx r31 : %016lx\n", regs->r29, regs->r30, regs->r31);
- /* print the stacked registers if cr.ifs is valid: */
- if (regs->cr_ifs & 0x8000000000000000) {
+ if (user_mode(regs)) {
+ /* print the stacked registers */
unsigned long val, sof, *bsp, ndirty;
int i, is_nat = 0;
@@ -122,8 +136,18 @@
if (!current->need_resched)
min_xtp();
#endif
- while (!current->need_resched)
+
+ while (!current->need_resched) {
+#ifdef CONFIG_IA64_SGI_SN
+ snidle();
+#endif
continue;
+ }
+
+#ifdef CONFIG_IA64_SGI_SN
+ snidleoff();
+#endif
+
#ifdef CONFIG_SMP
normal_xtp();
#endif
@@ -139,10 +163,17 @@
{
if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0)
ia64_save_debug_regs(&task->thread.dbr[0]);
+
#ifdef CONFIG_PERFMON
if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0)
pfm_save_regs(task);
+
+# ifdef CONFIG_SMP
+ if (local_cpu_data->pfm_syst_wide)
+ pfm_syst_wide_update_task(task, 0);
+# endif
#endif
+
if (IS_IA32_PROCESS(ia64_task_regs(task)))
ia32_save_state(task);
}
@@ -152,10 +183,17 @@
{
if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0)
ia64_load_debug_regs(&task->thread.dbr[0]);
+
#ifdef CONFIG_PERFMON
if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0)
pfm_load_regs(task);
+
+# ifdef CONFIG_SMP
+ if (local_cpu_data->pfm_syst_wide)
+ pfm_syst_wide_update_task(task, 1);
+# endif
#endif
+
if (IS_IA32_PROCESS(ia64_task_regs(task)))
ia32_load_state(task);
}
@@ -235,7 +273,7 @@
if (user_mode(child_ptregs)) {
if (user_stack_base) {
- child_ptregs->r12 = user_stack_base + user_stack_size;
+ child_ptregs->r12 = user_stack_base + user_stack_size - 16;
child_ptregs->ar_bspstore = user_stack_base;
child_ptregs->ar_rnat = 0;
child_ptregs->loadrs = 0;
@@ -288,9 +326,15 @@
if (IS_IA32_PROCESS(ia64_task_regs(current)))
ia32_save_state(p);
#endif
+
#ifdef CONFIG_PERFMON
- if (p->thread.pfm_context)
- retval = pfm_inherit(p, child_ptregs);
+ /*
+ * reset notifiers and owner check (may not have a perfmon context)
+ */
+ atomic_set(&p->thread.pfm_notifiers_check, 0);
+ atomic_set(&p->thread.pfm_owners_check, 0);
+
+ if (current->thread.pfm_context) retval = pfm_inherit(p, child_ptregs);
#endif
return retval;
}
@@ -414,6 +458,16 @@
return error;
}
+void
+ia64_set_personality (struct elf64_hdr *elf_ex, int ibcs2_interpreter)
+{
+ set_personality(PER_LINUX);
+ if (elf_ex->e_flags & EF_IA_64_LINUX_EXECUTABLE_STACK)
+ current->thread.flags |= IA64_THREAD_XSTACK;
+ else
+ current->thread.flags &= ~IA64_THREAD_XSTACK;
+}
+
pid_t
kernel_thread (int (*fn)(void *), void *arg, unsigned long flags)
{
@@ -445,15 +499,15 @@
#ifdef CONFIG_PERFMON
/*
- * By the time we get here, the task is detached from the tasklist. This is important
- * because it means that no other tasks can ever find it as a notifiied task, therfore
- * there is no race condition between this code and let's say a pfm_context_create().
- * Conversely, the pfm_cleanup_notifiers() cannot try to access a task's pfm context if
- * this other task is in the middle of its own pfm_context_exit() because it would alreayd
- * be out of the task list. Note that this case is very unlikely between a direct child
- * and its parents (if it is the notified process) because of the way the exit is notified
- * via SIGCHLD.
+ * by the time we get here, the task is detached from the tasklist. This is important
+ * because it means that no other tasks can ever find it as a notified task, therfore there
+ * is no race condition between this code and let's say a pfm_context_create().
+ * Conversely, the pfm_cleanup_notifiers() cannot try to access a task's pfm context if this
+ * other task is in the middle of its own pfm_context_exit() because it would already be out of
+ * the task list. Note that this case is very unlikely between a direct child and its parents
+ * (if it is the notified process) because of the way the exit is notified via SIGCHLD.
*/
+
void
release_thread (struct task_struct *task)
{
@@ -462,6 +516,12 @@
if (atomic_read(&task->thread.pfm_notifiers_check) > 0)
pfm_cleanup_notifiers(task);
+
+ if (atomic_read(&task->thread.pfm_owners_check) > 0)
+ pfm_cleanup_owners(task);
+
+ if (task->thread.pfm_smpl_buf_list)
+ pfm_cleanup_smpl_buf(task);
}
#endif
@@ -477,21 +537,13 @@
ia64_set_fpu_owner(0);
#endif
#ifdef CONFIG_PERFMON
- /* stop monitoring */
- if ((current->thread.flags & IA64_THREAD_PM_VALID) != 0) {
- /*
- * we cannot rely on switch_to() to save the PMU
- * context for the last time. There is a possible race
- * condition in SMP mode between the child and the
- * parent. by explicitly saving the PMU context here
- * we garantee no race. this call we also stop
- * monitoring
- */
+ /* if needed, stop monitoring and flush state to perfmon context */
+ if (current->thread.pfm_context)
pfm_flush_regs(current);
- /*
- * make sure that switch_to() will not save context again
- */
- current->thread.flags &= ~IA64_THREAD_PM_VALID;
+
+ /* free debug register resources */
+ if ((current->thread.flags & IA64_THREAD_DBG_VALID) != 0) {
+ pfm_release_debug_registers(current);
}
#endif
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)