Received: by 2002:a5b:505:0:0:0:0:0 with SMTP id o5csp2073294ybp; Thu, 10 Oct 2019 01:42:00 -0700 (PDT) X-Google-Smtp-Source: APXvYqxGGwub+DODOhhMq8y1eOlSzmuuobJDxVucILd3IsgMewFzy/zAFR5MKnDDasRjKR8pX2hr X-Received: by 2002:a17:906:3751:: with SMTP id e17mr7151264ejc.269.1570696919910; Thu, 10 Oct 2019 01:41:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1570696919; cv=none; d=google.com; s=arc-20160816; b=ZfX90ygo73jiAiAbX3cG9GnF079rvQFBLtcCcy77MQKw6cvdelrt0+NGidvltB4nbg 1MT39/MVWbdJrDa22qtZd0luvf24fZG/paLk8HQGOP7WQ94RNDisKxlJsadpUYSbvFgO COBKrIp4mBpFkKaW95iCD8OYSuj5X93kVQ6aLfGpsd8Z0P5alMxygi8FmrLndaM+plwI MWBMqYyAS4BfZVY3U5mcnnsMDy3CU961mQLTcI+rkbYAq3urMyLzILDfANNLsb/ZRv8U TtpysS3CpqVlc3F7F0nqj+GaOJy3i+ZPxyp/zYgiA4sfU7OSLXo3V3DABhih4+UHrtjO 8+Ag== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=Zy7FVkARK6T0CfFZGrCf2gUIF7whJojmOGk80RkXkAU=; b=AT8x0C0/+0Yqr1IlJxGkALoyn47qLMJxAIMCPbOgHkbCoe/JlX3FtIbUTmb/kXLLMy 6wvQc7jQ+yNEQakfnH95xS9/k/r3/11fbTfF7LWYoWcLuZ+V23sVEIz1NSGgQD+G9SWq F9JZaxSDMRY0N1ZDMwScj/joNRKESf45RX1q78R8iffSYbNqvcNkbqd7PLQPrQ143fcI 6F1BVA0SiLKIVbWILjRbgcHrPA7/Bj/cSg8SvUXCkmerwyEN3qXTz/Ld2PI+LKL9QXOI tU1q8H2k1rEGbNz7QUmIMvwzFsq6VvpWiBVMMsHWENbbeUlzz977KGLctKBYnMEbh7pm LQOA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=poEu5m5C; 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 la20si2698741ejb.73.2019.10.10.01.41.36; Thu, 10 Oct 2019 01:41:59 -0700 (PDT) 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=@kernel.org header.s=default header.b=poEu5m5C; 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 S2387675AbfJJIin (ORCPT + 99 others); Thu, 10 Oct 2019 04:38:43 -0400 Received: from mail.kernel.org ([198.145.29.99]:41614 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387635AbfJJIim (ORCPT ); Thu, 10 Oct 2019 04:38:42 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id AD066218AC; Thu, 10 Oct 2019 08:38:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1570696721; bh=PiLVW/DsUnOL6344RwbBLLZjLvoXyDOgI5e4SR7M1FU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=poEu5m5Cb9+nbI+NercR7FrqffJqatl6gYJ3Pao4XuAmhMOMborlw++JRHJGv6W6m lDebfKcbiP2AF70IcUNZ6vCJ5cQ4EzQa1JaSMLB+Gs1a6mTnXs4KSfiye9VnPppMt/ sqv6XiKrYM/blOCS7/WFfUpI5I11z56WbptylIYc= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, "Aneesh Kumar K.V" , "Gautham R. Shenoy" , Michael Ellerman Subject: [PATCH 5.3 028/148] powerpc/pseries: Fix cpu_hotplug_lock acquisition in resize_hpt() Date: Thu, 10 Oct 2019 10:34:49 +0200 Message-Id: <20191010083612.818069391@linuxfoundation.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191010083609.660878383@linuxfoundation.org> References: <20191010083609.660878383@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Gautham R. Shenoy commit c784be435d5dae28d3b03db31753dd7a18733f0c upstream. The calls to arch_add_memory()/arch_remove_memory() are always made with the read-side cpu_hotplug_lock acquired via memory_hotplug_begin(). On pSeries, arch_add_memory()/arch_remove_memory() eventually call resize_hpt() which in turn calls stop_machine() which acquires the read-side cpu_hotplug_lock again, thereby resulting in the recursive acquisition of this lock. In the absence of CONFIG_PROVE_LOCKING, we hadn't observed a system lockup during a memory hotplug operation because cpus_read_lock() is a per-cpu rwsem read, which, in the fast-path (in the absence of the writer, which in our case is a CPU-hotplug operation) simply increments the read_count on the semaphore. Thus a recursive read in the fast-path doesn't cause any problems. However, we can hit this problem in practice if there is a concurrent CPU-Hotplug operation in progress which is waiting to acquire the write-side of the lock. This will cause the second recursive read to block until the writer finishes. While the writer is blocked since the first read holds the lock. Thus both the reader as well as the writers fail to make any progress thereby blocking both CPU-Hotplug as well as Memory Hotplug operations. Memory-Hotplug CPU-Hotplug CPU 0 CPU 1 ------ ------ 1. down_read(cpu_hotplug_lock.rw_sem) [memory_hotplug_begin] 2. down_write(cpu_hotplug_lock.rw_sem) [cpu_up/cpu_down] 3. down_read(cpu_hotplug_lock.rw_sem) [stop_machine()] Lockdep complains as follows in these code-paths. swapper/0/1 is trying to acquire lock: (____ptrval____) (cpu_hotplug_lock.rw_sem){++++}, at: stop_machine+0x2c/0x60 but task is already holding lock: (____ptrval____) (cpu_hotplug_lock.rw_sem){++++}, at: mem_hotplug_begin+0x20/0x50 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(cpu_hotplug_lock.rw_sem); lock(cpu_hotplug_lock.rw_sem); *** DEADLOCK *** May be due to missing lock nesting notation 3 locks held by swapper/0/1: #0: (____ptrval____) (&dev->mutex){....}, at: __driver_attach+0x12c/0x1b0 #1: (____ptrval____) (cpu_hotplug_lock.rw_sem){++++}, at: mem_hotplug_begin+0x20/0x50 #2: (____ptrval____) (mem_hotplug_lock.rw_sem){++++}, at: percpu_down_write+0x54/0x1a0 stack backtrace: CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.0.0-rc5-58373-gbc99402235f3-dirty #166 Call Trace: dump_stack+0xe8/0x164 (unreliable) __lock_acquire+0x1110/0x1c70 lock_acquire+0x240/0x290 cpus_read_lock+0x64/0xf0 stop_machine+0x2c/0x60 pseries_lpar_resize_hpt+0x19c/0x2c0 resize_hpt_for_hotplug+0x70/0xd0 arch_add_memory+0x58/0xfc devm_memremap_pages+0x5e8/0x8f0 pmem_attach_disk+0x764/0x830 nvdimm_bus_probe+0x118/0x240 really_probe+0x230/0x4b0 driver_probe_device+0x16c/0x1e0 __driver_attach+0x148/0x1b0 bus_for_each_dev+0x90/0x130 driver_attach+0x34/0x50 bus_add_driver+0x1a8/0x360 driver_register+0x108/0x170 __nd_driver_register+0xd0/0xf0 nd_pmem_driver_init+0x34/0x48 do_one_initcall+0x1e0/0x45c kernel_init_freeable+0x540/0x64c kernel_init+0x2c/0x160 ret_from_kernel_thread+0x5c/0x68 Fix this issue by 1) Requiring all the calls to pseries_lpar_resize_hpt() be made with cpu_hotplug_lock held. 2) In pseries_lpar_resize_hpt() invoke stop_machine_cpuslocked() as a consequence of 1) 3) To satisfy 1), in hpt_order_set(), call mmu_hash_ops.resize_hpt() with cpu_hotplug_lock held. Fixes: dbcf929c0062 ("powerpc/pseries: Add support for hash table resizing") Cc: stable@vger.kernel.org # v4.11+ Reported-by: Aneesh Kumar K.V Signed-off-by: Gautham R. Shenoy Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/1557906352-29048-1-git-send-email-ego@linux.vnet.ibm.com Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/mm/book3s64/hash_utils.c | 9 ++++++++- arch/powerpc/platforms/pseries/lpar.c | 8 ++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) --- a/arch/powerpc/mm/book3s64/hash_utils.c +++ b/arch/powerpc/mm/book3s64/hash_utils.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -1931,10 +1932,16 @@ static int hpt_order_get(void *data, u64 static int hpt_order_set(void *data, u64 val) { + int ret; + if (!mmu_hash_ops.resize_hpt) return -ENODEV; - return mmu_hash_ops.resize_hpt(val); + cpus_read_lock(); + ret = mmu_hash_ops.resize_hpt(val); + cpus_read_unlock(); + + return ret; } DEFINE_DEBUGFS_ATTRIBUTE(fops_hpt_order, hpt_order_get, hpt_order_set, "%llu\n"); --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -1413,7 +1413,10 @@ static int pseries_lpar_resize_hpt_commi return 0; } -/* Must be called in user context */ +/* + * Must be called in process context. The caller must hold the + * cpus_lock. + */ static int pseries_lpar_resize_hpt(unsigned long shift) { struct hpt_resize_state state = { @@ -1467,7 +1470,8 @@ static int pseries_lpar_resize_hpt(unsig t1 = ktime_get(); - rc = stop_machine(pseries_lpar_resize_hpt_commit, &state, NULL); + rc = stop_machine_cpuslocked(pseries_lpar_resize_hpt_commit, + &state, NULL); t2 = ktime_get();