patch-2.4.15 linux/arch/ia64/kernel/process.c
Next file: linux/arch/ia64/kernel/ptrace.c
Previous file: linux/arch/ia64/kernel/perfmon.c
Back to the patch index
Back to the overall index
- Lines: 111
- Date:
Fri Nov 9 14:26:17 2001
- Orig file:
v2.4.14/linux/arch/ia64/kernel/process.c
- Orig date:
Tue Oct 9 17:06:51 2001
diff -u --recursive --new-file v2.4.14/linux/arch/ia64/kernel/process.c linux/arch/ia64/kernel/process.c
@@ -63,7 +63,8 @@
{
unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri;
- printk("\npsr : %016lx ifs : %016lx ip : [<%016lx>] %s\n",
+ printk("\nPid: %d, comm: %20s\n", current->pid, current->comm);
+ printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s\n",
regs->cr_ipsr, regs->cr_ifs, ip, print_tainted());
printk("unat: %016lx pfs : %016lx rsc : %016lx\n",
regs->ar_unat, regs->ar_pfs, regs->ar_rsc);
@@ -201,7 +202,7 @@
{
unsigned long rbs, child_rbs, rbs_size, stack_offset, stack_top, stack_used;
struct switch_stack *child_stack, *stack;
- extern char ia64_ret_from_clone;
+ extern char ia64_ret_from_clone, ia32_ret_from_clone;
struct pt_regs *child_ptregs;
int retval = 0;
@@ -250,7 +251,10 @@
child_ptregs->r12 = (unsigned long) (child_ptregs + 1); /* kernel sp */
child_ptregs->r13 = (unsigned long) p; /* set `current' pointer */
}
- child_stack->b0 = (unsigned long) &ia64_ret_from_clone;
+ if (IS_IA32_PROCESS(regs))
+ child_stack->b0 = (unsigned long) &ia32_ret_from_clone;
+ else
+ child_stack->b0 = (unsigned long) &ia64_ret_from_clone;
child_stack->ar_bspstore = child_rbs + rbs_size;
/* copy parts of thread_struct: */
@@ -285,9 +289,8 @@
ia32_save_state(p);
#endif
#ifdef CONFIG_PERFMON
- p->thread.pfm_pend_notify = 0;
if (p->thread.pfm_context)
- retval = pfm_inherit(p);
+ retval = pfm_inherit(p, child_ptregs);
#endif
return retval;
}
@@ -441,11 +444,24 @@
}
#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.
+ */
void
release_thread (struct task_struct *task)
{
if (task->thread.pfm_context)
pfm_context_exit(task);
+
+ if (atomic_read(&task->thread.pfm_notifiers_check) > 0)
+ pfm_cleanup_notifiers(task);
}
#endif
@@ -516,6 +532,29 @@
}
void
+cpu_halt (void)
+{
+ pal_power_mgmt_info_u_t power_info[8];
+ unsigned long min_power;
+ int i, min_power_state;
+
+ if (ia64_pal_halt_info(power_info) != 0)
+ return;
+
+ min_power_state = 0;
+ min_power = power_info[0].pal_power_mgmt_info_s.power_consumption;
+ for (i = 1; i < 8; ++i)
+ if (power_info[i].pal_power_mgmt_info_s.im
+ && power_info[i].pal_power_mgmt_info_s.power_consumption < min_power) {
+ min_power = power_info[i].pal_power_mgmt_info_s.power_consumption;
+ min_power_state = i;
+ }
+
+ while (1)
+ ia64_pal_halt(min_power_state);
+}
+
+void
machine_restart (char *restart_cmd)
{
(*efi.reset_system)(EFI_RESET_WARM, 0, 0, 0);
@@ -524,6 +563,7 @@
void
machine_halt (void)
{
+ cpu_halt();
}
void
@@ -531,4 +571,5 @@
{
if (pm_power_off)
pm_power_off();
+ machine_halt();
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)