Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755928AbbBPSxa (ORCPT ); Mon, 16 Feb 2015 13:53:30 -0500 Received: from mx1.redhat.com ([209.132.183.28]:51026 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755471AbbBPSxZ (ORCPT ); Mon, 16 Feb 2015 13:53:25 -0500 From: Josh Poimboeuf To: Andrew Morton , Ingo Molnar , Peter Zijlstra Cc: Jiri Kosina , Seth Jennings , linux-kernel@vger.kernel.org Subject: [PATCH 2/3] stacktrace: add save_stack_trace_tsk_safe() Date: Mon, 16 Feb 2015 12:52:35 -0600 Message-Id: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2314 Lines: 66 It isn't possible to get the stack of a running task (other than current) because we don't have the stack pointer and the stack can be inconsistent anyway. Add a safe stack saving facility which only saves the stack of the task if it's sleeping or if it's the current task. Suggested-by: Jiri Kosina Signed-off-by: Josh Poimboeuf --- include/linux/stacktrace.h | 2 ++ kernel/stacktrace.c | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/include/linux/stacktrace.h b/include/linux/stacktrace.h index 669045a..898f0fc 100644 --- a/include/linux/stacktrace.h +++ b/include/linux/stacktrace.h @@ -20,6 +20,8 @@ extern void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace); extern void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace); +extern void save_stack_trace_tsk_safe(struct task_struct *tsk, + struct stack_trace *trace); extern void print_stack_trace(struct stack_trace *trace, int spaces); extern int snprint_stack_trace(char *buf, size_t size, diff --git a/kernel/stacktrace.c b/kernel/stacktrace.c index b6e4c16..49cdd7f 100644 --- a/kernel/stacktrace.c +++ b/kernel/stacktrace.c @@ -57,6 +57,28 @@ int snprint_stack_trace(char *buf, size_t size, } EXPORT_SYMBOL_GPL(snprint_stack_trace); +static void __save_stack_trace_tsk_safe(struct task_struct *tsk, + void *data) +{ + struct stack_trace *trace = data; + + if (tsk != current && tsk->on_cpu) + return; + + save_stack_trace_tsk(tsk, trace); +} + +/* + * If the task is sleeping, safely get its stack. Otherwise, do nothing, since + * the stack of a running task is undefined. + */ +void save_stack_trace_tsk_safe(struct task_struct *tsk, + struct stack_trace *trace) +{ + sched_task_call(__save_stack_trace_tsk_safe, tsk, trace); +} +EXPORT_SYMBOL_GPL(save_stack_trace_tsk_safe); + /* * Architectures that do not implement save_stack_trace_tsk or * save_stack_trace_regs get this weak alias and a once-per-bootup warning -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/