Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp6939020imu; Thu, 31 Jan 2019 02:09:34 -0800 (PST) X-Google-Smtp-Source: ALg8bN6wvj+F7tjl5bjHcTYu5UDAzOny1kIGbjkf7nN/g+5aDYSCj6CEObgVzgjuiHQWD/4aw4qk X-Received: by 2002:a17:902:3383:: with SMTP id b3mr33303807plc.170.1548929373960; Thu, 31 Jan 2019 02:09:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548929373; cv=none; d=google.com; s=arc-20160816; b=SXB0oA8fSHFpK5tGgf7l7QQoP/xzA12TaiUwOu/iS3xYBJETzlq6MdwWcs6/4X5uXP 80h66McvPKJ6AcqxdnADIf3gEJV22BFw2tbQjduN/gNVczogZuH54/JZwmhi7pvy55a8 K6fzsSNNDNJhzWIqwlBO5GpBPb8rWqI/TU8QU1WSxAFEIVki6hwKGTEvmUOz25DQHDaR RmqFYaGokuRQn6oSmm8626Mjq1hTKCP/mfhuWrCgG/+1vuO7nxj1CEM15XDqR+j86wHT qBeyImFiGT408HSkAmOdSG3xgeJVJqdLmhn4jXgfMehddsZcl5xC9cjXgbatfTO12D5k 4kaw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:date:cc:to:subject:from:references :in-reply-to:message-id:dkim-signature; bh=yMq6si7jSH6bQUbdVukf4mkG8sOf1bePhLPx15JBPBI=; b=Rh5PmOqqPPCLAEdoMJF4//vk7xdTr/IZEScNOh19Hq/ahtqpgxWW5GfrTk+VHG9NYE DQ3X/b/Ker4DNRNmhqZm1+FnvitVM869SlEcSm6+aqIUNGayNFGFccI+82Kg9z0A2Xxr OGZCpA8NOA1kovUdMyw5RR6J5IjFyTbROrNO3FnwNDZrOkYOOxmQFb4ZYybqT9x9vw/L iDCv8QoUKHH9CXSqQnuLk+7y5hkFcm0wKluV/bvJZgo3OAcd6/qNMDxJ61U6EuJYFm29 Dq8qFkmfobGE5fycrGk4Sua0FhUlGn2/hvlOYuT1v4c+Z0eItgmTBmHuLUpJ5gDdA2Kq SfBQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@c-s.fr header.s=mail header.b=SIRd5y6K; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r7si4358399ple.281.2019.01.31.02.09.18; Thu, 31 Jan 2019 02:09:33 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@c-s.fr header.s=mail header.b=SIRd5y6K; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732054AbfAaKI7 (ORCPT + 99 others); Thu, 31 Jan 2019 05:08:59 -0500 Received: from pegase1.c-s.fr ([93.17.236.30]:2739 "EHLO pegase1.c-s.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731981AbfAaKIz (ORCPT ); Thu, 31 Jan 2019 05:08:55 -0500 Received: from localhost (mailhub1-int [192.168.12.234]) by localhost (Postfix) with ESMTP id 43qwtX1y3Rz9tyxD; Thu, 31 Jan 2019 11:08:52 +0100 (CET) Authentication-Results: localhost; dkim=pass reason="1024-bit key; insecure key" header.d=c-s.fr header.i=@c-s.fr header.b=SIRd5y6K; dkim-adsp=pass; dkim-atps=neutral X-Virus-Scanned: Debian amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [192.168.12.234]) (amavisd-new, port 10024) with ESMTP id dg1E1baNvEeN; Thu, 31 Jan 2019 11:08:52 +0100 (CET) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 43qwtX0wJkz9tyxB; Thu, 31 Jan 2019 11:08:52 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=c-s.fr; s=mail; t=1548929332; bh=yMq6si7jSH6bQUbdVukf4mkG8sOf1bePhLPx15JBPBI=; h=In-Reply-To:References:From:Subject:To:Cc:Date:From; b=SIRd5y6KTz59S6MR0NxmvTvQnbh0EppDwx+cUqIvuKIgn3iwerFhyJ9ng4B1INBAj TXaVhccbqh3kuEnbcUAQ5mW+HdTJBMRlkvL+sGlYkNnOTPZwNaYlZK/1uAor3xnAKo Nq3LMd9nwv0fFdoaOzpyJVZFU1CxMX9GP1/1cpQc= Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 437C28B814; Thu, 31 Jan 2019 11:08:53 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id zql9HpmPwQCG; Thu, 31 Jan 2019 11:08:53 +0100 (CET) Received: from po16846vm.idsi0.si.c-s.fr (unknown [192.168.4.90]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 05CB58B78D; Thu, 31 Jan 2019 11:08:53 +0100 (CET) Received: by po16846vm.idsi0.si.c-s.fr (Postfix, from userid 0) id 9AFEA72E14; Thu, 31 Jan 2019 10:08:52 +0000 (UTC) Message-Id: <38755f11005b121f1483736f565f6fd24c827e14.1548852243.git.christophe.leroy@c-s.fr> In-Reply-To: References: From: Christophe Leroy Subject: [PATCH v15 05/13] powerpc: prep stack walkers for THREAD_INFO_IN_TASK To: Benjamin Herrenschmidt , Paul Mackerras , Michael Ellerman , Nicholas Piggin Cc: linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Date: Thu, 31 Jan 2019 10:08:52 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org [text copied from commit 9bbd4c56b0b6 ("arm64: prep stack walkers for THREAD_INFO_IN_TASK")] When CONFIG_THREAD_INFO_IN_TASK is selected, task stacks may be freed before a task is destroyed. To account for this, the stacks are refcounted, and when manipulating the stack of another task, it is necessary to get/put the stack to ensure it isn't freed and/or re-used while we do so. This patch reworks the powerpc stack walking code to account for this. When CONFIG_THREAD_INFO_IN_TASK is not selected these perform no refcounting, and this should only be a structural change that does not affect behaviour. Acked-by: Mark Rutland Signed-off-by: Christophe Leroy --- arch/powerpc/kernel/process.c | 23 +++++++++++++++++++++-- arch/powerpc/kernel/stacktrace.c | 29 ++++++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index ce393df243aa..4ffbb677c9f5 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -2027,7 +2027,7 @@ int validate_sp(unsigned long sp, struct task_struct *p, EXPORT_SYMBOL(validate_sp); -unsigned long get_wchan(struct task_struct *p) +static unsigned long __get_wchan(struct task_struct *p) { unsigned long ip, sp; int count = 0; @@ -2053,6 +2053,20 @@ unsigned long get_wchan(struct task_struct *p) return 0; } +unsigned long get_wchan(struct task_struct *p) +{ + unsigned long ret; + + if (!try_get_task_stack(p)) + return 0; + + ret = __get_wchan(p); + + put_task_stack(p); + + return ret; +} + static int kstack_depth_to_print = CONFIG_PRINT_STACK_DEPTH; void show_stack(struct task_struct *tsk, unsigned long *stack) @@ -2067,6 +2081,9 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) int curr_frame = 0; #endif + if (!try_get_task_stack(tsk)) + return; + sp = (unsigned long) stack; if (tsk == NULL) tsk = current; @@ -2081,7 +2098,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) printk("Call Trace:\n"); do { if (!validate_sp(sp, tsk, STACK_FRAME_OVERHEAD)) - return; + break; stack = (unsigned long *) sp; newsp = stack[0]; @@ -2121,6 +2138,8 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) sp = newsp; } while (count++ < kstack_depth_to_print); + + put_task_stack(tsk); } #ifdef CONFIG_PPC64 diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c index e2c50b55138f..f80e1129c0f2 100644 --- a/arch/powerpc/kernel/stacktrace.c +++ b/arch/powerpc/kernel/stacktrace.c @@ -67,12 +67,17 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) { unsigned long sp; + if (!try_get_task_stack(tsk)) + return; + if (tsk == current) sp = current_stack_pointer(); else sp = tsk->thread.ksp; save_context_stack(trace, sp, tsk, 0); + + put_task_stack(tsk); } EXPORT_SYMBOL_GPL(save_stack_trace_tsk); @@ -84,9 +89,8 @@ save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) EXPORT_SYMBOL_GPL(save_stack_trace_regs); #ifdef CONFIG_HAVE_RELIABLE_STACKTRACE -int -save_stack_trace_tsk_reliable(struct task_struct *tsk, - struct stack_trace *trace) +static int __save_stack_trace_tsk_reliable(struct task_struct *tsk, + struct stack_trace *trace) { unsigned long sp; unsigned long stack_page = (unsigned long)task_stack_page(tsk); @@ -193,6 +197,25 @@ save_stack_trace_tsk_reliable(struct task_struct *tsk, } return 0; } + +int save_stack_trace_tsk_reliable(struct task_struct *tsk, + struct stack_trace *trace) +{ + int ret; + + /* + * If the task doesn't have a stack (e.g., a zombie), the stack is + * "reliably" empty. + */ + if (!try_get_task_stack(tsk)) + return 0; + + ret = __save_stack_trace_tsk_reliable(tsk, trace); + + put_task_stack(tsk); + + return ret; +} EXPORT_SYMBOL_GPL(save_stack_trace_tsk_reliable); #endif /* CONFIG_HAVE_RELIABLE_STACKTRACE */ -- 2.13.3