Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp272006imu; Fri, 16 Nov 2018 02:16:13 -0800 (PST) X-Google-Smtp-Source: AJdET5fhGDDpEdcWprCB1ZBppfC8BB4DSIvYTZY02TOF29Avigl63yvE/TUlkOWbe4fMcPmgZiC5 X-Received: by 2002:a63:f34b:: with SMTP id t11mr9409079pgj.341.1542363373170; Fri, 16 Nov 2018 02:16:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1542363373; cv=none; d=google.com; s=arc-20160816; b=zLj5Hce5eRwFNTPX299EGRQqfLN8MFCneUocbOVBD6D+ZkxAAm4sRGKySDTfLB9j0y tess7Dke3Vf7jyT4t4WC7XNC35+T2vAFBMB5l7Czxv4wt/fqL060rzp8JaGsooYqip+1 Zr+irY5z0S78VZzzy0b2EK0AyCZK2K3OWTVIWc0mUaERP8tnUGhMr90HaI04f4FTlQTK WI5+yqsK6uPYcMCu6i3B6oyBVjW9OmkBc5pmTNeqFMPng0SJmZLpPcrjeViMcca/wg21 nqtnChGu/nNafUION5ReSGWOnEjKribScvt0ByBfHaXpCKHTAzYC6Ab1Urr1PUYBYNfm eyYw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=ztfFhJ4CoNc6R6R9Q/LETEEhgVHfk7yPaMYc3owaP6o=; b=DSYeW/lYxFZFEj/2Fhb/ERA+mnrE0gZEKvDsde9uyyAralCm1vMySZletDx1Gb4wxy LkeCPWGt7Ac5n8bl6/bGrPo19XZ/OVQkCnOiyEAPf0mof4LuYI3F1e9Xz8iS05PvQ9Qr xtVkB1XQ4SI2TKiyW30RWywvQTpnVVUfH+AtHRRbsph7L7fMTcR77s9YFFFr4A/wgcAE XZR1ye+Y9S5LT7HyokJs7rUcBIvkRfWFq35WsToochlYEDbcQY0dG9X9246NzpuWnVtJ cwmM6mForZulSAC1nZe+XHAnYfUjOwhmlWcXd/zk1PPwOtW3ZYAOGaY9Nu0aPO5zg7XW ZtZA== ARC-Authentication-Results: i=1; mx.google.com; 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 s9si30325247pgv.397.2018.11.16.02.15.57; Fri, 16 Nov 2018 02:16:13 -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; 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 S2389487AbeKPUYw (ORCPT + 99 others); Fri, 16 Nov 2018 15:24:52 -0500 Received: from smtp.nue.novell.com ([195.135.221.5]:53344 "EHLO smtp.nue.novell.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727490AbeKPUYv (ORCPT ); Fri, 16 Nov 2018 15:24:51 -0500 Received: from emea4-mta.ukb.novell.com ([10.120.13.87]) by smtp.nue.novell.com with ESMTP (TLS encrypted); Fri, 16 Nov 2018 11:13:09 +0100 Received: from d104.suse.de (nwb-a10-snat.microfocus.com [10.120.13.202]) by emea4-mta.ukb.novell.com with ESMTP (NOT encrypted); Fri, 16 Nov 2018 10:12:50 +0000 From: Oscar Salvador To: linux-mm@kvack.org Cc: mhocko@suse.com, david@redhat.com, rppt@linux.vnet.ibm.com, akpm@linux-foundation.org, arunks@codeaurora.org, bhe@redhat.com, dan.j.williams@intel.com, Pavel.Tatashin@microsoft.com, Jonathan.Cameron@huawei.com, jglisse@redhat.com, linux-kernel@vger.kernel.org, Oscar Salvador Subject: [RFC PATCH 1/4] mm, memory_hotplug: cleanup memory offline path Date: Fri, 16 Nov 2018 11:12:19 +0100 Message-Id: <20181116101222.16581-2-osalvador@suse.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20181116101222.16581-1-osalvador@suse.com> References: <20181116101222.16581-1-osalvador@suse.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Michal Hocko check_pages_isolated_cb currently accounts the whole pfn range as being offlined if test_pages_isolated suceeds on the range. This is based on the assumption that all pages in the range are freed which is currently the case in most cases but it won't be with later changes. I haven't double checked but if the range contains invalid pfns we could theoretically over account and underflow zone's managed pages. Move the offlined pages counting to offline_isolated_pages_cb and rely on __offline_isolated_pages to return the correct value. check_pages_isolated_cb will still do it's primary job and check the pfn range. While we are at it remove check_pages_isolated and offline_isolated_pages and use directly walk_system_ram_range as do in online_pages. Signed-off-by: Michal Hocko Signed-off-by: Oscar Salvador --- include/linux/memory_hotplug.h | 2 +- mm/memory_hotplug.c | 44 +++++++++++------------------------------- mm/page_alloc.c | 11 +++++++++-- 3 files changed, 21 insertions(+), 36 deletions(-) diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 84e9ae205930..1cb7054cdc03 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -85,7 +85,7 @@ extern int add_one_highpage(struct page *page, int pfn, int bad_ppro); extern int online_pages(unsigned long, unsigned long, int); extern int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn, unsigned long *valid_start, unsigned long *valid_end); -extern void __offline_isolated_pages(unsigned long, unsigned long); +extern unsigned long __offline_isolated_pages(unsigned long, unsigned long); typedef int (*online_page_callback_t)(struct page *page, unsigned int order); diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index dbbb94547ad0..d19e5f33e33b 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1442,17 +1442,12 @@ static int offline_isolated_pages_cb(unsigned long start, unsigned long nr_pages, void *data) { - __offline_isolated_pages(start, start + nr_pages); + unsigned long offlined_pages; + offlined_pages = __offline_isolated_pages(start, start + nr_pages); + *(unsigned long *)data += offlined_pages; return 0; } -static void -offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn) -{ - walk_system_ram_range(start_pfn, end_pfn - start_pfn, NULL, - offline_isolated_pages_cb); -} - /* * Check all pages in range, recoreded as memory resource, are isolated. */ @@ -1460,26 +1455,7 @@ static int check_pages_isolated_cb(unsigned long start_pfn, unsigned long nr_pages, void *data) { - int ret; - long offlined = *(long *)data; - ret = test_pages_isolated(start_pfn, start_pfn + nr_pages, true); - offlined = nr_pages; - if (!ret) - *(long *)data += offlined; - return ret; -} - -static long -check_pages_isolated(unsigned long start_pfn, unsigned long end_pfn) -{ - long offlined = 0; - int ret; - - ret = walk_system_ram_range(start_pfn, end_pfn - start_pfn, &offlined, - check_pages_isolated_cb); - if (ret < 0) - offlined = (long)ret; - return offlined; + return test_pages_isolated(start_pfn, start_pfn + nr_pages, true); } static int __init cmdline_parse_movable_node(char *p) @@ -1564,7 +1540,7 @@ static int __ref __offline_pages(unsigned long start_pfn, unsigned long end_pfn) { unsigned long pfn, nr_pages; - long offlined_pages; + unsigned long offlined_pages = 0; int ret, node; unsigned long flags; unsigned long valid_start, valid_end; @@ -1633,13 +1609,15 @@ static int __ref __offline_pages(unsigned long start_pfn, if (ret) goto failed_removal; /* check again */ - offlined_pages = check_pages_isolated(start_pfn, end_pfn); - if (offlined_pages < 0) + if (walk_system_ram_range(start_pfn, end_pfn - start_pfn, NULL, + check_pages_isolated_cb)) { goto repeat; - pr_info("Offlined Pages %ld\n", offlined_pages); + } /* Ok, all of our target is isolated. We cannot do rollback at this point. */ - offline_isolated_pages(start_pfn, end_pfn); + walk_system_ram_range(start_pfn, end_pfn - start_pfn, &offlined_pages, + offline_isolated_pages_cb); + pr_info("Offlined Pages %ld\n", offlined_pages); /* reset pagetype flags and makes migrate type to be MOVABLE */ undo_isolate_page_range(start_pfn, end_pfn, MIGRATE_MOVABLE); /* removal success */ diff --git a/mm/page_alloc.c b/mm/page_alloc.c index ae31839874b8..3d417c724551 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -8111,7 +8111,7 @@ void zone_pcp_reset(struct zone *zone) * All pages in the range must be in a single zone and isolated * before calling this. */ -void +unsigned long __offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn) { struct page *page; @@ -8119,12 +8119,15 @@ __offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn) unsigned int order, i; unsigned long pfn; unsigned long flags; + unsigned long offlined_pages = 0; + /* find the first valid pfn */ for (pfn = start_pfn; pfn < end_pfn; pfn++) if (pfn_valid(pfn)) break; if (pfn == end_pfn) - return; + return offlined_pages; + offline_mem_sections(pfn, end_pfn); zone = page_zone(pfn_to_page(pfn)); spin_lock_irqsave(&zone->lock, flags); @@ -8142,12 +8145,14 @@ __offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn) if (unlikely(!PageBuddy(page) && PageHWPoison(page))) { pfn++; SetPageReserved(page); + offlined_pages++; continue; } BUG_ON(page_count(page)); BUG_ON(!PageBuddy(page)); order = page_order(page); + offlined_pages += 1 << order; #ifdef CONFIG_DEBUG_VM pr_info("remove from free list %lx %d %lx\n", pfn, 1 << order, end_pfn); @@ -8160,6 +8165,8 @@ __offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn) pfn += (1 << order); } spin_unlock_irqrestore(&zone->lock, flags); + + return offlined_pages; } #endif -- 2.13.6