License cleanup: add SPDX GPL-2.0 license identifier to files with no license
Many source files in the tree are missing licensing information, which
makes it harder for compliance tools to determine the correct license.
By default all files without license information are under the default
license of the kernel, which is GPL version 2.
Update the files which contain no license information with the 'GPL-2.0'
SPDX license identifier. The SPDX identifier is a legally binding
shorthand, which can be used instead of the full boiler plate text.
This patch is based on work done by Thomas Gleixner and Kate Stewart and
Philippe Ombredanne.
How this work was done:
Patches were generated and checked against linux-4.14-rc6 for a subset of
the use cases:
- file had no licensing information it it.
- file was a */uapi/* one with no licensing information in it,
- file was a */uapi/* one with existing licensing information,
Further patches will be generated in subsequent months to fix up cases
where non-standard license headers were used, and references to license
had to be inferred by heuristics based on keywords.
The analysis to determine which SPDX License Identifier to be applied to
a file was done in a spreadsheet of side by side results from of the
output of two independent scanners (ScanCode & Windriver) producing SPDX
tag:value files created by Philippe Ombredanne. Philippe prepared the
base worksheet, and did an initial spot review of a few 1000 files.
The 4.13 kernel was the starting point of the analysis with 60,537 files
assessed. Kate Stewart did a file by file comparison of the scanner
results in the spreadsheet to determine which SPDX license identifier(s)
to be applied to the file. She confirmed any determination that was not
immediately clear with lawyers working with the Linux Foundation.
Criteria used to select files for SPDX license identifier tagging was:
- Files considered eligible had to be source code files.
- Make and config files were included as candidates if they contained >5
lines of source
- File already had some variant of a license header in it (even if <5
lines).
All documentation files were explicitly excluded.
The following heuristics were used to determine which SPDX license
identifiers to apply.
- when both scanners couldn't find any license traces, file was
considered to have no license information in it, and the top level
COPYING file license applied.
For non */uapi/* files that summary was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 11139
and resulted in the first patch in this series.
If that file was a */uapi/* path one, it was "GPL-2.0 WITH
Linux-syscall-note" otherwise it was "GPL-2.0". Results of that was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 WITH Linux-syscall-note 930
and resulted in the second patch in this series.
- if a file had some form of licensing information in it, and was one
of the */uapi/* ones, it was denoted with the Linux-syscall-note if
any GPL family license was found in the file or had no licensing in
it (per prior point). Results summary:
SPDX license identifier # files
---------------------------------------------------|------
GPL-2.0 WITH Linux-syscall-note 270
GPL-2.0+ WITH Linux-syscall-note 169
((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) 21
((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) 17
LGPL-2.1+ WITH Linux-syscall-note 15
GPL-1.0+ WITH Linux-syscall-note 14
((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) 5
LGPL-2.0+ WITH Linux-syscall-note 4
LGPL-2.1 WITH Linux-syscall-note 3
((GPL-2.0 WITH Linux-syscall-note) OR MIT) 3
((GPL-2.0 WITH Linux-syscall-note) AND MIT) 1
and that resulted in the third patch in this series.
- when the two scanners agreed on the detected license(s), that became
the concluded license(s).
- when there was disagreement between the two scanners (one detected a
license but the other didn't, or they both detected different
licenses) a manual inspection of the file occurred.
- In most cases a manual inspection of the information in the file
resulted in a clear resolution of the license that should apply (and
which scanner probably needed to revisit its heuristics).
- When it was not immediately clear, the license identifier was
confirmed with lawyers working with the Linux Foundation.
- If there was any question as to the appropriate license identifier,
the file was flagged for further research and to be revisited later
in time.
In total, over 70 hours of logged manual review was done on the
spreadsheet to determine the SPDX license identifiers to apply to the
source files by Kate, Philippe, Thomas and, in some cases, confirmation
by lawyers working with the Linux Foundation.
Kate also obtained a third independent scan of the 4.13 code base from
FOSSology, and compared selected files where the other two scanners
disagreed against that SPDX file, to see if there was new insights. The
Windriver scanner is based on an older version of FOSSology in part, so
they are related.
Thomas did random spot checks in about 500 files from the spreadsheets
for the uapi headers and agreed with SPDX license identifier in the
files he inspected. For the non-uapi files Thomas did random spot checks
in about 15000 files.
In initial set of patches against 4.14-rc6, 3 files were found to have
copy/paste license identifier errors, and have been fixed to reflect the
correct identifier.
Additionally Philippe spent 10 hours this week doing a detailed manual
inspection and review of the 12,461 patched files from the initial patch
version early this week with:
- a full scancode scan run, collecting the matched texts, detected
license ids and scores
- reviewing anything where there was a license detected (about 500+
files) to ensure that the applied SPDX license was correct
- reviewing anything where there was no detection but the patch license
was not GPL-2.0 WITH Linux-syscall-note to ensure that the applied
SPDX license was correct
This produced a worksheet with 20 files needing minor correction. This
worksheet was then exported into 3 different .csv files for the
different types of files to be modified.
These .csv files were then reviewed by Greg. Thomas wrote a script to
parse the csv files and add the proper SPDX tag to the file, in the
format that the file expected. This script was further refined by Greg
based on the output to detect more types of files automatically and to
distinguish between header and source .c files (which need different
comment types.) Finally Greg ran the script using the .csv files to
generate the patches.
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Reviewed-by: Philippe Ombredanne <pombredanne@nexb.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-11-01 22:07:57 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2007-10-16 16:26:11 +08:00
|
|
|
/*
|
|
|
|
* linux/mm/page_isolation.c
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/mm.h>
|
|
|
|
#include <linux/page-isolation.h>
|
|
|
|
#include <linux/pageblock-flags.h>
|
2012-08-01 07:43:50 +08:00
|
|
|
#include <linux/memory.h>
|
2013-09-12 05:22:09 +08:00
|
|
|
#include <linux/hugetlb.h>
|
2016-07-27 06:23:43 +08:00
|
|
|
#include <linux/page_owner.h>
|
2017-07-11 06:48:47 +08:00
|
|
|
#include <linux/migrate.h>
|
2007-10-16 16:26:11 +08:00
|
|
|
#include "internal.h"
|
|
|
|
|
2016-01-15 07:18:42 +08:00
|
|
|
#define CREATE_TRACE_POINTS
|
|
|
|
#include <trace/events/page_isolation.h>
|
|
|
|
|
2017-11-16 09:33:26 +08:00
|
|
|
static int set_migratetype_isolate(struct page *page, int migratetype,
|
2015-09-09 06:02:09 +08:00
|
|
|
bool skip_hwpoisoned_pages)
|
2012-08-01 07:43:50 +08:00
|
|
|
{
|
|
|
|
struct zone *zone;
|
|
|
|
unsigned long flags, pfn;
|
|
|
|
struct memory_isolate_notify arg;
|
|
|
|
int notifier_ret;
|
|
|
|
int ret = -EBUSY;
|
|
|
|
|
|
|
|
zone = page_zone(page);
|
|
|
|
|
|
|
|
spin_lock_irqsave(&zone->lock, flags);
|
|
|
|
|
2018-04-06 07:25:26 +08:00
|
|
|
/*
|
|
|
|
* We assume the caller intended to SET migrate type to isolate.
|
|
|
|
* If it is already set, then someone else must have raced and
|
|
|
|
* set it before us. Return -EBUSY
|
|
|
|
*/
|
|
|
|
if (is_migrate_isolate_page(page))
|
|
|
|
goto out;
|
|
|
|
|
2012-08-01 07:43:50 +08:00
|
|
|
pfn = page_to_pfn(page);
|
|
|
|
arg.start_pfn = pfn;
|
|
|
|
arg.nr_pages = pageblock_nr_pages;
|
|
|
|
arg.pages_found = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* It may be possible to isolate a pageblock even if the
|
|
|
|
* migratetype is not MIGRATE_MOVABLE. The memory isolation
|
|
|
|
* notifier chain is used by balloon drivers to return the
|
|
|
|
* number of pages in a range that are held by the balloon
|
|
|
|
* driver to shrink memory. If all the pages are accounted for
|
|
|
|
* by balloons, are free, or on the LRU, isolation can continue.
|
|
|
|
* Later, for example, when memory hotplug notifier runs, these
|
|
|
|
* pages reported as "can be isolated" should be isolated(freed)
|
|
|
|
* by the balloon driver through the memory notifier chain.
|
|
|
|
*/
|
|
|
|
notifier_ret = memory_isolate_notify(MEM_ISOLATE_COUNT, &arg);
|
|
|
|
notifier_ret = notifier_to_errno(notifier_ret);
|
|
|
|
if (notifier_ret)
|
|
|
|
goto out;
|
|
|
|
/*
|
|
|
|
* FIXME: Now, memory hotplug doesn't call shrink_slab() by itself.
|
|
|
|
* We just check MOVABLE pages.
|
|
|
|
*/
|
2017-11-16 09:33:26 +08:00
|
|
|
if (!has_unmovable_pages(zone, page, arg.pages_found, migratetype,
|
2012-12-12 08:00:45 +08:00
|
|
|
skip_hwpoisoned_pages))
|
2012-08-01 07:43:50 +08:00
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
/*
|
2016-10-08 08:01:16 +08:00
|
|
|
* immobile means "not-on-lru" pages. If immobile is larger than
|
2012-08-01 07:43:50 +08:00
|
|
|
* removable-by-driver pages reported by notifier, we'll fail.
|
|
|
|
*/
|
|
|
|
|
|
|
|
out:
|
|
|
|
if (!ret) {
|
2012-10-09 07:32:00 +08:00
|
|
|
unsigned long nr_pages;
|
2017-11-16 09:33:26 +08:00
|
|
|
int mt = get_pageblock_migratetype(page);
|
2012-10-09 07:32:00 +08:00
|
|
|
|
2013-01-05 07:35:08 +08:00
|
|
|
set_pageblock_migratetype(page, MIGRATE_ISOLATE);
|
mm/page_alloc: fix incorrect isolation behavior by rechecking migratetype
Before describing bugs itself, I first explain definition of freepage.
1. pages on buddy list are counted as freepage.
2. pages on isolate migratetype buddy list are *not* counted as freepage.
3. pages on cma buddy list are counted as CMA freepage, too.
Now, I describe problems and related patch.
Patch 1: There is race conditions on getting pageblock migratetype that
it results in misplacement of freepages on buddy list, incorrect
freepage count and un-availability of freepage.
Patch 2: Freepages on pcp list could have stale cached information to
determine migratetype of buddy list to go. This causes misplacement of
freepages on buddy list and incorrect freepage count.
Patch 4: Merging between freepages on different migratetype of
pageblocks will cause freepages accouting problem. This patch fixes it.
Without patchset [3], above problem doesn't happens on my CMA allocation
test, because CMA reserved pages aren't used at all. So there is no
chance for above race.
With patchset [3], I did simple CMA allocation test and get below
result:
- Virtual machine, 4 cpus, 1024 MB memory, 256 MB CMA reservation
- run kernel build (make -j16) on background
- 30 times CMA allocation(8MB * 30 = 240MB) attempts in 5 sec interval
- Result: more than 5000 freepage count are missed
With patchset [3] and this patchset, I found that no freepage count are
missed so that I conclude that problems are solved.
On my simple memory offlining test, these problems also occur on that
environment, too.
This patch (of 4):
There are two paths to reach core free function of buddy allocator,
__free_one_page(), one is free_one_page()->__free_one_page() and the
other is free_hot_cold_page()->free_pcppages_bulk()->__free_one_page().
Each paths has race condition causing serious problems. At first, this
patch is focused on first type of freepath. And then, following patch
will solve the problem in second type of freepath.
In the first type of freepath, we got migratetype of freeing page
without holding the zone lock, so it could be racy. There are two cases
of this race.
1. pages are added to isolate buddy list after restoring orignal
migratetype
CPU1 CPU2
get migratetype => return MIGRATE_ISOLATE
call free_one_page() with MIGRATE_ISOLATE
grab the zone lock
unisolate pageblock
release the zone lock
grab the zone lock
call __free_one_page() with MIGRATE_ISOLATE
freepage go into isolate buddy list,
although pageblock is already unisolated
This may cause two problems. One is that we can't use this page anymore
until next isolation attempt of this pageblock, because freepage is on
isolate buddy list. The other is that freepage accouting could be wrong
due to merging between different buddy list. Freepages on isolate buddy
list aren't counted as freepage, but ones on normal buddy list are
counted as freepage. If merge happens, buddy freepage on normal buddy
list is inevitably moved to isolate buddy list without any consideration
of freepage accouting so it could be incorrect.
2. pages are added to normal buddy list while pageblock is isolated.
It is similar with above case.
This also may cause two problems. One is that we can't keep these
freepages from being allocated. Although this pageblock is isolated,
freepage would be added to normal buddy list so that it could be
allocated without any restriction. And the other problem is same as
case 1, that it, incorrect freepage accouting.
This race condition would be prevented by checking migratetype again
with holding the zone lock. Because it is somewhat heavy operation and
it isn't needed in common case, we want to avoid rechecking as much as
possible. So this patch introduce new variable, nr_isolate_pageblock in
struct zone to check if there is isolated pageblock. With this, we can
avoid to re-check migratetype in common case and do it only if there is
isolated pageblock or migratetype is MIGRATE_ISOLATE. This solve above
mentioned problems.
Changes from v3:
Add one more check in free_one_page() that checks whether migratetype is
MIGRATE_ISOLATE or not. Without this, abovementioned case 1 could happens.
Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Acked-by: Minchan Kim <minchan@kernel.org>
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Cc: "Kirill A. Shutemov" <kirill@shutemov.name>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Cc: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
Cc: Tang Chen <tangchen@cn.fujitsu.com>
Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Cc: Wen Congyang <wency@cn.fujitsu.com>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Laura Abbott <lauraa@codeaurora.org>
Cc: Heesub Shin <heesub.shin@samsung.com>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Cc: Ritesh Harjani <ritesh.list@gmail.com>
Cc: Gioh Kim <gioh.kim@lge.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2014-11-14 07:19:11 +08:00
|
|
|
zone->nr_isolate_pageblock++;
|
mm, page_alloc: count movable pages when stealing from pageblock
When stealing pages from pageblock of a different migratetype, we count
how many free pages were stolen, and change the pageblock's migratetype
if more than half of the pageblock was free. This might be too
conservative, as there might be other pages that are not free, but were
allocated with the same migratetype as our allocation requested.
While we cannot determine the migratetype of allocated pages precisely
(at least without the page_owner functionality enabled), we can count
pages that compaction would try to isolate for migration - those are
either on LRU or __PageMovable(). The rest can be assumed to be
MIGRATE_RECLAIMABLE or MIGRATE_UNMOVABLE, which we cannot easily
distinguish. This counting can be done as part of free page stealing
with little additional overhead.
The page stealing code is changed so that it considers free pages plus
pages of the "good" migratetype for the decision whether to change
pageblock's migratetype.
The result should be more accurate migratetype of pageblocks wrt the
actual pages in the pageblocks, when stealing from semi-occupied
pageblocks. This should help the efficiency of page grouping by
mobility.
In testing based on 4.9 kernel with stress-highalloc from mmtests
configured for order-4 GFP_KERNEL allocations, this patch has reduced
the number of unmovable allocations falling back to movable pageblocks
by 47%. The number of movable allocations falling back to other
pageblocks are increased by 55%, but these events don't cause permanent
fragmentation, so the tradeoff should be positive. Later patches also
offset the movable fallback increase to some extent.
[akpm@linux-foundation.org: merge fix]
Link: http://lkml.kernel.org/r/20170307131545.28577-5-vbabka@suse.cz
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Acked-by: Mel Gorman <mgorman@techsingularity.net>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: David Rientjes <rientjes@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2017-05-09 06:54:40 +08:00
|
|
|
nr_pages = move_freepages_block(zone, page, MIGRATE_ISOLATE,
|
|
|
|
NULL);
|
2012-10-09 07:32:00 +08:00
|
|
|
|
2017-11-16 09:33:26 +08:00
|
|
|
__mod_zone_freepage_state(zone, -nr_pages, mt);
|
2012-08-01 07:43:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
spin_unlock_irqrestore(&zone->lock, flags);
|
|
|
|
if (!ret)
|
2014-12-11 07:43:04 +08:00
|
|
|
drain_all_pages(zone);
|
2012-08-01 07:43:50 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-09-09 06:02:09 +08:00
|
|
|
static void unset_migratetype_isolate(struct page *page, unsigned migratetype)
|
2012-08-01 07:43:50 +08:00
|
|
|
{
|
|
|
|
struct zone *zone;
|
2012-10-09 07:32:00 +08:00
|
|
|
unsigned long flags, nr_pages;
|
2016-07-27 06:24:01 +08:00
|
|
|
bool isolated_page = false;
|
2014-11-14 07:19:21 +08:00
|
|
|
unsigned int order;
|
2017-02-23 07:41:48 +08:00
|
|
|
unsigned long pfn, buddy_pfn;
|
2014-11-14 07:19:21 +08:00
|
|
|
struct page *buddy;
|
2012-10-09 07:32:00 +08:00
|
|
|
|
2012-08-01 07:43:50 +08:00
|
|
|
zone = page_zone(page);
|
|
|
|
spin_lock_irqsave(&zone->lock, flags);
|
2017-05-04 05:52:55 +08:00
|
|
|
if (!is_migrate_isolate_page(page))
|
2012-08-01 07:43:50 +08:00
|
|
|
goto out;
|
2014-11-14 07:19:21 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Because freepage with more than pageblock_order on isolated
|
|
|
|
* pageblock is restricted to merge due to freepage counting problem,
|
|
|
|
* it is possible that there is free buddy page.
|
|
|
|
* move_freepages_block() doesn't care of merge so we need other
|
|
|
|
* approach in order to merge them. Isolation and free will make
|
|
|
|
* these pages to be merged.
|
|
|
|
*/
|
|
|
|
if (PageBuddy(page)) {
|
|
|
|
order = page_order(page);
|
|
|
|
if (order >= pageblock_order) {
|
2017-02-23 07:41:48 +08:00
|
|
|
pfn = page_to_pfn(page);
|
|
|
|
buddy_pfn = __find_buddy_pfn(pfn, order);
|
|
|
|
buddy = page + (buddy_pfn - pfn);
|
2014-11-14 07:19:21 +08:00
|
|
|
|
2017-02-23 07:41:51 +08:00
|
|
|
if (pfn_valid_within(buddy_pfn) &&
|
2015-05-15 06:17:04 +08:00
|
|
|
!is_migrate_isolate_page(buddy)) {
|
2014-11-14 07:19:21 +08:00
|
|
|
__isolate_free_page(page, order);
|
2016-07-27 06:24:01 +08:00
|
|
|
isolated_page = true;
|
2014-11-14 07:19:21 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If we isolate freepage with more than pageblock_order, there
|
|
|
|
* should be no freepage in the range, so we could avoid costly
|
|
|
|
* pageblock scanning for freepage moving.
|
|
|
|
*/
|
|
|
|
if (!isolated_page) {
|
mm, page_alloc: count movable pages when stealing from pageblock
When stealing pages from pageblock of a different migratetype, we count
how many free pages were stolen, and change the pageblock's migratetype
if more than half of the pageblock was free. This might be too
conservative, as there might be other pages that are not free, but were
allocated with the same migratetype as our allocation requested.
While we cannot determine the migratetype of allocated pages precisely
(at least without the page_owner functionality enabled), we can count
pages that compaction would try to isolate for migration - those are
either on LRU or __PageMovable(). The rest can be assumed to be
MIGRATE_RECLAIMABLE or MIGRATE_UNMOVABLE, which we cannot easily
distinguish. This counting can be done as part of free page stealing
with little additional overhead.
The page stealing code is changed so that it considers free pages plus
pages of the "good" migratetype for the decision whether to change
pageblock's migratetype.
The result should be more accurate migratetype of pageblocks wrt the
actual pages in the pageblocks, when stealing from semi-occupied
pageblocks. This should help the efficiency of page grouping by
mobility.
In testing based on 4.9 kernel with stress-highalloc from mmtests
configured for order-4 GFP_KERNEL allocations, this patch has reduced
the number of unmovable allocations falling back to movable pageblocks
by 47%. The number of movable allocations falling back to other
pageblocks are increased by 55%, but these events don't cause permanent
fragmentation, so the tradeoff should be positive. Later patches also
offset the movable fallback increase to some extent.
[akpm@linux-foundation.org: merge fix]
Link: http://lkml.kernel.org/r/20170307131545.28577-5-vbabka@suse.cz
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Acked-by: Mel Gorman <mgorman@techsingularity.net>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: David Rientjes <rientjes@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2017-05-09 06:54:40 +08:00
|
|
|
nr_pages = move_freepages_block(zone, page, migratetype, NULL);
|
2014-11-14 07:19:21 +08:00
|
|
|
__mod_zone_freepage_state(zone, nr_pages, migratetype);
|
|
|
|
}
|
2013-01-05 07:35:08 +08:00
|
|
|
set_pageblock_migratetype(page, migratetype);
|
mm/page_alloc: fix incorrect isolation behavior by rechecking migratetype
Before describing bugs itself, I first explain definition of freepage.
1. pages on buddy list are counted as freepage.
2. pages on isolate migratetype buddy list are *not* counted as freepage.
3. pages on cma buddy list are counted as CMA freepage, too.
Now, I describe problems and related patch.
Patch 1: There is race conditions on getting pageblock migratetype that
it results in misplacement of freepages on buddy list, incorrect
freepage count and un-availability of freepage.
Patch 2: Freepages on pcp list could have stale cached information to
determine migratetype of buddy list to go. This causes misplacement of
freepages on buddy list and incorrect freepage count.
Patch 4: Merging between freepages on different migratetype of
pageblocks will cause freepages accouting problem. This patch fixes it.
Without patchset [3], above problem doesn't happens on my CMA allocation
test, because CMA reserved pages aren't used at all. So there is no
chance for above race.
With patchset [3], I did simple CMA allocation test and get below
result:
- Virtual machine, 4 cpus, 1024 MB memory, 256 MB CMA reservation
- run kernel build (make -j16) on background
- 30 times CMA allocation(8MB * 30 = 240MB) attempts in 5 sec interval
- Result: more than 5000 freepage count are missed
With patchset [3] and this patchset, I found that no freepage count are
missed so that I conclude that problems are solved.
On my simple memory offlining test, these problems also occur on that
environment, too.
This patch (of 4):
There are two paths to reach core free function of buddy allocator,
__free_one_page(), one is free_one_page()->__free_one_page() and the
other is free_hot_cold_page()->free_pcppages_bulk()->__free_one_page().
Each paths has race condition causing serious problems. At first, this
patch is focused on first type of freepath. And then, following patch
will solve the problem in second type of freepath.
In the first type of freepath, we got migratetype of freeing page
without holding the zone lock, so it could be racy. There are two cases
of this race.
1. pages are added to isolate buddy list after restoring orignal
migratetype
CPU1 CPU2
get migratetype => return MIGRATE_ISOLATE
call free_one_page() with MIGRATE_ISOLATE
grab the zone lock
unisolate pageblock
release the zone lock
grab the zone lock
call __free_one_page() with MIGRATE_ISOLATE
freepage go into isolate buddy list,
although pageblock is already unisolated
This may cause two problems. One is that we can't use this page anymore
until next isolation attempt of this pageblock, because freepage is on
isolate buddy list. The other is that freepage accouting could be wrong
due to merging between different buddy list. Freepages on isolate buddy
list aren't counted as freepage, but ones on normal buddy list are
counted as freepage. If merge happens, buddy freepage on normal buddy
list is inevitably moved to isolate buddy list without any consideration
of freepage accouting so it could be incorrect.
2. pages are added to normal buddy list while pageblock is isolated.
It is similar with above case.
This also may cause two problems. One is that we can't keep these
freepages from being allocated. Although this pageblock is isolated,
freepage would be added to normal buddy list so that it could be
allocated without any restriction. And the other problem is same as
case 1, that it, incorrect freepage accouting.
This race condition would be prevented by checking migratetype again
with holding the zone lock. Because it is somewhat heavy operation and
it isn't needed in common case, we want to avoid rechecking as much as
possible. So this patch introduce new variable, nr_isolate_pageblock in
struct zone to check if there is isolated pageblock. With this, we can
avoid to re-check migratetype in common case and do it only if there is
isolated pageblock or migratetype is MIGRATE_ISOLATE. This solve above
mentioned problems.
Changes from v3:
Add one more check in free_one_page() that checks whether migratetype is
MIGRATE_ISOLATE or not. Without this, abovementioned case 1 could happens.
Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Acked-by: Minchan Kim <minchan@kernel.org>
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Cc: "Kirill A. Shutemov" <kirill@shutemov.name>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Cc: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
Cc: Tang Chen <tangchen@cn.fujitsu.com>
Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Cc: Wen Congyang <wency@cn.fujitsu.com>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Laura Abbott <lauraa@codeaurora.org>
Cc: Heesub Shin <heesub.shin@samsung.com>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
Cc: Ritesh Harjani <ritesh.list@gmail.com>
Cc: Gioh Kim <gioh.kim@lge.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2014-11-14 07:19:11 +08:00
|
|
|
zone->nr_isolate_pageblock--;
|
2012-08-01 07:43:50 +08:00
|
|
|
out:
|
|
|
|
spin_unlock_irqrestore(&zone->lock, flags);
|
2016-07-27 06:23:43 +08:00
|
|
|
if (isolated_page) {
|
2016-07-27 06:23:58 +08:00
|
|
|
post_alloc_hook(page, order, __GFP_MOVABLE);
|
2016-07-27 06:24:01 +08:00
|
|
|
__free_pages(page, order);
|
2016-07-27 06:23:43 +08:00
|
|
|
}
|
2012-08-01 07:43:50 +08:00
|
|
|
}
|
|
|
|
|
2007-10-16 16:26:11 +08:00
|
|
|
static inline struct page *
|
|
|
|
__first_valid_page(unsigned long pfn, unsigned long nr_pages)
|
|
|
|
{
|
|
|
|
int i;
|
2017-07-07 06:38:04 +08:00
|
|
|
|
|
|
|
for (i = 0; i < nr_pages; i++) {
|
|
|
|
struct page *page;
|
|
|
|
|
|
|
|
if (!pfn_valid_within(pfn + i))
|
|
|
|
continue;
|
|
|
|
page = pfn_to_online_page(pfn + i);
|
|
|
|
if (!page)
|
|
|
|
continue;
|
|
|
|
return page;
|
|
|
|
}
|
|
|
|
return NULL;
|
2007-10-16 16:26:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* start_isolate_page_range() -- make page-allocation-type of range of pages
|
|
|
|
* to be MIGRATE_ISOLATE.
|
|
|
|
* @start_pfn: The lower PFN of the range to be isolated.
|
|
|
|
* @end_pfn: The upper PFN of the range to be isolated.
|
2012-04-03 21:06:15 +08:00
|
|
|
* @migratetype: migrate type to set in error recovery.
|
2007-10-16 16:26:11 +08:00
|
|
|
*
|
|
|
|
* Making page-allocation-type to be MIGRATE_ISOLATE means free pages in
|
|
|
|
* the range will never be allocated. Any free pages and pages freed in the
|
|
|
|
* future will not be allocated again.
|
|
|
|
*
|
|
|
|
* start_pfn/end_pfn must be aligned to pageblock_order.
|
2018-04-06 07:25:26 +08:00
|
|
|
* Return 0 on success and -EBUSY if any part of range cannot be isolated.
|
|
|
|
*
|
|
|
|
* There is no high level synchronization mechanism that prevents two threads
|
|
|
|
* from trying to isolate overlapping ranges. If this happens, one thread
|
|
|
|
* will notice pageblocks in the overlapping range already set to isolate.
|
|
|
|
* This happens in set_migratetype_isolate, and set_migratetype_isolate
|
|
|
|
* returns an error. We then clean up by restoring the migration type on
|
|
|
|
* pageblocks we may have modified and return -EBUSY to caller. This
|
|
|
|
* prevents two threads from simultaneously working on overlapping ranges.
|
2007-10-16 16:26:11 +08:00
|
|
|
*/
|
2012-04-03 21:06:15 +08:00
|
|
|
int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
|
2012-12-12 08:00:45 +08:00
|
|
|
unsigned migratetype, bool skip_hwpoisoned_pages)
|
2007-10-16 16:26:11 +08:00
|
|
|
{
|
|
|
|
unsigned long pfn;
|
|
|
|
unsigned long undo_pfn;
|
|
|
|
struct page *page;
|
|
|
|
|
2016-01-15 07:22:13 +08:00
|
|
|
BUG_ON(!IS_ALIGNED(start_pfn, pageblock_nr_pages));
|
|
|
|
BUG_ON(!IS_ALIGNED(end_pfn, pageblock_nr_pages));
|
2007-10-16 16:26:11 +08:00
|
|
|
|
|
|
|
for (pfn = start_pfn;
|
|
|
|
pfn < end_pfn;
|
|
|
|
pfn += pageblock_nr_pages) {
|
|
|
|
page = __first_valid_page(pfn, pageblock_nr_pages);
|
2012-12-12 08:00:45 +08:00
|
|
|
if (page &&
|
2017-11-16 09:33:26 +08:00
|
|
|
set_migratetype_isolate(page, migratetype, skip_hwpoisoned_pages)) {
|
2007-10-16 16:26:11 +08:00
|
|
|
undo_pfn = pfn;
|
|
|
|
goto undo;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
undo:
|
|
|
|
for (pfn = start_pfn;
|
2007-11-15 08:59:12 +08:00
|
|
|
pfn < undo_pfn;
|
2017-07-07 06:38:04 +08:00
|
|
|
pfn += pageblock_nr_pages) {
|
|
|
|
struct page *page = pfn_to_online_page(pfn);
|
|
|
|
if (!page)
|
|
|
|
continue;
|
|
|
|
unset_migratetype_isolate(page, migratetype);
|
|
|
|
}
|
2007-10-16 16:26:11 +08:00
|
|
|
|
|
|
|
return -EBUSY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make isolated pages available again.
|
|
|
|
*/
|
2012-04-03 21:06:15 +08:00
|
|
|
int undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
|
|
|
|
unsigned migratetype)
|
2007-10-16 16:26:11 +08:00
|
|
|
{
|
|
|
|
unsigned long pfn;
|
|
|
|
struct page *page;
|
2016-01-16 08:57:13 +08:00
|
|
|
|
|
|
|
BUG_ON(!IS_ALIGNED(start_pfn, pageblock_nr_pages));
|
|
|
|
BUG_ON(!IS_ALIGNED(end_pfn, pageblock_nr_pages));
|
|
|
|
|
2007-10-16 16:26:11 +08:00
|
|
|
for (pfn = start_pfn;
|
|
|
|
pfn < end_pfn;
|
|
|
|
pfn += pageblock_nr_pages) {
|
|
|
|
page = __first_valid_page(pfn, pageblock_nr_pages);
|
2017-05-04 05:52:55 +08:00
|
|
|
if (!page || !is_migrate_isolate_page(page))
|
2007-10-16 16:26:11 +08:00
|
|
|
continue;
|
2012-04-03 21:06:15 +08:00
|
|
|
unset_migratetype_isolate(page, migratetype);
|
2007-10-16 16:26:11 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Test all pages in the range is free(means isolated) or not.
|
|
|
|
* all pages in [start_pfn...end_pfn) must be in the same zone.
|
|
|
|
* zone->lock must be held before call this.
|
|
|
|
*
|
2016-04-02 05:31:37 +08:00
|
|
|
* Returns the last tested pfn.
|
2007-10-16 16:26:11 +08:00
|
|
|
*/
|
2016-01-15 07:18:39 +08:00
|
|
|
static unsigned long
|
2012-12-12 08:00:45 +08:00
|
|
|
__test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn,
|
|
|
|
bool skip_hwpoisoned_pages)
|
2007-10-16 16:26:11 +08:00
|
|
|
{
|
|
|
|
struct page *page;
|
|
|
|
|
|
|
|
while (pfn < end_pfn) {
|
|
|
|
if (!pfn_valid_within(pfn)) {
|
|
|
|
pfn++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
page = pfn_to_page(pfn);
|
mm, page_isolation: remove bogus tests for isolated pages
The __test_page_isolated_in_pageblock() is used to verify whether all
pages in pageblock were either successfully isolated, or are hwpoisoned.
Two of the possible state of pages, that are tested, are however bogus
and misleading.
Both tests rely on get_freepage_migratetype(page), which however has no
guarantees about pages on freelists. Specifically, it doesn't guarantee
that the migratetype returned by the function actually matches the
migratetype of the freelist that the page is on. Such guarantee is not
its purpose and would have negative impact on allocator performance.
The first test checks whether the freepage_migratetype equals
MIGRATE_ISOLATE, supposedly to catch races between page isolation and
allocator activity. These races should be fixed nowadays with
51bb1a4093 ("mm/page_alloc: add freepage on isolate pageblock to correct
buddy list") and related patches. As explained above, the check
wouldn't be able to catch them reliably anyway. For the same reason
false positives can happen, although they are harmless, as the
move_freepages() call would just move the page to the same freelist it's
already on. So removing the test is not a bug fix, just cleanup. After
this patch, we assume that all PageBuddy pages are on the correct
freelist and that the races were really fixed. A truly reliable
verification in the form of e.g. VM_BUG_ON() would be complicated and
is arguably not needed.
The second test (page_count(page) == 0 && get_freepage_migratetype(page)
== MIGRATE_ISOLATE) is probably supposed (the code comes from a big
memory isolation patch from 2007) to catch pages on MIGRATE_ISOLATE
pcplists. However, pcplists don't contain MIGRATE_ISOLATE freepages
nowadays, those are freed directly to free lists, so the check is
obsolete. Remove it as well.
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Acked-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Minchan Kim <minchan@kernel.org>
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Cc: Laura Abbott <lauraa@codeaurora.org>
Reviewed-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: Seungho Park <seungho1.park@lge.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Acked-by: Mel Gorman <mgorman@techsingularity.net>
Cc: David Rientjes <rientjes@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2015-09-09 06:01:22 +08:00
|
|
|
if (PageBuddy(page))
|
2012-10-09 07:32:16 +08:00
|
|
|
/*
|
mm, page_isolation: remove bogus tests for isolated pages
The __test_page_isolated_in_pageblock() is used to verify whether all
pages in pageblock were either successfully isolated, or are hwpoisoned.
Two of the possible state of pages, that are tested, are however bogus
and misleading.
Both tests rely on get_freepage_migratetype(page), which however has no
guarantees about pages on freelists. Specifically, it doesn't guarantee
that the migratetype returned by the function actually matches the
migratetype of the freelist that the page is on. Such guarantee is not
its purpose and would have negative impact on allocator performance.
The first test checks whether the freepage_migratetype equals
MIGRATE_ISOLATE, supposedly to catch races between page isolation and
allocator activity. These races should be fixed nowadays with
51bb1a4093 ("mm/page_alloc: add freepage on isolate pageblock to correct
buddy list") and related patches. As explained above, the check
wouldn't be able to catch them reliably anyway. For the same reason
false positives can happen, although they are harmless, as the
move_freepages() call would just move the page to the same freelist it's
already on. So removing the test is not a bug fix, just cleanup. After
this patch, we assume that all PageBuddy pages are on the correct
freelist and that the races were really fixed. A truly reliable
verification in the form of e.g. VM_BUG_ON() would be complicated and
is arguably not needed.
The second test (page_count(page) == 0 && get_freepage_migratetype(page)
== MIGRATE_ISOLATE) is probably supposed (the code comes from a big
memory isolation patch from 2007) to catch pages on MIGRATE_ISOLATE
pcplists. However, pcplists don't contain MIGRATE_ISOLATE freepages
nowadays, those are freed directly to free lists, so the check is
obsolete. Remove it as well.
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Acked-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Minchan Kim <minchan@kernel.org>
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Cc: Laura Abbott <lauraa@codeaurora.org>
Reviewed-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: Seungho Park <seungho1.park@lge.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Acked-by: Mel Gorman <mgorman@techsingularity.net>
Cc: David Rientjes <rientjes@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2015-09-09 06:01:22 +08:00
|
|
|
* If the page is on a free list, it has to be on
|
|
|
|
* the correct MIGRATE_ISOLATE freelist. There is no
|
|
|
|
* simple way to verify that as VM_BUG_ON(), though.
|
2012-10-09 07:32:16 +08:00
|
|
|
*/
|
2007-10-16 16:26:11 +08:00
|
|
|
pfn += 1 << page_order(page);
|
mm, page_isolation: remove bogus tests for isolated pages
The __test_page_isolated_in_pageblock() is used to verify whether all
pages in pageblock were either successfully isolated, or are hwpoisoned.
Two of the possible state of pages, that are tested, are however bogus
and misleading.
Both tests rely on get_freepage_migratetype(page), which however has no
guarantees about pages on freelists. Specifically, it doesn't guarantee
that the migratetype returned by the function actually matches the
migratetype of the freelist that the page is on. Such guarantee is not
its purpose and would have negative impact on allocator performance.
The first test checks whether the freepage_migratetype equals
MIGRATE_ISOLATE, supposedly to catch races between page isolation and
allocator activity. These races should be fixed nowadays with
51bb1a4093 ("mm/page_alloc: add freepage on isolate pageblock to correct
buddy list") and related patches. As explained above, the check
wouldn't be able to catch them reliably anyway. For the same reason
false positives can happen, although they are harmless, as the
move_freepages() call would just move the page to the same freelist it's
already on. So removing the test is not a bug fix, just cleanup. After
this patch, we assume that all PageBuddy pages are on the correct
freelist and that the races were really fixed. A truly reliable
verification in the form of e.g. VM_BUG_ON() would be complicated and
is arguably not needed.
The second test (page_count(page) == 0 && get_freepage_migratetype(page)
== MIGRATE_ISOLATE) is probably supposed (the code comes from a big
memory isolation patch from 2007) to catch pages on MIGRATE_ISOLATE
pcplists. However, pcplists don't contain MIGRATE_ISOLATE freepages
nowadays, those are freed directly to free lists, so the check is
obsolete. Remove it as well.
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Acked-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Minchan Kim <minchan@kernel.org>
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Cc: Laura Abbott <lauraa@codeaurora.org>
Reviewed-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: Seungho Park <seungho1.park@lge.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Acked-by: Mel Gorman <mgorman@techsingularity.net>
Cc: David Rientjes <rientjes@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2015-09-09 06:01:22 +08:00
|
|
|
else if (skip_hwpoisoned_pages && PageHWPoison(page))
|
|
|
|
/* A HWPoisoned page cannot be also PageBuddy */
|
2012-12-12 08:00:45 +08:00
|
|
|
pfn++;
|
2007-10-16 16:26:11 +08:00
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
2016-01-15 07:18:39 +08:00
|
|
|
|
|
|
|
return pfn;
|
2007-10-16 16:26:11 +08:00
|
|
|
}
|
|
|
|
|
2016-05-20 08:12:06 +08:00
|
|
|
/* Caller should ensure that requested range is in a single zone */
|
2012-12-12 08:00:45 +08:00
|
|
|
int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn,
|
|
|
|
bool skip_hwpoisoned_pages)
|
2007-10-16 16:26:11 +08:00
|
|
|
{
|
memory hotplug: missing zone->lock in test_pages_isolated()
__test_page_isolated_in_pageblock() in mm/page_isolation.c has a comment
saying that the caller must hold zone->lock. But the only caller of that
function, test_pages_isolated(), does not hold zone->lock and the lock is
also not acquired anywhere before. This patch adds the missing zone->lock
to test_pages_isolated().
We reproducibly run into BUG_ON(!PageBuddy(page)) in __offline_isolated_pages()
during memory hotplug stress test, see trace below. This patch fixes that
problem, it would be good if we could have it in 2.6.27.
kernel BUG at /home/autobuild/BUILD/linux-2.6.26-20080909/mm/page_alloc.c:4561!
illegal operation: 0001 [#1] PREEMPT SMP
Modules linked in: dm_multipath sunrpc bonding qeth_l3 dm_mod qeth ccwgroup vmur
CPU: 1 Not tainted 2.6.26-29.x.20080909-s390default #1
Process memory_loop_all (pid: 10025, task: 2f444028, ksp: 2b10dd28)
Krnl PSW : 040c0000 801727ea (__offline_isolated_pages+0x18e/0x1c4)
R:0 T:1 IO:0 EX:0 Key:0 M:1 W:0 P:0 AS:0 CC:0 PM:0
Krnl GPRS: 00000000 7e27fc00 00000000 7e27fc00
00000000 00000400 00014000 7e27fc01
00606f00 7e27fc00 00013fe0 2b10dd28
00000005 80172662 801727b2 2b10dd28
Krnl Code: 801727de: 5810900c l %r1,12(%r9)
801727e2: a7f4ffb3 brc 15,80172748
801727e6: a7f40001 brc 15,801727e8
>801727ea: a7f4ffbc brc 15,80172762
801727ee: a7f40001 brc 15,801727f0
801727f2: a7f4ffaf brc 15,80172750
801727f6: 0707 bcr 0,%r7
801727f8: 0017 unknown
Call Trace:
([<0000000000172772>] __offline_isolated_pages+0x116/0x1c4)
[<00000000001953a2>] offline_isolated_pages_cb+0x22/0x34
[<000000000013164c>] walk_memory_resource+0xcc/0x11c
[<000000000019520e>] offline_pages+0x36a/0x498
[<00000000001004d6>] remove_memory+0x36/0x44
[<000000000028fb06>] memory_block_change_state+0x112/0x150
[<000000000028ffb8>] store_mem_state+0x90/0xe4
[<0000000000289c00>] sysdev_store+0x34/0x40
[<00000000001ee048>] sysfs_write_file+0xd0/0x178
[<000000000019b1a8>] vfs_write+0x74/0x118
[<000000000019b9ae>] sys_write+0x46/0x7c
[<000000000011160e>] sysc_do_restart+0x12/0x16
[<0000000077f3e8ca>] 0x77f3e8ca
Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-10-03 05:50:16 +08:00
|
|
|
unsigned long pfn, flags;
|
2007-10-16 16:26:11 +08:00
|
|
|
struct page *page;
|
memory hotplug: missing zone->lock in test_pages_isolated()
__test_page_isolated_in_pageblock() in mm/page_isolation.c has a comment
saying that the caller must hold zone->lock. But the only caller of that
function, test_pages_isolated(), does not hold zone->lock and the lock is
also not acquired anywhere before. This patch adds the missing zone->lock
to test_pages_isolated().
We reproducibly run into BUG_ON(!PageBuddy(page)) in __offline_isolated_pages()
during memory hotplug stress test, see trace below. This patch fixes that
problem, it would be good if we could have it in 2.6.27.
kernel BUG at /home/autobuild/BUILD/linux-2.6.26-20080909/mm/page_alloc.c:4561!
illegal operation: 0001 [#1] PREEMPT SMP
Modules linked in: dm_multipath sunrpc bonding qeth_l3 dm_mod qeth ccwgroup vmur
CPU: 1 Not tainted 2.6.26-29.x.20080909-s390default #1
Process memory_loop_all (pid: 10025, task: 2f444028, ksp: 2b10dd28)
Krnl PSW : 040c0000 801727ea (__offline_isolated_pages+0x18e/0x1c4)
R:0 T:1 IO:0 EX:0 Key:0 M:1 W:0 P:0 AS:0 CC:0 PM:0
Krnl GPRS: 00000000 7e27fc00 00000000 7e27fc00
00000000 00000400 00014000 7e27fc01
00606f00 7e27fc00 00013fe0 2b10dd28
00000005 80172662 801727b2 2b10dd28
Krnl Code: 801727de: 5810900c l %r1,12(%r9)
801727e2: a7f4ffb3 brc 15,80172748
801727e6: a7f40001 brc 15,801727e8
>801727ea: a7f4ffbc brc 15,80172762
801727ee: a7f40001 brc 15,801727f0
801727f2: a7f4ffaf brc 15,80172750
801727f6: 0707 bcr 0,%r7
801727f8: 0017 unknown
Call Trace:
([<0000000000172772>] __offline_isolated_pages+0x116/0x1c4)
[<00000000001953a2>] offline_isolated_pages_cb+0x22/0x34
[<000000000013164c>] walk_memory_resource+0xcc/0x11c
[<000000000019520e>] offline_pages+0x36a/0x498
[<00000000001004d6>] remove_memory+0x36/0x44
[<000000000028fb06>] memory_block_change_state+0x112/0x150
[<000000000028ffb8>] store_mem_state+0x90/0xe4
[<0000000000289c00>] sysdev_store+0x34/0x40
[<00000000001ee048>] sysfs_write_file+0xd0/0x178
[<000000000019b1a8>] vfs_write+0x74/0x118
[<000000000019b9ae>] sys_write+0x46/0x7c
[<000000000011160e>] sysc_do_restart+0x12/0x16
[<0000000077f3e8ca>] 0x77f3e8ca
Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-10-03 05:50:16 +08:00
|
|
|
struct zone *zone;
|
2007-10-16 16:26:11 +08:00
|
|
|
|
|
|
|
/*
|
2013-06-20 18:10:19 +08:00
|
|
|
* Note: pageblock_nr_pages != MAX_ORDER. Then, chunks of free pages
|
|
|
|
* are not aligned to pageblock_nr_pages.
|
|
|
|
* Then we just check migratetype first.
|
2007-10-16 16:26:11 +08:00
|
|
|
*/
|
|
|
|
for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) {
|
|
|
|
page = __first_valid_page(pfn, pageblock_nr_pages);
|
2017-05-04 05:52:55 +08:00
|
|
|
if (page && !is_migrate_isolate_page(page))
|
2007-10-16 16:26:11 +08:00
|
|
|
break;
|
|
|
|
}
|
2008-11-07 04:53:36 +08:00
|
|
|
page = __first_valid_page(start_pfn, end_pfn - start_pfn);
|
|
|
|
if ((pfn < end_pfn) || !page)
|
2007-10-16 16:26:11 +08:00
|
|
|
return -EBUSY;
|
2013-06-20 18:10:19 +08:00
|
|
|
/* Check all pages are free or marked as ISOLATED */
|
2008-11-07 04:53:36 +08:00
|
|
|
zone = page_zone(page);
|
memory hotplug: missing zone->lock in test_pages_isolated()
__test_page_isolated_in_pageblock() in mm/page_isolation.c has a comment
saying that the caller must hold zone->lock. But the only caller of that
function, test_pages_isolated(), does not hold zone->lock and the lock is
also not acquired anywhere before. This patch adds the missing zone->lock
to test_pages_isolated().
We reproducibly run into BUG_ON(!PageBuddy(page)) in __offline_isolated_pages()
during memory hotplug stress test, see trace below. This patch fixes that
problem, it would be good if we could have it in 2.6.27.
kernel BUG at /home/autobuild/BUILD/linux-2.6.26-20080909/mm/page_alloc.c:4561!
illegal operation: 0001 [#1] PREEMPT SMP
Modules linked in: dm_multipath sunrpc bonding qeth_l3 dm_mod qeth ccwgroup vmur
CPU: 1 Not tainted 2.6.26-29.x.20080909-s390default #1
Process memory_loop_all (pid: 10025, task: 2f444028, ksp: 2b10dd28)
Krnl PSW : 040c0000 801727ea (__offline_isolated_pages+0x18e/0x1c4)
R:0 T:1 IO:0 EX:0 Key:0 M:1 W:0 P:0 AS:0 CC:0 PM:0
Krnl GPRS: 00000000 7e27fc00 00000000 7e27fc00
00000000 00000400 00014000 7e27fc01
00606f00 7e27fc00 00013fe0 2b10dd28
00000005 80172662 801727b2 2b10dd28
Krnl Code: 801727de: 5810900c l %r1,12(%r9)
801727e2: a7f4ffb3 brc 15,80172748
801727e6: a7f40001 brc 15,801727e8
>801727ea: a7f4ffbc brc 15,80172762
801727ee: a7f40001 brc 15,801727f0
801727f2: a7f4ffaf brc 15,80172750
801727f6: 0707 bcr 0,%r7
801727f8: 0017 unknown
Call Trace:
([<0000000000172772>] __offline_isolated_pages+0x116/0x1c4)
[<00000000001953a2>] offline_isolated_pages_cb+0x22/0x34
[<000000000013164c>] walk_memory_resource+0xcc/0x11c
[<000000000019520e>] offline_pages+0x36a/0x498
[<00000000001004d6>] remove_memory+0x36/0x44
[<000000000028fb06>] memory_block_change_state+0x112/0x150
[<000000000028ffb8>] store_mem_state+0x90/0xe4
[<0000000000289c00>] sysdev_store+0x34/0x40
[<00000000001ee048>] sysfs_write_file+0xd0/0x178
[<000000000019b1a8>] vfs_write+0x74/0x118
[<000000000019b9ae>] sys_write+0x46/0x7c
[<000000000011160e>] sysc_do_restart+0x12/0x16
[<0000000077f3e8ca>] 0x77f3e8ca
Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-10-03 05:50:16 +08:00
|
|
|
spin_lock_irqsave(&zone->lock, flags);
|
2016-01-15 07:18:39 +08:00
|
|
|
pfn = __test_page_isolated_in_pageblock(start_pfn, end_pfn,
|
2012-12-12 08:00:45 +08:00
|
|
|
skip_hwpoisoned_pages);
|
memory hotplug: missing zone->lock in test_pages_isolated()
__test_page_isolated_in_pageblock() in mm/page_isolation.c has a comment
saying that the caller must hold zone->lock. But the only caller of that
function, test_pages_isolated(), does not hold zone->lock and the lock is
also not acquired anywhere before. This patch adds the missing zone->lock
to test_pages_isolated().
We reproducibly run into BUG_ON(!PageBuddy(page)) in __offline_isolated_pages()
during memory hotplug stress test, see trace below. This patch fixes that
problem, it would be good if we could have it in 2.6.27.
kernel BUG at /home/autobuild/BUILD/linux-2.6.26-20080909/mm/page_alloc.c:4561!
illegal operation: 0001 [#1] PREEMPT SMP
Modules linked in: dm_multipath sunrpc bonding qeth_l3 dm_mod qeth ccwgroup vmur
CPU: 1 Not tainted 2.6.26-29.x.20080909-s390default #1
Process memory_loop_all (pid: 10025, task: 2f444028, ksp: 2b10dd28)
Krnl PSW : 040c0000 801727ea (__offline_isolated_pages+0x18e/0x1c4)
R:0 T:1 IO:0 EX:0 Key:0 M:1 W:0 P:0 AS:0 CC:0 PM:0
Krnl GPRS: 00000000 7e27fc00 00000000 7e27fc00
00000000 00000400 00014000 7e27fc01
00606f00 7e27fc00 00013fe0 2b10dd28
00000005 80172662 801727b2 2b10dd28
Krnl Code: 801727de: 5810900c l %r1,12(%r9)
801727e2: a7f4ffb3 brc 15,80172748
801727e6: a7f40001 brc 15,801727e8
>801727ea: a7f4ffbc brc 15,80172762
801727ee: a7f40001 brc 15,801727f0
801727f2: a7f4ffaf brc 15,80172750
801727f6: 0707 bcr 0,%r7
801727f8: 0017 unknown
Call Trace:
([<0000000000172772>] __offline_isolated_pages+0x116/0x1c4)
[<00000000001953a2>] offline_isolated_pages_cb+0x22/0x34
[<000000000013164c>] walk_memory_resource+0xcc/0x11c
[<000000000019520e>] offline_pages+0x36a/0x498
[<00000000001004d6>] remove_memory+0x36/0x44
[<000000000028fb06>] memory_block_change_state+0x112/0x150
[<000000000028ffb8>] store_mem_state+0x90/0xe4
[<0000000000289c00>] sysdev_store+0x34/0x40
[<00000000001ee048>] sysfs_write_file+0xd0/0x178
[<000000000019b1a8>] vfs_write+0x74/0x118
[<000000000019b9ae>] sys_write+0x46/0x7c
[<000000000011160e>] sysc_do_restart+0x12/0x16
[<0000000077f3e8ca>] 0x77f3e8ca
Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-10-03 05:50:16 +08:00
|
|
|
spin_unlock_irqrestore(&zone->lock, flags);
|
2016-01-15 07:18:39 +08:00
|
|
|
|
2016-01-15 07:18:42 +08:00
|
|
|
trace_test_pages_isolated(start_pfn, end_pfn, pfn);
|
|
|
|
|
2016-01-15 07:18:39 +08:00
|
|
|
return pfn < end_pfn ? -EBUSY : 0;
|
2007-10-16 16:26:11 +08:00
|
|
|
}
|
2012-10-09 07:32:52 +08:00
|
|
|
|
|
|
|
struct page *alloc_migrate_target(struct page *page, unsigned long private,
|
|
|
|
int **resultp)
|
|
|
|
{
|
2017-07-11 06:48:47 +08:00
|
|
|
return new_page_nodemask(page, numa_node_id(), &node_states[N_MEMORY]);
|
2012-10-09 07:32:52 +08:00
|
|
|
}
|