From patchwork Fri Jul 28 02:06:14 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leo Yan X-Patchwork-Id: 108864 Delivered-To: patch@linaro.org Received: by 10.140.101.44 with SMTP id t41csp2810522qge; Thu, 27 Jul 2017 19:06:38 -0700 (PDT) X-Received: by 10.99.100.193 with SMTP id y184mr6110123pgb.364.1501207598683; Thu, 27 Jul 2017 19:06:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1501207598; cv=none; d=google.com; s=arc-20160816; b=To292uBxX93WBiCas5Bs/ZrIOT3c6AFY1yY8HdfJPICsE7LlyNJ8Wv6OBqAbifGUOP vUIqmNQ0MGQ0zF9Z6VDK7riAK9IMDrmQ2Sz+7Gb06lw3A4iYmKmbq6nW7iBn2JcfZh3O lQomMGbmVgR08AF0SIz+33uV66Q/7EJtUuM+PXqiL9kEkMllmIrU1I9Z6HPt/wSTkQVN 69FsXe6Mqt6UNFYd7VYS2xwRJeOpoo/kwQqKH0xmd9NC8nQNztHtcihOzrCkOwfHaR0S lqCwkZmtgyZqnCX+XZ7J0a3tYECeGkAS6YC8aidDgiQtwBscM47IaghLx+djChnX9CT8 gksg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=YAF/wHzA8mRfoKGixdW8u7idkGwYP0VBcQsoZ7iYypU=; b=GzkRKlfvBACzY8KmYhyvtPBpaiQAHN98FtpnbToG1Ns7qtZhjJ1BBu5ZRvpgfidaWs +O5IL/BHuEB+rcUGWaVOBeMV+2wwHmXo9P2QIhwZxAwiWS+r7yJrC4mTSMnsBS0FOewR VmGLF+HP68Q/tyT/p4fB7U+w2m4jXv3kWu0wdEN5It6a9DlnO9DrQ9bV3kv6k2VH2g1+ HqqthoColBf8LJdubQpHlKarykzhbtDT9IfPd5Tf3M8WUy70dkjbS+RvvHqdLldPhUEb g0u7juQVXZyP9B4cQldauWmVD/h1+YLpvEEvFmcpC1CWF/1vHsbenb88AUZI7mKWXjY2 sECA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.b=fspLx7hh; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c8si3398824pfj.231.2017.07.27.19.06.38; Thu, 27 Jul 2017 19:06:38 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of stable-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=@linaro.org header.b=fspLx7hh; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751738AbdG1CGh (ORCPT + 6 others); Thu, 27 Jul 2017 22:06:37 -0400 Received: from mail-pf0-f179.google.com ([209.85.192.179]:36290 "EHLO mail-pf0-f179.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751699AbdG1CGf (ORCPT ); Thu, 27 Jul 2017 22:06:35 -0400 Received: by mail-pf0-f179.google.com with SMTP id z129so50619591pfb.3 for ; Thu, 27 Jul 2017 19:06:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=YAF/wHzA8mRfoKGixdW8u7idkGwYP0VBcQsoZ7iYypU=; b=fspLx7hhCRYE28aM40M80w1PnygjHZni4VHU53E5xUFJnUkLwIX42uR8Y4DeksNs6Y lDFfr9v0b2nqrRnH+2c//waVMHThVt6V9PLyHoToeGHOTj1UbOXtVzaoRJStn4nbQyyf FVNJGi3s1m73i+h2Ac7nkib68/eHPnUc2QMa0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=YAF/wHzA8mRfoKGixdW8u7idkGwYP0VBcQsoZ7iYypU=; b=gwLhQMOH/WuiJ5AfCd5ASpfZfPPlv0y+OkDuDwNE4wTtQhF+xbib/b/O9NqbraIIm2 kcAIZqXTqhSyyTyj4A5AaZpRVSl6IwHPHKXeeAAV2EQXR4O0+p9sl4JqVb7VsmCPydlw 8wy95x1Zsaox4SCelEIm3y55xOjABwaOcMlfahToITWyRTg3UvOvNGHV64ni7Uo2V25N F7ImfWYPbhx0STVeWYmQLYxxsqYoLNac2DKYywo34ZxmfmXdOAlUEFP+ng2ZGUsPCZap EzXVQpa4ulcDze2/pc5X3wuHG4JlMgImzkTWvXD1YIQ543T1tbMWJ0NnJwEPC5cQFAll vvUQ== X-Gm-Message-State: AIVw112xHZE3MrfS2txbgs7f1TovRyfoE0V0dokP3giqp3B8DKS9QsZO LydFRE+PXknVowa/ X-Received: by 10.98.11.67 with SMTP id t64mr436407pfi.82.1501207595190; Thu, 27 Jul 2017 19:06:35 -0700 (PDT) Received: from localhost.localdomain (li1068-205.members.linode.com. [106.184.3.205]) by smtp.gmail.com with ESMTPSA id s15sm39142662pfk.42.2017.07.27.19.06.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 27 Jul 2017 19:06:33 -0700 (PDT) From: Leo Yan To: linux-kernel@vger.kernel.org, stable@vger.kernel.org, Willy Tarreau , Greg Kroah-Hartman Cc: Joel Fernandes , Kees Cook , Leo Yan Subject: [PATCH 3.10] pstore: Make spinlock per zone instead of global Date: Fri, 28 Jul 2017 10:06:14 +0800 Message-Id: <1501207574-24958-1-git-send-email-leo.yan@linaro.org> X-Mailer: git-send-email 2.7.4 Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Joel Fernandes Currently pstore has a global spinlock for all zones. Since the zones are independent and modify different areas of memory, there's no need to have a global lock, so we should use a per-zone lock as introduced here. Also, when ramoops's ftrace use-case has a FTRACE_PER_CPU flag introduced later, which splits the ftrace memory area into a single zone per CPU, it will eliminate the need for locking. In preparation for this, make the locking optional. Supply for commit log (Leo): This patch has another effect is to fix deadlock issue when enable ftrace and console log together in ramoops; in the old code ftrace buffer and console buffer in ramoops use the same raw spinlock "buffer_lock". So in below case the kernel firstly has acquired the lock for console buffer; when exit from console recording it calls function _raw_spin_unlock_irqrestore(), this function has been enabled function tracer when enter it, before release the spinlock it call function tracing and acquire the spinlock again. At the end the spinlock recursion happens and introduce the hang. This patch uses separate locks for every buffer, this let console buffer and ftrace buffer uses the dedicated locking in the same flow; this effectively fixes the lock recursion issue. [ 65.103905] hrtimer: interrupt took 2759375 ns [ 65.108721] BUG: spinlock recursion on CPU#0, kschedfreq:0/1246 [ 65.108760] lock: buffer_lock+0x0/0x38, .magic: dead4ead, .owner: kschedfreq:0/1246, .owner_cpu: 0 [ 65.108779] CPU: 0 PID: 1246 Comm: kschedfreq:0 Not tainted 4.4.74-07294-g5c996a9-dirty #130 [ 65.108786] Hardware name: HiKey960 (DT) [ 65.108794] Call trace: [ 65.108820] [] dump_backtrace+0x0/0x1e0 [ 65.108835] [] show_stack+0x20/0x28 [ 65.108857] [] dump_stack+0xa8/0xe0 [ 65.108872] [] spin_dump+0x88/0xac [ 65.108882] [] spin_bug+0x30/0x3c [ 65.108894] [] do_raw_spin_lock+0xd0/0x1b8 [ 65.108916] [] _raw_spin_lock_irqsave+0x58/0x68 [ 65.108935] [] buffer_size_add.isra.4+0x30/0x78 [ 65.108948] [] persistent_ram_write+0x58/0x150 [ 65.108961] [] ramoops_pstore_write_buf+0x14c/0x1d8 [ 65.108974] [] pstore_ftrace_call+0x80/0xb4 [ 65.108991] [] ftrace_ops_no_ops+0xb8/0x154 [ 65.109008] [] ftrace_graph_call+0x0/0x14 [ 65.109023] [] _raw_spin_unlock_irqrestore+0x20/0x90 [ 65.109036] [] buffer_size_add.isra.4+0x68/0x78 [ 65.109048] [] persistent_ram_write+0x58/0x150 [ 65.109061] [] ramoops_pstore_write_buf+0x14c/0x1d8 [ 65.109073] [] pstore_write_compat+0x60/0x6c [ 65.109086] [] pstore_console_write+0xa8/0xf4 [ 65.109104] [] call_console_drivers.constprop.21+0x1bc/0x1ec [ 65.109117] [] console_unlock+0x3a8/0x500 [ 65.109129] [] vprintk_emit+0x320/0x62c [ 65.109142] [] vprintk_default+0x48/0x54 [ 65.109161] [] printk+0xa8/0xb4 [ 65.109178] [] hrtimer_interrupt+0x1f0/0x1f4 [ 65.109197] [] arch_timer_handler_phys+0x3c/0x48 [ 65.109211] [] handle_percpu_devid_irq+0xd0/0x3c0 [ 65.109225] [] generic_handle_irq+0x34/0x4c [ 65.109237] [] __handle_domain_irq+0x90/0xf8 [ 65.109250] [] gic_handle_irq+0x5c/0xa8 Fixes: 0405a5cec340 ("pstore/ram: avoid atomic accesses for ioremapped regions") Signed-off-by: Joel Fernandes [kees: updated commit message] Signed-off-by: Kees Cook Signed-off-by: Leo Yan --- fs/pstore/ram_core.c | 11 +++++------ include/linux/pstore_ram.h | 1 + 2 files changed, 6 insertions(+), 6 deletions(-) -- 2.7.4 diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index 7df456d..ac55707 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -45,8 +45,6 @@ static inline size_t buffer_start(struct persistent_ram_zone *prz) return atomic_read(&prz->buffer->start); } -static DEFINE_RAW_SPINLOCK(buffer_lock); - /* increase and wrap the start pointer, returning the old value */ static size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a) { @@ -54,7 +52,7 @@ static size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a) int new; unsigned long flags; - raw_spin_lock_irqsave(&buffer_lock, flags); + raw_spin_lock_irqsave(&prz->buffer_lock, flags); old = atomic_read(&prz->buffer->start); new = old + a; @@ -62,7 +60,7 @@ static size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a) new -= prz->buffer_size; atomic_set(&prz->buffer->start, new); - raw_spin_unlock_irqrestore(&buffer_lock, flags); + raw_spin_unlock_irqrestore(&prz->buffer_lock, flags); return old; } @@ -74,7 +72,7 @@ static void buffer_size_add(struct persistent_ram_zone *prz, size_t a) size_t new; unsigned long flags; - raw_spin_lock_irqsave(&buffer_lock, flags); + raw_spin_lock_irqsave(&prz->buffer_lock, flags); old = atomic_read(&prz->buffer->size); if (old == prz->buffer_size) @@ -86,7 +84,7 @@ static void buffer_size_add(struct persistent_ram_zone *prz, size_t a) atomic_set(&prz->buffer->size, new); exit: - raw_spin_unlock_irqrestore(&buffer_lock, flags); + raw_spin_unlock_irqrestore(&prz->buffer_lock, flags); } static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz, @@ -452,6 +450,7 @@ static int persistent_ram_post_init(struct persistent_ram_zone *prz, u32 sig, prz->buffer->sig = sig; persistent_ram_zap(prz); + prz->buffer_lock = __RAW_SPIN_LOCK_UNLOCKED(buffer_lock); return 0; } diff --git a/include/linux/pstore_ram.h b/include/linux/pstore_ram.h index 4af3fdc..4bfcd43 100644 --- a/include/linux/pstore_ram.h +++ b/include/linux/pstore_ram.h @@ -39,6 +39,7 @@ struct persistent_ram_zone { void *vaddr; struct persistent_ram_buffer *buffer; size_t buffer_size; + raw_spinlock_t buffer_lock; /* ECC correction */ char *par_buffer;