From patchwork Thu Dec 8 05:13:21 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 9465843 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 7CC9A60459 for ; Thu, 8 Dec 2016 05:13:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 77E7B2851F for ; Thu, 8 Dec 2016 05:13:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6CDF528538; Thu, 8 Dec 2016 05:13:36 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CE2CC28532 for ; Thu, 8 Dec 2016 05:13:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753118AbcLHFNb (ORCPT ); Thu, 8 Dec 2016 00:13:31 -0500 Received: from ozlabs.org ([103.22.144.67]:58673 "EHLO ozlabs.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752956AbcLHFN3 (ORCPT ); Thu, 8 Dec 2016 00:13:29 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 3tZ3RX0J6Vz9t87; Thu, 8 Dec 2016 16:13:27 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1481174008; bh=pKscE/BeiViRi0nJQaweYbRQGjJcIqFC92UJALk49Lo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pYJyDzA51D8g1BSjVoP3783lBSXutkTfZbSebmro4xQE75mGwFahJSdDefEyPzlFK T006g5MsDwk/eEpuk8lBpdWqN8qzFyAEiId5KXm/AINBsqWrIw/wfmwlwmBHxRcmte ukfje6qRxer4xvgHxXRWmycKwZSnneNeeNLzfvt4= From: David Gibson To: michael@ellerman.id.au, paulus@samba.org Cc: linuxppc-dev@ozlabs.org, kvm@vger.kernel.org, David Gibson Subject: [PATCH 6/6] pseries: Automatically resize HPT for memory hot add/remove Date: Thu, 8 Dec 2016 16:13:21 +1100 Message-Id: <20161208051321.31446-7-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20161208051321.31446-1-david@gibson.dropbear.id.au> References: <20161208051321.31446-1-david@gibson.dropbear.id.au> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP We've now implemented code in the pseries platform to use the new PAPR interface to allow resizing the hash page table (HPT) at runtime. This patch uses that interface to automatically attempt to resize the HPT when memory is hot added or removed. This tries to always keep the HPT at a reasonable size for our current memory size. Signed-off-by: David Gibson Reviewed-by: Paul Mackerras --- arch/powerpc/include/asm/sparsemem.h | 1 + arch/powerpc/mm/hash_utils_64.c | 29 +++++++++++++++++++++++++++++ arch/powerpc/mm/mem.c | 4 ++++ 3 files changed, 34 insertions(+) diff --git a/arch/powerpc/include/asm/sparsemem.h b/arch/powerpc/include/asm/sparsemem.h index f6fc0ee..737335c 100644 --- a/arch/powerpc/include/asm/sparsemem.h +++ b/arch/powerpc/include/asm/sparsemem.h @@ -16,6 +16,7 @@ #endif /* CONFIG_SPARSEMEM */ #ifdef CONFIG_MEMORY_HOTPLUG +extern void resize_hpt_for_hotplug(unsigned long new_mem_size); extern int create_section_mapping(unsigned long start, unsigned long end); extern int remove_section_mapping(unsigned long start, unsigned long end); #ifdef CONFIG_NUMA diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 474da2e..e2eb461 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -748,6 +748,35 @@ static unsigned long __init htab_get_table_size(void) } #ifdef CONFIG_MEMORY_HOTPLUG +void resize_hpt_for_hotplug(unsigned long new_mem_size) +{ + unsigned target_hpt_shift; + + if (!mmu_hash_ops.resize_hpt) + return; + + target_hpt_shift = htab_shift_for_mem_size(new_mem_size); + + /* + * To avoid lots of HPT resizes if memory size is fluctuating + * across a boundary, we deliberately have some hysterisis + * here: we immediately increase the HPT size if the target + * shift exceeds the current shift, but we won't attempt to + * reduce unless the target shift is at least 2 below the + * current shift + */ + if ((target_hpt_shift > ppc64_pft_size) + || (target_hpt_shift < (ppc64_pft_size - 1))) { + int rc; + + rc = mmu_hash_ops.resize_hpt(target_hpt_shift); + if (rc) + printk(KERN_WARNING + "Unable to resize hash page table to target order %d: %d\n", + target_hpt_shift, rc); + } +} + int create_section_mapping(unsigned long start, unsigned long end) { int rc = htab_bolt_mapping(start, end, __pa(start), diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 5f84433..9ee536e 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -134,6 +134,8 @@ int arch_add_memory(int nid, u64 start, u64 size, bool for_device) unsigned long nr_pages = size >> PAGE_SHIFT; int rc; + resize_hpt_for_hotplug(memblock_phys_mem_size()); + pgdata = NODE_DATA(nid); start = (unsigned long)__va(start); @@ -174,6 +176,8 @@ int arch_remove_memory(u64 start, u64 size) */ vm_unmap_aliases(); + resize_hpt_for_hotplug(memblock_phys_mem_size()); + return ret; } #endif