diff options
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/asm-offsets.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/machine_kexec.c | 54 | ||||
-rw-r--r-- | arch/powerpc/kernel/process.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/time.c | 32 | ||||
-rw-r--r-- | arch/powerpc/kernel/traps.c | 4 |
5 files changed, 61 insertions, 32 deletions
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 0ae5d57..2c8e756 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -141,6 +141,7 @@ int main(void) DEFINE(PACALPPACAPTR, offsetof(struct paca_struct, lppaca_ptr)); DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr)); + DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr)); DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time)); DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); DEFINE(PACA_SLBSHADOWPTR, offsetof(struct paca_struct, slb_shadow_ptr)); diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index e60a0c5..c0c8e8c 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -61,45 +61,39 @@ NORET_TYPE void machine_kexec(struct kimage *image) for(;;); } -static int __init early_parse_crashk(char *p) -{ - unsigned long size; - - if (!p) - return 1; - - size = memparse(p, &p); - - if (*p == '@') - crashk_res.start = memparse(p + 1, &p); - else - crashk_res.start = KDUMP_KERNELBASE; - - crashk_res.end = crashk_res.start + size - 1; - - return 0; -} -early_param("crashkernel", early_parse_crashk); - void __init reserve_crashkernel(void) { - unsigned long size; + unsigned long long crash_size, crash_base; + int ret; + + /* this is necessary because of lmb_phys_mem_size() */ + lmb_analyze(); + + /* use common parsing */ + ret = parse_crashkernel(boot_command_line, lmb_phys_mem_size(), + &crash_size, &crash_base); + if (ret == 0 && crash_size > 0) { + if (crash_base == 0) + crash_base = KDUMP_KERNELBASE; + crashk_res.start = crash_base; + } else { + /* handle the device tree */ + crash_size = crashk_res.end - crashk_res.start + 1; + } - if (crashk_res.start == 0) + if (crash_size == 0) return; /* We might have got these values via the command line or the * device tree, either way sanitise them now. */ - size = crashk_res.end - crashk_res.start + 1; - if (crashk_res.start != KDUMP_KERNELBASE) printk("Crash kernel location must be 0x%x\n", KDUMP_KERNELBASE); crashk_res.start = KDUMP_KERNELBASE; - size = PAGE_ALIGN(size); - crashk_res.end = crashk_res.start + size - 1; + crash_size = PAGE_ALIGN(crash_size); + crashk_res.end = crashk_res.start + crash_size - 1; /* Crash kernel trumps memory limit */ if (memory_limit && memory_limit <= crashk_res.end) { @@ -108,7 +102,13 @@ void __init reserve_crashkernel(void) memory_limit); } - lmb_reserve(crashk_res.start, size); + printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " + "for crashkernel (System RAM: %ldMB)\n", + (unsigned long)(crash_size >> 20), + (unsigned long)(crashk_res.start >> 20), + (unsigned long)(lmb_phys_mem_size() >> 20)); + + lmb_reserve(crashk_res.start, crash_size); } int overlaps_crashkernel(unsigned long start, unsigned long size) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index ea6ad7a..b9d8837 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -459,7 +459,7 @@ void show_regs(struct pt_regs * regs) printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr); #endif printk("TASK = %p[%d] '%s' THREAD: %p", - current, current->pid, current->comm, task_thread_info(current)); + current, task_pid_nr(current), current->comm, task_thread_info(current)); #ifdef CONFIG_SMP printk(" CPU: %d", smp_processor_id()); diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 863a5d6..9eb3284 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -212,23 +212,44 @@ static u64 read_purr(void) } /* + * Read the SPURR on systems that have it, otherwise the purr + */ +static u64 read_spurr(u64 purr) +{ + if (cpu_has_feature(CPU_FTR_SPURR)) + return mfspr(SPRN_SPURR); + return purr; +} + +/* * Account time for a transition between system, hard irq * or soft irq state. */ void account_system_vtime(struct task_struct *tsk) { - u64 now, delta; + u64 now, nowscaled, delta, deltascaled; unsigned long flags; local_irq_save(flags); now = read_purr(); delta = now - get_paca()->startpurr; get_paca()->startpurr = now; + nowscaled = read_spurr(now); + deltascaled = nowscaled - get_paca()->startspurr; + get_paca()->startspurr = nowscaled; if (!in_interrupt()) { + /* deltascaled includes both user and system time. + * Hence scale it based on the purr ratio to estimate + * the system time */ + deltascaled = deltascaled * get_paca()->system_time / + (get_paca()->system_time + get_paca()->user_time); delta += get_paca()->system_time; get_paca()->system_time = 0; } account_system_time(tsk, 0, delta); + get_paca()->purrdelta = delta; + account_system_time_scaled(tsk, deltascaled); + get_paca()->spurrdelta = deltascaled; local_irq_restore(flags); } @@ -240,11 +261,17 @@ void account_system_vtime(struct task_struct *tsk) */ void account_process_vtime(struct task_struct *tsk) { - cputime_t utime; + cputime_t utime, utimescaled; utime = get_paca()->user_time; get_paca()->user_time = 0; account_user_time(tsk, utime); + + /* Estimate the scaled utime by scaling the real utime based + * on the last spurr to purr ratio */ + utimescaled = utime * get_paca()->spurrdelta / get_paca()->purrdelta; + get_paca()->spurrdelta = get_paca()->purrdelta = 0; + account_user_time_scaled(tsk, utimescaled); } static void account_process_time(struct pt_regs *regs) @@ -266,6 +293,7 @@ struct cpu_purr_data { int initialized; /* thread is running */ u64 tb; /* last TB value read */ u64 purr; /* last PURR value read */ + u64 spurr; /* last SPURR value read */ }; /* diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index bf9e39c..59c464e 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -201,7 +201,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) * generate the same exception over and over again and we get * nowhere. Better to kill it and let the kernel panic. */ - if (is_init(current)) { + if (is_global_init(current)) { __sighandler_t handler; spin_lock_irq(¤t->sighand->siglock); @@ -881,7 +881,7 @@ void nonrecoverable_exception(struct pt_regs *regs) void trace_syscall(struct pt_regs *regs) { printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n", - current, current->pid, regs->nip, regs->link, regs->gpr[0], + current, task_pid_nr(current), regs->nip, regs->link, regs->gpr[0], regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted()); } |