All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Hildenbrand <david@redhat.com>
To: linux-kernel@vger.kernel.org
Cc: linux-mm@kvack.org, David Hildenbrand <david@redhat.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Oscar Salvador <osalvador@suse.de>,
	Michal Hocko <mhocko@suse.com>,
	Pavel Tatashin <pasha.tatashin@soleen.com>,
	Dan Williams <dan.j.williams@intel.com>,
	Wei Yang <richardw.yang@linux.intel.com>,
	"Aneesh Kumar K . V" <aneesh.kumar@linux.ibm.com>
Subject: [PATCH v4 1/8] mm/memory_hotplug: Don't access uninitialized memmaps in shrink_pgdat_span()
Date: Fri, 30 Aug 2019 11:14:21 +0200	[thread overview]
Message-ID: <20190830091428.18399-2-david@redhat.com> (raw)
In-Reply-To: <20190830091428.18399-1-david@redhat.com>

We might use the nid of memmaps that were never initialized. For
example, if the memmap was poisoned, we will crash the kernel in
pfn_to_nid() right now. Let's use the calculated boundaries of the separate
zones instead. This now also avoids having to iterate over a whole bunch of
subsections again, after shrinking one zone.

Before commit d0dc12e86b31 ("mm/memory_hotplug: optimize memory
hotplug"), the memmap was initialized to 0 and the node was set to the
right value. After that commit, the node might be garbage.

We'll have to fix shrink_zone_span() next.

Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: David Hildenbrand <david@redhat.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Pavel Tatashin <pasha.tatashin@soleen.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Wei Yang <richardw.yang@linux.intel.com>
Fixes: d0dc12e86b31 ("mm/memory_hotplug: optimize memory hotplug")
Reported-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
 mm/memory_hotplug.c | 72 ++++++++++-----------------------------------
 1 file changed, 15 insertions(+), 57 deletions(-)

diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 49f7bf91c25a..ddba8d786e4a 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -436,67 +436,25 @@ static void shrink_zone_span(struct zone *zone, unsigned long start_pfn,
 	zone_span_writeunlock(zone);
 }
 
-static void shrink_pgdat_span(struct pglist_data *pgdat,
-			      unsigned long start_pfn, unsigned long end_pfn)
+static void update_pgdat_span(struct pglist_data *pgdat)
 {
-	unsigned long pgdat_start_pfn = pgdat->node_start_pfn;
-	unsigned long p = pgdat_end_pfn(pgdat); /* pgdat_end_pfn namespace clash */
-	unsigned long pgdat_end_pfn = p;
-	unsigned long pfn;
-	int nid = pgdat->node_id;
-
-	if (pgdat_start_pfn == start_pfn) {
-		/*
-		 * If the section is smallest section in the pgdat, it need
-		 * shrink pgdat->node_start_pfn and pgdat->node_spanned_pages.
-		 * In this case, we find second smallest valid mem_section
-		 * for shrinking zone.
-		 */
-		pfn = find_smallest_section_pfn(nid, NULL, end_pfn,
-						pgdat_end_pfn);
-		if (pfn) {
-			pgdat->node_start_pfn = pfn;
-			pgdat->node_spanned_pages = pgdat_end_pfn - pfn;
-		}
-	} else if (pgdat_end_pfn == end_pfn) {
-		/*
-		 * If the section is biggest section in the pgdat, it need
-		 * shrink pgdat->node_spanned_pages.
-		 * In this case, we find second biggest valid mem_section for
-		 * shrinking zone.
-		 */
-		pfn = find_biggest_section_pfn(nid, NULL, pgdat_start_pfn,
-					       start_pfn);
-		if (pfn)
-			pgdat->node_spanned_pages = pfn - pgdat_start_pfn + 1;
-	}
-
-	/*
-	 * If the section is not biggest or smallest mem_section in the pgdat,
-	 * it only creates a hole in the pgdat. So in this case, we need not
-	 * change the pgdat.
-	 * But perhaps, the pgdat has only hole data. Thus it check the pgdat
-	 * has only hole or not.
-	 */
-	pfn = pgdat_start_pfn;
-	for (; pfn < pgdat_end_pfn; pfn += PAGES_PER_SUBSECTION) {
-		if (unlikely(!pfn_valid(pfn)))
-			continue;
-
-		if (pfn_to_nid(pfn) != nid)
-			continue;
+	unsigned long node_start_pfn = 0, node_end_pfn = 0;
+	struct zone *zone;
 
-		/* Skip range to be removed */
-		if (pfn >= start_pfn && pfn < end_pfn)
-			continue;
+	for (zone = pgdat->node_zones;
+	     zone < pgdat->node_zones + MAX_NR_ZONES; zone++) {
+		unsigned long zone_end_pfn = zone->zone_start_pfn +
+					     zone->spanned_pages;
 
-		/* If we find valid section, we have nothing to do */
-		return;
+		/* No need to lock the zones, they can't change. */
+		if (zone_end_pfn > node_end_pfn)
+			node_end_pfn = zone_end_pfn;
+		if (zone->zone_start_pfn < node_start_pfn)
+			node_start_pfn = zone->zone_start_pfn;
 	}
 
-	/* The pgdat has no valid section */
-	pgdat->node_start_pfn = 0;
-	pgdat->node_spanned_pages = 0;
+	pgdat->node_start_pfn = node_start_pfn;
+	pgdat->node_spanned_pages = node_end_pfn - node_start_pfn;
 }
 
 static void __remove_zone(struct zone *zone, unsigned long start_pfn,
@@ -507,7 +465,7 @@ static void __remove_zone(struct zone *zone, unsigned long start_pfn,
 
 	pgdat_resize_lock(zone->zone_pgdat, &flags);
 	shrink_zone_span(zone, start_pfn, start_pfn + nr_pages);
-	shrink_pgdat_span(pgdat, start_pfn, start_pfn + nr_pages);
+	update_pgdat_span(pgdat);
 	pgdat_resize_unlock(zone->zone_pgdat, &flags);
 }
 
-- 
2.21.0


  reply	other threads:[~2019-08-30  9:14 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-30  9:14 [PATCH v4 0/8] mm/memory_hotplug: Shrink zones before removing memory David Hildenbrand
2019-08-30  9:14 ` David Hildenbrand [this message]
2019-08-30  9:14 ` [PATCH v4 2/8] mm/memory_hotplug: Don't access uninitialized memmaps in shrink_zone_span() David Hildenbrand
2019-09-26  9:12   ` Aneesh Kumar K.V
2019-09-26  9:22     ` David Hildenbrand
2019-08-30  9:14 ` [PATCH v4 3/8] mm/memory_hotplug: Shrink zones when offlining memory David Hildenbrand
2019-08-30  9:14   ` David Hildenbrand
2019-08-30  9:14 ` [PATCH v4 4/8] mm/memory_hotplug: Poison memmap in remove_pfn_range_from_zone() David Hildenbrand
2019-09-26  9:10   ` Aneesh Kumar K.V
2019-09-26  9:14     ` David Hildenbrand
2019-08-30  9:14 ` [PATCH v4 5/8] mm/memory_hotplug: We always have a zone in find_(smallest|biggest)_section_pfn David Hildenbrand
2019-08-30  9:14 ` [PATCH v4 6/8] mm/memory_hotplug: Don't check for "all holes" in shrink_zone_span() David Hildenbrand
2019-08-30  9:14 ` [PATCH v4 7/8] mm/memory_hotplug: Drop local variables " David Hildenbrand
2019-08-30  9:14 ` [PATCH v4 8/8] mm/memory_hotplug: Cleanup __remove_pages() David Hildenbrand
2019-09-06  9:21 ` [PATCH v4 0/8] mm/memory_hotplug: Shrink zones before removing memory David Hildenbrand
2019-09-19 13:58 ` David Hildenbrand
2019-09-19 19:16   ` Andrew Morton
2019-09-20  8:16     ` David Hildenbrand
2019-09-26 12:25 ` [PATCH 1/2] mm/memunmap: Use the correct start and end pfn when removing pages from zone Aneesh Kumar K.V
2019-09-26 12:25   ` Aneesh Kumar K.V
2019-09-26 12:25   ` [PATCH 2/2] mm/memmap_init: Update variable name in memmap_init_zone Aneesh Kumar K.V
2019-09-26 12:25     ` Aneesh Kumar K.V
2019-09-26 12:56     ` David Hildenbrand
2019-09-26 12:56       ` David Hildenbrand
2019-09-26 13:38     ` Pankaj Gupta
2019-09-26 13:38       ` Pankaj Gupta
2019-09-26 12:43   ` [PATCH 1/2] mm/memunmap: Use the correct start and end pfn when removing pages from zone David Hildenbrand
2019-09-26 12:43     ` David Hildenbrand
2019-09-26 13:15     ` Aneesh Kumar K.V
2019-09-26 13:15       ` Aneesh Kumar K.V
2019-09-26 13:34   ` Pankaj Gupta
2019-09-26 13:34     ` Pankaj Gupta
2019-09-26 22:45   ` Andrew Morton
2019-09-26 22:45     ` Andrew Morton
2019-09-27  1:51     ` Aneesh Kumar K.V
2019-09-27  1:51       ` Aneesh Kumar K.V
2019-09-27  7:46       ` David Hildenbrand
2019-09-27  7:46         ` David Hildenbrand
2019-09-27 10:32         ` [PATCH] " Aneesh Kumar K.V
2019-09-27 10:32           ` Aneesh Kumar K.V
2019-09-27 10:38           ` David Hildenbrand
2019-09-27 10:38             ` David Hildenbrand
2019-09-27 10:36         ` [PATCH 1/2] " Aneesh Kumar K.V
2019-09-27 10:36           ` Aneesh Kumar K.V
2019-09-27 10:40           ` David Hildenbrand
2019-09-27 10:40             ` David Hildenbrand
2019-09-27 11:35             ` Aneesh Kumar K.V
2019-09-27 11:35               ` Aneesh Kumar K.V
2019-09-27 11:38               ` David Hildenbrand
2019-09-27 11:38                 ` David Hildenbrand

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190830091428.18399-2-david@redhat.com \
    --to=david@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=aneesh.kumar@linux.ibm.com \
    --cc=dan.j.williams@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mhocko@suse.com \
    --cc=osalvador@suse.de \
    --cc=pasha.tatashin@soleen.com \
    --cc=richardw.yang@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.