Home Home > GIT Browse > SLE15
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2017-07-04 10:50:57 +0200
committerTakashi Iwai <tiwai@suse.de>2017-07-04 10:50:57 +0200
commit601ea515fd7c90a98f218e21bcd655051e5b7731 (patch)
tree260a5be217b9980726297990e342846766007b69
parent540206bc749a3080787d03a726c0529e1935d31f (diff)
parent20dfae637099f63de6719f4a099f4a8aff80039f (diff)
Merge branch 'SLE12-SP2' into users/tiwai/SLE12-SP3/for-updaterpm-4.4.75-8
-rw-r--r--patches.fixes/mm-fix-classzone_idx-underflow-in-shrink_zones.patch111
-rw-r--r--series.conf2
2 files changed, 113 insertions, 0 deletions
diff --git a/patches.fixes/mm-fix-classzone_idx-underflow-in-shrink_zones.patch b/patches.fixes/mm-fix-classzone_idx-underflow-in-shrink_zones.patch
new file mode 100644
index 0000000000..db1f83c482
--- /dev/null
+++ b/patches.fixes/mm-fix-classzone_idx-underflow-in-shrink_zones.patch
@@ -0,0 +1,111 @@
+From a1a1e459276298ac98827520e07923aa1219dbe1 Mon Sep 17 00:00:00 2001
+From: Vlastimil Babka <vbabka@suse.cz>
+Date: Thu, 22 Jun 2017 16:23:13 +0200
+Subject: [PATCH] mm: fix classzone_idx underflow in shrink_zones()
+Patch-mainline: Never, upstream fixed accidentaly as part of zone->node reclaim rework by commit b2e18757f2c9d
+References: VM Functionality, bsc#1042314
+
+We've got reported a BUG in do_try_to_free_pages():
+
+BUG: unable to handle kernel paging request at ffff8ffffff28990
+IP: [<ffffffff8119abe0>] do_try_to_free_pages+0x140/0x490
+PGD 0
+Oops: 0000 [#1] SMP
+megaraid_sas sg scsi_mod efivarfs autofs4
+Supported: No, Unsupported modules are loaded
+Workqueue: kacpi_hotplug acpi_hotplug_work_fn
+task: ffff88ffd0d4c540 ti: ffff88ffd0e48000 task.ti: ffff88ffd0e48000
+RIP: 0010:[<ffffffff8119abe0>] [<ffffffff8119abe0>] do_try_to_free_pages+0x140/0x490
+RSP: 0018:ffff88ffd0e4ba60 EFLAGS: 00010206
+RAX: 000006fffffff900 RBX: 00000000ffffffff RCX: ffff88fffff29000
+RDX: 000000ffffffff00 RSI: 0000000000000003 RDI: 00000000024200c8
+RBP: 0000000001320122 R08: 0000000000000000 R09: ffff88ffd0e4bbac
+R10: 0000000000000000 R11: 0000000000000000 R12: ffff88ffd0e4bae0
+R13: 0000000000000e00 R14: ffff88fffff2a500 R15: ffff88fffff2b300
+FS: 0000000000000000(0000) GS:ffff88ffe6440000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: ffff8ffffff28990 CR3: 0000000001c0a000 CR4: 00000000003406e0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Stack:
+ 00000002db570a80 024200c80000001e ffff88fffff2b300 0000000000000000
+ ffff88fffffd5700 ffff88ffd0d4c540 ffff88ffd0d4c540 ffffffff0000000c
+ 0000000000000000 0000000000000040 00000000024200c8 ffff88ffd0e4bae0
+Call Trace:
+ [<ffffffff8119afea>] try_to_free_pages+0xba/0x170
+ [<ffffffff8118cf2f>] __alloc_pages_nodemask+0x53f/0xb20
+ [<ffffffff811d39ff>] alloc_pages_current+0x7f/0x100
+ [<ffffffff811e2232>] migrate_pages+0x202/0x710
+ [<ffffffff815dadaa>] __offline_pages.constprop.23+0x4ba/0x790
+ [<ffffffff81463263>] memory_subsys_offline+0x43/0x70
+ [<ffffffff8144cbed>] device_offline+0x7d/0xa0
+ [<ffffffff81392fa2>] acpi_bus_offline+0xa5/0xef
+ [<ffffffff81394a77>] acpi_device_hotplug+0x21b/0x41f
+ [<ffffffff8138dab7>] acpi_hotplug_work_fn+0x1a/0x23
+ [<ffffffff81093cee>] process_one_work+0x14e/0x410
+ [<ffffffff81094546>] worker_thread+0x116/0x490
+ [<ffffffff810999ed>] kthread+0xbd/0xe0
+ [<ffffffff815e4e7f>] ret_from_fork+0x3f/0x70
+
+This translates to the loop in shrink_zone():
+
+classzone_idx = requested_highidx;
+while (!populated_zone(zone->zone_pgdat->node_zones +
+ classzone_idx))
+ classzone_idx--;
+
+where no zone is populated, so classzone_idx becomes -1 (in RBX).
+
+Added debugging output reveals that we enter the function with
+sc->gfp_mask == GFP_NOFS|__GFP_NOFAIL|__GFP_HARDWALL|__GFP_MOVABLE
+requested_highidx = gfp_zone(sc->gfp_mask) == 2 (ZONE_NORMAL)
+
+Inside the for loop, however:
+gfp_zone(sc->gfp_mask) == 3 (ZONE_MOVABLE)
+
+This means we have gone through this branch:
+
+if (buffer_heads_over_limit)
+ sc->gfp_mask |= __GFP_HIGHMEM;
+
+This changes the gfp_zone() result, but requested_highidx remains unchanged.
+On nodes where the only populated zone is movable, the inner while loop will
+check only lower zones, which are not populated, and underflow classzone_idx.
+
+To sum up, the bug occurs in configurations with ZONE_MOVABLE (such as when
+booted with the movable_node parameter) and only in situations when
+buffer_heads_over_limit is true, and there's an allocation with __GFP_MOVABLE
+and without __GFP_HIGHMEM performing direct reclaim.
+
+This patch makes sure that classzone_idx starts with the correct zone.
+
+Mainline has been affected in versions 4.6 and 4.7, but the culprit commit has
+been also included in stable trees.
+In mainline, this has been fixed accidentally as part of 34-patch series (plus
+follow-up fixes) "Move LRU page reclaim from zones to nodes", which makes the
+mainline commit unsuitable for stable backport, unfortunately.
+
+Fixes: 7bf52fb891b6 ("mm: vmscan: reclaim highmem zone if buffer_heads is over limit")
+Obsoleted-by: b2e18757f2c9 ("mm, vmscan: begin reclaiming pages on a per-node basis")
+Debugged-by: Michal Hocko <mhocko@suse.cz>
+Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Mel Gorman <mgorman@techsingularity.net>
+Cc: <stable@vger.kernel.org>
+
+---
+ mm/vmscan.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -2539,7 +2539,7 @@ static bool shrink_zones(struct zonelist
+ if (!populated_zone(zone))
+ continue;
+
+- classzone_idx = requested_highidx;
++ classzone_idx = gfp_zone(sc->gfp_mask);
+ while (!populated_zone(zone->zone_pgdat->node_zones +
+ classzone_idx))
+ classzone_idx--;
diff --git a/series.conf b/series.conf
index 2da1a12cd7..0c26a9785e 100644
--- a/series.conf
+++ b/series.conf
@@ -2719,6 +2719,8 @@
patches.fixes/fuse-fix-clearing-suid-sgid-for-chown.patch
patches.fixes/hwpoison-memcg-forcibly-uncharge-LRU-pages.patch
+
+ patches.fixes/mm-fix-classzone_idx-underflow-in-shrink_zones.patch
# MADV_FREE
patches.suse/mm-support-madvise-MADV_FREE.patch