Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp2173906imu; Thu, 24 Jan 2019 08:21:21 -0800 (PST) X-Google-Smtp-Source: ALg8bN6f7k8XkUfl7G0oXCnW2nHK4J3m/ppxMFPyfaS1GRwECG0+LbxLummTG3X87G/osbkvpOiI X-Received: by 2002:a63:ce08:: with SMTP id y8mr6443959pgf.388.1548346881046; Thu, 24 Jan 2019 08:21:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548346881; cv=none; d=google.com; s=arc-20160816; b=gRG+PJZraKZXGiHjdu2jZyvZLrRZq5k0/FqokTI5Q6yWrtjiZRy+UGaz2Q0w4TV7Ww dUOisoOR71NTVkS6+Ekgf1yxW4wyAZo1GLVZyASwvbFZcd/znQ5O90Y6rUNuvqs65IGS zCjFFo5zdfGVb7G6KXLk86QRIibYZJRAxHpZadvK49ONBZviTDa82j9/aZH0piwHz6tP uIfR45u29zphe+7OlMx1DaYLeo5jQeW9pptycjd+2zPdPebDKWYOxssZ+8botsAgU8XD 8rOGAMTuSMzzdtTsdC0EBH8uOvMXREsfLNvT0NXz+XEJqs/k2ePpnzaLUcBj1Vuyt36h BTBg== 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=OJ5h6Vnl8SC0pBTakE1vl4wqfvX1VVC/D+o9hFpCrdg=; b=GnDL1hEiaVK0m0KL9J9bMzgp0utH7RuJr4HC/UjMbT6p2XdE3sAxebXgdiY2kT12Lj 9Wm+eoX502UbNIA08hBbRNuBAzh6eYgjytSQz9sI6nqX2vzVIKf8JMvqG3ZYMJd0yX5M T9ALgG9OzgZf0G3DnJ4Fdn0J8jACl8na85T08iwH0SagnSB23di8MzcD+zoe7SNHeZlg Jeuwl9HcNd3Xom0lDF4dJEuTEx6OrfsvWiXIgO3o29w8sH8E7p7RIevqhDyVLJHjVZlX eq2ZloyiRwTCeihp5SQ74cAEHitemVrRhpsKu8qg3ZzF4ZE1Q/Eci3XOMmUvRl0WmpJ8 G9Xg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@c-s.fr header.s=mail header.b="LoPiIa/o"; 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 p14si21137010pfi.12.2019.01.24.08.21.05; Thu, 24 Jan 2019 08:21:20 -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="LoPiIa/o"; 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 S1728668AbfAXQTo (ORCPT + 99 others); Thu, 24 Jan 2019 11:19:44 -0500 Received: from pegase1.c-s.fr ([93.17.236.30]:51286 "EHLO pegase1.c-s.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727943AbfAXQTl (ORCPT ); Thu, 24 Jan 2019 11:19:41 -0500 Received: from localhost (mailhub1-int [192.168.12.234]) by localhost (Postfix) with ESMTP id 43lnRZ1PqSz9v01d; Thu, 24 Jan 2019 17:19:38 +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=LoPiIa/o; 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 Rzg9PkkWlqYZ; Thu, 24 Jan 2019 17:19:38 +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 43lnRZ0Myhz9v01Z; Thu, 24 Jan 2019 17:19:38 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=c-s.fr; s=mail; t=1548346778; bh=OJ5h6Vnl8SC0pBTakE1vl4wqfvX1VVC/D+o9hFpCrdg=; h=In-Reply-To:References:From:Subject:To:Cc:Date:From; b=LoPiIa/oxXAnbhnjLAo8Jah/uOdxVxNXn8RPj9yypcHFgtMX9tNqVMmWQeAmNMeTK 2IUb/dcMTbeo0u8g5elWnOItnso1tA0sHYeQ7OxFGLmEBQp4a4qvYbtLJd2xbXyhdp lTFFHnBLUKxpODl1ds7udSDjTRn51mkB5AFH/C4g= Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 998AE8B863; Thu, 24 Jan 2019 17:19:39 +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 QVxCKTMqU75V; Thu, 24 Jan 2019 17:19:39 +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 4FE6C8B850; Thu, 24 Jan 2019 17:19:39 +0100 (CET) Received: by po16846vm.idsi0.si.c-s.fr (Postfix, from userid 0) id 215BF72D88; Thu, 24 Jan 2019 16:19:39 +0000 (UTC) Message-Id: <685ac94ceb1dfac43fbd2ee11a987cbaca63ab0b.1548346225.git.christophe.leroy@c-s.fr> In-Reply-To: References: From: Christophe Leroy Subject: [PATCH v14 05/12] powerpc: prep stack walkers for THREAD_INFO_IN_TASK To: Benjamin Herrenschmidt , Paul Mackerras , Michael Ellerman , Nicholas Piggin , Mike Rapoport Cc: linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, Mark Rutland Date: Thu, 24 Jan 2019 16:19:39 +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. 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..a5745571e06e 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(trace, tsk); + + put_task_stack(tsk); + + return ret; +} EXPORT_SYMBOL_GPL(save_stack_trace_tsk_reliable); #endif /* CONFIG_HAVE_RELIABLE_STACKTRACE */ -- 2.13.3