From 87e8f0e3e6d0b720a2462ebc5667eaa462752f74 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 21 Apr 2010 02:31:50 -0700 Subject: sparc64: Show stack backtrace from show_regs() just like other platforms. Signed-off-by: David S. Miller diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index a5cf386..dbe81a3 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c @@ -202,6 +202,7 @@ void show_regs(struct pt_regs *regs) regs->u_regs[15]); printk("RPC: <%pS>\n", (void *) regs->u_regs[15]); show_regwindow(regs); + show_stack(current, (unsigned long *) regs->u_regs[UREG_FP]); } struct global_reg_snapshot global_reg_snapshot[NR_CPUS]; -- cgit v0.10.2 From 667f0cee3e0321151aa7a1a5222afe67ca4be0ea Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 21 Apr 2010 03:08:11 -0700 Subject: sparc64: Fix stack dumping and tracing when function graph is enabled. Like x86, when the function graph tracer is enabled, emit the ftrace stub as well as the program counter it will be transformed back into. We duplicate a lot of similar stack walking logic in 3 or 4 spots, so eventually we should consolidate things like x86 does. Thanks to Frederic Weisbecker for pointing this out. Signed-off-by: David S. Miller diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index e277193..34ce49f 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -1276,6 +1277,9 @@ static void perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry) { unsigned long ksp, fp; +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + int graph = 0; +#endif callchain_store(entry, PERF_CONTEXT_KERNEL); callchain_store(entry, regs->tpc); @@ -1303,6 +1307,16 @@ static void perf_callchain_kernel(struct pt_regs *regs, fp = (unsigned long)sf->fp + STACK_BIAS; } callchain_store(entry, pc); +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + if ((pc + 8UL) == (unsigned long) &return_to_handler) { + int index = current->curr_ret_stack; + if (current->ret_stack && index >= graph) { + pc = current->ret_stack[index - graph].ret; + callchain_store(entry, pc); + graph++; + } + } +#endif } while (entry->nr < PERF_MAX_STACK_DEPTH); } diff --git a/arch/sparc/kernel/stacktrace.c b/arch/sparc/kernel/stacktrace.c index acb12f6..3e08153 100644 --- a/arch/sparc/kernel/stacktrace.c +++ b/arch/sparc/kernel/stacktrace.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -12,6 +13,10 @@ static void __save_stack_trace(struct thread_info *tp, bool skip_sched) { unsigned long ksp, fp; +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + struct task_struct *t; + int graph = 0; +#endif if (tp == current_thread_info()) { stack_trace_flush(); @@ -21,6 +26,9 @@ static void __save_stack_trace(struct thread_info *tp, } fp = ksp + STACK_BIAS; +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + t = tp->task; +#endif do { struct sparc_stackf *sf; struct pt_regs *regs; @@ -44,8 +52,21 @@ static void __save_stack_trace(struct thread_info *tp, if (trace->skip > 0) trace->skip--; - else if (!skip_sched || !in_sched_functions(pc)) + else if (!skip_sched || !in_sched_functions(pc)) { trace->entries[trace->nr_entries++] = pc; +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + if ((pc + 8UL) == (unsigned long) &return_to_handler) { + int index = t->curr_ret_stack; + if (t->ret_stack && index >= graph) { + pc = t->ret_stack[index - graph].ret; + if (trace->nr_entries < + trace->max_entries) + trace->entries[trace->nr_entries++] = pc; + graph++; + } + } +#endif + } } while (trace->nr_entries < trace->max_entries); } diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index 9da57f0..42ad2ba 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -2154,6 +2155,9 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp) unsigned long fp, thread_base, ksp; struct thread_info *tp; int count = 0; +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + int graph = 0; +#endif ksp = (unsigned long) _ksp; if (!tsk) @@ -2193,6 +2197,16 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp) } printk(" [%016lx] %pS\n", pc, (void *) pc); +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + if ((pc + 8UL) == (unsigned long) &return_to_handler) { + int index = tsk->curr_ret_stack; + if (tsk->ret_stack && index >= graph) { + pc = tsk->ret_stack[index - graph].ret; + printk(" [%016lx] %pS\n", pc, (void *) pc); + graph++; + } + } +#endif } while (++count < 16); } -- cgit v0.10.2 From be94bbb5db4de0f3a2a5405511ea3ebea261f2c8 Mon Sep 17 00:00:00 2001 From: Jan Blunck Date: Tue, 27 Apr 2010 18:48:52 -0700 Subject: drivers/sbus/char/flash.c: flash_read should update ppos instead of file->f_pos flash_read() updates file->f_pos directly instead of the ppos given. The VFS later updates the file->f_pos and overwrites it with the unchanged value of ppos. Signed-off-by: Jan Blunck Signed-off-by: Andrew Morton Signed-off-by: David S. Miller diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index 19f255b..d3b62eb 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c @@ -105,9 +105,9 @@ static ssize_t flash_read(struct file * file, char __user * buf, size_t count, loff_t *ppos) { - unsigned long p = file->f_pos; + loff_t p = *ppos; int i; - + if (count > flash.read_size - p) count = flash.read_size - p; @@ -118,7 +118,7 @@ flash_read(struct file * file, char __user * buf, buf++; } - file->f_pos += count; + *ppos += count; return count; } -- cgit v0.10.2 From 273fca0ecad9305247043815e185d1bfd04047d4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 18 May 2010 15:23:58 -0700 Subject: sparc: Define ARCH_SLAB_MINALIGN Because SLOB fancies being different, the default minimum alignment is only "unsigned long" instead of SLAB/SLUB where the default is "unsigned long long" The inconsistency makes no sense and is asking for trouble, but define ARCH_SLAB_MINALIGN to get it right in all cases even after they fix the inconsistency. Signed-off-by: David S. Miller diff --git a/arch/sparc/include/asm/cache.h b/arch/sparc/include/asm/cache.h index 41f85ae..78b0700 100644 --- a/arch/sparc/include/asm/cache.h +++ b/arch/sparc/include/asm/cache.h @@ -7,6 +7,8 @@ #ifndef _SPARC_CACHE_H #define _SPARC_CACHE_H +#define ARCH_SLAB_MINALIGN __alignof__(unsigned long long) + #define L1_CACHE_SHIFT 5 #define L1_CACHE_BYTES 32 #define L1_CACHE_ALIGN(x) ((((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))) -- cgit v0.10.2