diff options
author | Michal Hocko <mhocko@suse.com> | 2017-07-06 18:38:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-06 19:24:32 -0400 |
commit | 2ce13640b3f4c8721e6820476cb380fbbfaedc18 (patch) | |
tree | d5aa27f26ec9af754ff15ba98cbb6bbc1ec901a6 /mm/page_isolation.c | |
parent | ccbe1e4ddece5ef9d83f2af7f28733efe6ae806a (diff) |
mm: __first_valid_page skip over offline pages
__first_valid_page skips over invalid pfns in the range but it might
still stumble over offline pages. At least start_isolate_page_range
will mark those set_migratetype_isolate. This doesn't represent any
immediate AFAICS because alloc_contig_range will fail to isolate those
pages but it relies on not fully initialized page which will become a
problem later when we stop associating offline pages to zones. Use
pfn_to_online_page to handle this.
This is more a preparatory patch than a fix.
Link: http://lkml.kernel.org/r/20170515085827.16474-10-mhocko@kernel.org
Signed-off-by: Michal Hocko <mhocko@suse.com>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Balbir Singh <bsingharora@gmail.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Daniel Kiper <daniel.kiper@oracle.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Jerome Glisse <jglisse@redhat.com>
Cc: Joonsoo Kim <js1304@gmail.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Reza Arbab <arbab@linux.vnet.ibm.com>
Cc: Tobias Regnery <tobias.regnery@gmail.com>
Cc: Toshi Kani <toshi.kani@hpe.com>
Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
Cc: Xishi Qiu <qiuxishi@huawei.com>
Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/page_isolation.c')
-rw-r--r-- | mm/page_isolation.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/mm/page_isolation.c b/mm/page_isolation.c index 5092e4ef00c8..3606104893e0 100644 --- a/mm/page_isolation.c +++ b/mm/page_isolation.c | |||
@@ -138,12 +138,18 @@ static inline struct page * | |||
138 | __first_valid_page(unsigned long pfn, unsigned long nr_pages) | 138 | __first_valid_page(unsigned long pfn, unsigned long nr_pages) |
139 | { | 139 | { |
140 | int i; | 140 | int i; |
141 | for (i = 0; i < nr_pages; i++) | 141 | |
142 | if (pfn_valid_within(pfn + i)) | 142 | for (i = 0; i < nr_pages; i++) { |
143 | break; | 143 | struct page *page; |
144 | if (unlikely(i == nr_pages)) | 144 | |
145 | return NULL; | 145 | if (!pfn_valid_within(pfn + i)) |
146 | return pfn_to_page(pfn + i); | 146 | continue; |
147 | page = pfn_to_online_page(pfn + i); | ||
148 | if (!page) | ||
149 | continue; | ||
150 | return page; | ||
151 | } | ||
152 | return NULL; | ||
147 | } | 153 | } |
148 | 154 | ||
149 | /* | 155 | /* |
@@ -184,8 +190,12 @@ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn, | |||
184 | undo: | 190 | undo: |
185 | for (pfn = start_pfn; | 191 | for (pfn = start_pfn; |
186 | pfn < undo_pfn; | 192 | pfn < undo_pfn; |
187 | pfn += pageblock_nr_pages) | 193 | pfn += pageblock_nr_pages) { |
188 | unset_migratetype_isolate(pfn_to_page(pfn), migratetype); | 194 | struct page *page = pfn_to_online_page(pfn); |
195 | if (!page) | ||
196 | continue; | ||
197 | unset_migratetype_isolate(page, migratetype); | ||
198 | } | ||
189 | 199 | ||
190 | return -EBUSY; | 200 | return -EBUSY; |
191 | } | 201 | } |