1 // SPDX-License-Identifier: GPL-2.0 1 // SPDX-License-Identifier: GPL-2.0 2 /* 2 /* 3 * linux/mm/page_isolation.c 3 * linux/mm/page_isolation.c 4 */ 4 */ 5 5 6 #include <linux/mm.h> 6 #include <linux/mm.h> 7 #include <linux/page-isolation.h> 7 #include <linux/page-isolation.h> 8 #include <linux/pageblock-flags.h> 8 #include <linux/pageblock-flags.h> 9 #include <linux/memory.h> 9 #include <linux/memory.h> 10 #include <linux/hugetlb.h> 10 #include <linux/hugetlb.h> 11 #include <linux/page_owner.h> 11 #include <linux/page_owner.h> 12 #include <linux/migrate.h> 12 #include <linux/migrate.h> 13 #include "internal.h" 13 #include "internal.h" 14 14 15 #define CREATE_TRACE_POINTS 15 #define CREATE_TRACE_POINTS 16 #include <trace/events/page_isolation.h> 16 #include <trace/events/page_isolation.h> 17 17 18 /* !! 18 static int set_migratetype_isolate(struct page *page, int migratetype, int isol_flags) 19 * This function checks whether the range [sta << 20 * unmovable pages or not. The range must fall << 21 * consequently belong to a single zone. << 22 * << 23 * PageLRU check without isolation or lru_lock << 24 * MIGRATE_MOVABLE block might include unmovab << 25 * check without lock_page also may miss some << 26 * race condition. So you can't expect this fu << 27 * << 28 * Returns a page without holding a reference. << 29 * dereference that page (e.g., dumping), it h << 30 * cannot get removed (e.g., via memory unplug << 31 * << 32 */ << 33 static struct page *has_unmovable_pages(unsign << 34 int migratetyp << 35 { << 36 struct page *page = pfn_to_page(start_ << 37 struct zone *zone = page_zone(page); << 38 unsigned long pfn; << 39 << 40 VM_BUG_ON(pageblock_start_pfn(start_pf << 41 pageblock_start_pfn(end_pfn << 42 << 43 if (is_migrate_cma_page(page)) { << 44 /* << 45 * CMA allocations (alloc_cont << 46 * isolate CMA pageblocks even << 47 * so consider them movable he << 48 */ << 49 if (is_migrate_cma(migratetype << 50 return NULL; << 51 << 52 return page; << 53 } << 54 << 55 for (pfn = start_pfn; pfn < end_pfn; p << 56 page = pfn_to_page(pfn); << 57 << 58 /* << 59 * Both, bootmem allocations a << 60 * PG_reserved and are unmovab << 61 * allocations inside ZONE_MOV << 62 * specifying "movablecore". << 63 */ << 64 if (PageReserved(page)) << 65 return page; << 66 << 67 /* << 68 * If the zone is movable and << 69 * pages then it should be rea << 70 * is movable. << 71 */ << 72 if (zone_idx(zone) == ZONE_MOV << 73 continue; << 74 << 75 /* << 76 * Hugepages are not in LRU li << 77 * THPs are on the LRU, but ne << 78 * We need not scan over tail << 79 * handle each tail page indiv << 80 */ << 81 if (PageHuge(page) || PageTran << 82 struct folio *folio = << 83 unsigned int skip_page << 84 << 85 if (PageHuge(page)) { << 86 if (!hugepage_ << 87 return << 88 } else if (!folio_test << 89 return page; << 90 } << 91 << 92 skip_pages = folio_nr_ << 93 pfn += skip_pages - 1; << 94 continue; << 95 } << 96 << 97 /* << 98 * We can't use page_count wit << 99 * because another CPU can fre << 100 * This check already skips co << 101 * because their page->_refcou << 102 */ << 103 if (!page_ref_count(page)) { << 104 if (PageBuddy(page)) << 105 pfn += (1 << b << 106 continue; << 107 } << 108 << 109 /* << 110 * The HWPoisoned page may be << 111 * page_count() is not 0. << 112 */ << 113 if ((flags & MEMORY_OFFLINE) & << 114 continue; << 115 << 116 /* << 117 * We treat all PageOffline() << 118 * to give drivers a chance to << 119 * in MEM_GOING_OFFLINE in ord << 120 * can be offlined as there ar << 121 * For actually unmovable Page << 122 * not support this, we will f << 123 * move these pages that still << 124 * (false negatives in this fu << 125 */ << 126 if ((flags & MEMORY_OFFLINE) & << 127 continue; << 128 << 129 if (__PageMovable(page) || Pag << 130 continue; << 131 << 132 /* << 133 * If there are RECLAIMABLE pa << 134 * it. But now, memory offlin << 135 * shrink_node_slabs() and it << 136 */ << 137 return page; << 138 } << 139 return NULL; << 140 } << 141 << 142 /* << 143 * This function set pageblock migratetype to << 144 * present in [start_pfn, end_pfn). The pagebl << 145 * [start_pfn, end_pfn). << 146 */ << 147 static int set_migratetype_isolate(struct page << 148 unsigned long start_pf << 149 { 19 { 150 struct zone *zone = page_zone(page); 20 struct zone *zone = page_zone(page); 151 struct page *unmovable; 21 struct page *unmovable; 152 unsigned long flags; 22 unsigned long flags; 153 unsigned long check_unmovable_start, c << 154 << 155 if (PageUnaccepted(page)) << 156 accept_page(page); << 157 23 158 spin_lock_irqsave(&zone->lock, flags); 24 spin_lock_irqsave(&zone->lock, flags); 159 25 160 /* 26 /* 161 * We assume the caller intended to SE 27 * We assume the caller intended to SET migrate type to isolate. 162 * If it is already set, then someone 28 * If it is already set, then someone else must have raced and 163 * set it before us. 29 * set it before us. 164 */ 30 */ 165 if (is_migrate_isolate_page(page)) { 31 if (is_migrate_isolate_page(page)) { 166 spin_unlock_irqrestore(&zone-> 32 spin_unlock_irqrestore(&zone->lock, flags); 167 return -EBUSY; 33 return -EBUSY; 168 } 34 } 169 35 170 /* 36 /* 171 * FIXME: Now, memory hotplug doesn't 37 * FIXME: Now, memory hotplug doesn't call shrink_slab() by itself. 172 * We just check MOVABLE pages. 38 * We just check MOVABLE pages. 173 * << 174 * Pass the intersection of [start_pfn << 175 * to avoid redundant checks. << 176 */ 39 */ 177 check_unmovable_start = max(page_to_pf !! 40 unmovable = has_unmovable_pages(zone, page, migratetype, isol_flags); 178 check_unmovable_end = min(pageblock_en << 179 end_pfn); << 180 << 181 unmovable = has_unmovable_pages(check_ << 182 migratetype, isol_flag << 183 if (!unmovable) { 41 if (!unmovable) { 184 if (!move_freepages_block_isol !! 42 unsigned long nr_pages; 185 spin_unlock_irqrestore !! 43 int mt = get_pageblock_migratetype(page); 186 return -EBUSY; !! 44 187 } !! 45 set_pageblock_migratetype(page, MIGRATE_ISOLATE); 188 zone->nr_isolate_pageblock++; 46 zone->nr_isolate_pageblock++; >> 47 nr_pages = move_freepages_block(zone, page, MIGRATE_ISOLATE, >> 48 NULL); >> 49 >> 50 __mod_zone_freepage_state(zone, -nr_pages, mt); 189 spin_unlock_irqrestore(&zone-> 51 spin_unlock_irqrestore(&zone->lock, flags); 190 return 0; 52 return 0; 191 } 53 } 192 54 193 spin_unlock_irqrestore(&zone->lock, fl 55 spin_unlock_irqrestore(&zone->lock, flags); 194 if (isol_flags & REPORT_FAILURE) { 56 if (isol_flags & REPORT_FAILURE) { 195 /* 57 /* 196 * printk() with zone->lock he 58 * printk() with zone->lock held will likely trigger a 197 * lockdep splat, so defer it 59 * lockdep splat, so defer it here. 198 */ 60 */ 199 dump_page(unmovable, "unmovabl 61 dump_page(unmovable, "unmovable page"); 200 } 62 } 201 63 202 return -EBUSY; 64 return -EBUSY; 203 } 65 } 204 66 205 static void unset_migratetype_isolate(struct p !! 67 static void unset_migratetype_isolate(struct page *page, unsigned migratetype) 206 { 68 { 207 struct zone *zone; 69 struct zone *zone; 208 unsigned long flags; !! 70 unsigned long flags, nr_pages; 209 bool isolated_page = false; 71 bool isolated_page = false; 210 unsigned int order; 72 unsigned int order; >> 73 unsigned long pfn, buddy_pfn; 211 struct page *buddy; 74 struct page *buddy; 212 75 213 zone = page_zone(page); 76 zone = page_zone(page); 214 spin_lock_irqsave(&zone->lock, flags); 77 spin_lock_irqsave(&zone->lock, flags); 215 if (!is_migrate_isolate_page(page)) 78 if (!is_migrate_isolate_page(page)) 216 goto out; 79 goto out; 217 80 218 /* 81 /* 219 * Because freepage with more than pag 82 * Because freepage with more than pageblock_order on isolated 220 * pageblock is restricted to merge du 83 * pageblock is restricted to merge due to freepage counting problem, 221 * it is possible that there is free b 84 * it is possible that there is free buddy page. 222 * move_freepages_block() doesn't care 85 * move_freepages_block() doesn't care of merge so we need other 223 * approach in order to merge them. Is 86 * approach in order to merge them. Isolation and free will make 224 * these pages to be merged. 87 * these pages to be merged. 225 */ 88 */ 226 if (PageBuddy(page)) { 89 if (PageBuddy(page)) { 227 order = buddy_order(page); 90 order = buddy_order(page); 228 if (order >= pageblock_order & !! 91 if (order >= pageblock_order && order < MAX_ORDER - 1) { 229 buddy = find_buddy_pag !! 92 pfn = page_to_pfn(page); 230 !! 93 buddy_pfn = __find_buddy_pfn(pfn, order); 231 if (buddy && !is_migra !! 94 buddy = page + (buddy_pfn - pfn); 232 isolated_page !! 95 233 /* !! 96 if (pfn_valid_within(buddy_pfn) && 234 * Isolating a !! 97 !is_migrate_isolate_page(buddy)) { 235 * is expected !! 98 __isolate_free_page(page, order); 236 * apply here. !! 99 isolated_page = true; 237 */ << 238 VM_WARN_ON(!is << 239 } 100 } 240 } 101 } 241 } 102 } 242 103 243 /* 104 /* 244 * If we isolate freepage with more th 105 * If we isolate freepage with more than pageblock_order, there 245 * should be no freepage in the range, 106 * should be no freepage in the range, so we could avoid costly 246 * pageblock scanning for freepage mov 107 * pageblock scanning for freepage moving. 247 * 108 * 248 * We didn't actually touch any of the 109 * We didn't actually touch any of the isolated pages, so place them 249 * to the tail of the freelist. This i 110 * to the tail of the freelist. This is an optimization for memory 250 * onlining - just onlined memory won' 111 * onlining - just onlined memory won't immediately be considered for 251 * allocation. 112 * allocation. 252 */ 113 */ 253 if (!isolated_page) { 114 if (!isolated_page) { 254 /* !! 115 nr_pages = move_freepages_block(zone, page, migratetype, NULL); 255 * Isolating this block alread !! 116 __mod_zone_freepage_state(zone, nr_pages, migratetype); 256 * should not fail on zone bou << 257 */ << 258 WARN_ON_ONCE(!move_freepages_b << 259 } else { << 260 set_pageblock_migratetype(page << 261 __putback_isolated_page(page, << 262 } 117 } >> 118 set_pageblock_migratetype(page, migratetype); >> 119 if (isolated_page) >> 120 __putback_isolated_page(page, order, migratetype); 263 zone->nr_isolate_pageblock--; 121 zone->nr_isolate_pageblock--; 264 out: 122 out: 265 spin_unlock_irqrestore(&zone->lock, fl 123 spin_unlock_irqrestore(&zone->lock, flags); 266 } 124 } 267 125 268 static inline struct page * 126 static inline struct page * 269 __first_valid_page(unsigned long pfn, unsigned 127 __first_valid_page(unsigned long pfn, unsigned long nr_pages) 270 { 128 { 271 int i; 129 int i; 272 130 273 for (i = 0; i < nr_pages; i++) { 131 for (i = 0; i < nr_pages; i++) { 274 struct page *page; 132 struct page *page; 275 133 276 page = pfn_to_online_page(pfn 134 page = pfn_to_online_page(pfn + i); 277 if (!page) 135 if (!page) 278 continue; 136 continue; 279 return page; 137 return page; 280 } 138 } 281 return NULL; 139 return NULL; 282 } 140 } 283 141 284 /** 142 /** 285 * isolate_single_pageblock() -- tries to isol !! 143 * start_isolate_page_range() - make page-allocation-type of range of pages to 286 * within a free or in-use page. !! 144 * be MIGRATE_ISOLATE. 287 * @boundary_pfn: pageblock-alig !! 145 * @start_pfn: The lower PFN of the range to be isolated. 288 * @flags: isolation flag !! 146 * @end_pfn: The upper PFN of the range to be isolated. 289 * @gfp_flags: GFP flags used !! 147 * start_pfn/end_pfn must be aligned to pageblock_order. 290 * @isolate_before: isolate the pageblock << 291 * @skip_isolation: the flag to skip the p << 292 * isolate_single_pageblo << 293 * @migratetype: migrate type to set in << 294 * << 295 * Free and in-use pages can be as big as MAX_ << 296 * pageblock. When not all pageblocks within a << 297 * time, free page accounting can go wrong. Fo << 298 * MAX_PAGE_ORDER = pageblock_order + 1, a MAX << 299 * pagelbocks. << 300 * [ MAX_PAGE_ORDER ] << 301 * [ pageblock0 | pageblock1 ] << 302 * When either pageblock is isolated, if it is << 303 * split into separate migratetype lists, whic << 304 * in-use page and freed later, __free_one_pag << 305 * either. The function handles this by splitt << 306 * the in-use page then splitting the free pag << 307 */ << 308 static int isolate_single_pageblock(unsigned l << 309 gfp_t gfp_flags, bool << 310 int migratetype) << 311 { << 312 unsigned long start_pfn; << 313 unsigned long isolate_pageblock; << 314 unsigned long pfn; << 315 struct zone *zone; << 316 int ret; << 317 << 318 VM_BUG_ON(!pageblock_aligned(boundary_ << 319 << 320 if (isolate_before) << 321 isolate_pageblock = boundary_p << 322 else << 323 isolate_pageblock = boundary_p << 324 << 325 /* << 326 * scan at the beginning of MAX_ORDER_ << 327 * only isolating a subset of pagebloc << 328 * free or in-use page. Also make sure << 329 * are within the same zone. << 330 */ << 331 zone = page_zone(pfn_to_page(isolate_ << 332 start_pfn = max(ALIGN_DOWN(isolate_pa << 333 zone->zo << 334 << 335 if (skip_isolation) { << 336 int mt __maybe_unused = get_pa << 337 << 338 VM_BUG_ON(!is_migrate_isolate( << 339 } else { << 340 ret = set_migratetype_isolate( << 341 flags, isolate << 342 << 343 if (ret) << 344 return ret; << 345 } << 346 << 347 /* << 348 * Bail out early when the to-be-isola << 349 * a free or in-use page across bounda << 350 * << 351 * 1. isolate before boundary_pfn: the << 352 * 2. isolate after boundary_pfn: the << 353 * << 354 * This also ensures correctness. With << 355 * boundary_pfn and [start_pfn, bounda << 356 * __first_valid_page() will return un << 357 * below. << 358 */ << 359 if (isolate_before) { << 360 if (!pfn_to_online_page(bounda << 361 return 0; << 362 } else { << 363 if (!pfn_to_online_page(bounda << 364 return 0; << 365 } << 366 << 367 for (pfn = start_pfn; pfn < boundary_p << 368 struct page *page = __first_va << 369 << 370 VM_BUG_ON(!page); << 371 pfn = page_to_pfn(page); << 372 << 373 if (PageUnaccepted(page)) { << 374 pfn += MAX_ORDER_NR_PA << 375 continue; << 376 } << 377 << 378 if (PageBuddy(page)) { << 379 int order = buddy_orde << 380 << 381 /* move_freepages_bloc << 382 VM_WARN_ON_ONCE(pfn + << 383 << 384 pfn += 1UL << order; << 385 continue; << 386 } << 387 << 388 /* << 389 * If a compound page is strad << 390 * to migrate it out of the wa << 391 * << 392 * We don't have to worry abou << 393 * free page that straddles in << 394 * pages are freed as order-0 << 395 * (currently) do not exceed p << 396 * << 397 * The block of interest has a << 398 * MIGRATE_ISOLATE above, so w << 399 * will free its pages onto th << 400 */ << 401 if (PageCompound(page)) { << 402 struct page *head = co << 403 unsigned long head_pfn << 404 unsigned long nr_pages << 405 << 406 if (head_pfn + nr_page << 407 PageHuge(page)) { << 408 pfn = head_pfn << 409 continue; << 410 } << 411 << 412 /* << 413 * These pages are mov << 414 * not expected to exc << 415 * << 416 * Let us know when th << 417 * proper free and spl << 418 */ << 419 VM_WARN_ON_ONCE_PAGE(P << 420 VM_WARN_ON_ONCE_PAGE(_ << 421 << 422 goto failed; << 423 } << 424 << 425 pfn++; << 426 } << 427 return 0; << 428 failed: << 429 /* restore the original migratetype */ << 430 if (!skip_isolation) << 431 unset_migratetype_isolate(pfn_ << 432 return -EBUSY; << 433 } << 434 << 435 /** << 436 * start_isolate_page_range() - mark page rang << 437 * @start_pfn: The first PFN of the r << 438 * @end_pfn: The last PFN of the ra << 439 * @migratetype: Migrate type to set in 148 * @migratetype: Migrate type to set in error recovery. 440 * @flags: The following flags ar 149 * @flags: The following flags are allowed (they can be combined in 441 * a bit mask) 150 * a bit mask) 442 * MEMORY_OFFLINE - isola 151 * MEMORY_OFFLINE - isolate to offline (!allocate) memory 443 * e.g., 152 * e.g., skip over PageHWPoison() pages 444 * and P 153 * and PageOffline() pages. 445 * REPORT_FAILURE - repor 154 * REPORT_FAILURE - report details about the failure to 446 * isolate the range 155 * isolate the range 447 * @gfp_flags: GFP flags used for mig << 448 * range boundaries. << 449 * 156 * 450 * Making page-allocation-type to be MIGRATE_I 157 * Making page-allocation-type to be MIGRATE_ISOLATE means free pages in 451 * the range will never be allocated. Any free 158 * the range will never be allocated. Any free pages and pages freed in the 452 * future will not be allocated again. If spec 159 * future will not be allocated again. If specified range includes migrate types 453 * other than MOVABLE or CMA, this will fail w 160 * other than MOVABLE or CMA, this will fail with -EBUSY. For isolating all 454 * pages in the range finally, the caller have 161 * pages in the range finally, the caller have to free all pages in the range. 455 * test_page_isolated() can be used for test i 162 * test_page_isolated() can be used for test it. 456 * 163 * 457 * The function first tries to isolate the pag << 458 * of the range, since there might be pages ac << 459 * Afterwards, it isolates the rest of the ran << 460 * << 461 * There is no high level synchronization mech 164 * There is no high level synchronization mechanism that prevents two threads 462 * from trying to isolate overlapping ranges. 165 * from trying to isolate overlapping ranges. If this happens, one thread 463 * will notice pageblocks in the overlapping r 166 * will notice pageblocks in the overlapping range already set to isolate. 464 * This happens in set_migratetype_isolate, an 167 * This happens in set_migratetype_isolate, and set_migratetype_isolate 465 * returns an error. We then clean up by resto 168 * returns an error. We then clean up by restoring the migration type on 466 * pageblocks we may have modified and return 169 * pageblocks we may have modified and return -EBUSY to caller. This 467 * prevents two threads from simultaneously wo 170 * prevents two threads from simultaneously working on overlapping ranges. 468 * 171 * 469 * Please note that there is no strong synchro 172 * Please note that there is no strong synchronization with the page allocator 470 * either. Pages might be freed while their pa 173 * either. Pages might be freed while their page blocks are marked ISOLATED. 471 * A call to drain_all_pages() after isolation 174 * A call to drain_all_pages() after isolation can flush most of them. However 472 * in some cases pages might still end up on p 175 * in some cases pages might still end up on pcp lists and that would allow 473 * for their allocation even when they are in 176 * for their allocation even when they are in fact isolated already. Depending 474 * on how strong of a guarantee the caller nee 177 * on how strong of a guarantee the caller needs, zone_pcp_disable/enable() 475 * might be used to flush and disable pcplist 178 * might be used to flush and disable pcplist before isolation and enable after 476 * unisolation. 179 * unisolation. 477 * 180 * 478 * Return: 0 on success and -EBUSY if any part 181 * Return: 0 on success and -EBUSY if any part of range cannot be isolated. 479 */ 182 */ 480 int start_isolate_page_range(unsigned long sta 183 int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn, 481 int migratetype, !! 184 unsigned migratetype, int flags) 482 { 185 { 483 unsigned long pfn; 186 unsigned long pfn; >> 187 unsigned long undo_pfn; 484 struct page *page; 188 struct page *page; 485 /* isolation is done at page block gra !! 189 486 unsigned long isolate_start = pagebloc !! 190 BUG_ON(!IS_ALIGNED(start_pfn, pageblock_nr_pages)); 487 unsigned long isolate_end = pageblock_ !! 191 BUG_ON(!IS_ALIGNED(end_pfn, pageblock_nr_pages)); 488 int ret; !! 192 489 bool skip_isolation = false; !! 193 for (pfn = start_pfn; 490 !! 194 pfn < end_pfn; 491 /* isolate [isolate_start, isolate_sta << 492 ret = isolate_single_pageblock(isolate << 493 skip_isolation, migrat << 494 if (ret) << 495 return ret; << 496 << 497 if (isolate_start == isolate_end - pag << 498 skip_isolation = true; << 499 << 500 /* isolate [isolate_end - pageblock_nr << 501 ret = isolate_single_pageblock(isolate << 502 skip_isolation, migrat << 503 if (ret) { << 504 unset_migratetype_isolate(pfn_ << 505 return ret; << 506 } << 507 << 508 /* skip isolated pageblocks at the beg << 509 for (pfn = isolate_start + pageblock_n << 510 pfn < isolate_end - pageblock_nr_ << 511 pfn += pageblock_nr_pages) { 195 pfn += pageblock_nr_pages) { 512 page = __first_valid_page(pfn, 196 page = __first_valid_page(pfn, pageblock_nr_pages); 513 if (page && set_migratetype_is !! 197 if (page) { 514 start_ !! 198 if (set_migratetype_isolate(page, migratetype, flags)) { 515 undo_isolate_page_rang !! 199 undo_pfn = pfn; 516 unset_migratetype_isol !! 200 goto undo; 517 pfn_to_page(is !! 201 } 518 migratetype); << 519 return -EBUSY; << 520 } 202 } 521 } 203 } 522 return 0; 204 return 0; >> 205 undo: >> 206 for (pfn = start_pfn; >> 207 pfn < undo_pfn; >> 208 pfn += pageblock_nr_pages) { >> 209 struct page *page = pfn_to_online_page(pfn); >> 210 if (!page) >> 211 continue; >> 212 unset_migratetype_isolate(page, migratetype); >> 213 } >> 214 >> 215 return -EBUSY; 523 } 216 } 524 217 525 /** !! 218 /* 526 * undo_isolate_page_range - undo effects of s !! 219 * Make isolated pages available again. 527 * @start_pfn: The first PFN of the i << 528 * @end_pfn: The last PFN of the is << 529 * @migratetype: New migrate type to se << 530 * << 531 * This finds every MIGRATE_ISOLATE page block << 532 * and switches it to @migratetype. << 533 */ 220 */ 534 void undo_isolate_page_range(unsigned long sta 221 void undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn, 535 int migratetype) !! 222 unsigned migratetype) 536 { 223 { 537 unsigned long pfn; 224 unsigned long pfn; 538 struct page *page; 225 struct page *page; 539 unsigned long isolate_start = pagebloc << 540 unsigned long isolate_end = pageblock_ << 541 226 542 for (pfn = isolate_start; !! 227 BUG_ON(!IS_ALIGNED(start_pfn, pageblock_nr_pages)); 543 pfn < isolate_end; !! 228 BUG_ON(!IS_ALIGNED(end_pfn, pageblock_nr_pages)); >> 229 >> 230 for (pfn = start_pfn; >> 231 pfn < end_pfn; 544 pfn += pageblock_nr_pages) { 232 pfn += pageblock_nr_pages) { 545 page = __first_valid_page(pfn, 233 page = __first_valid_page(pfn, pageblock_nr_pages); 546 if (!page || !is_migrate_isola 234 if (!page || !is_migrate_isolate_page(page)) 547 continue; 235 continue; 548 unset_migratetype_isolate(page 236 unset_migratetype_isolate(page, migratetype); 549 } 237 } 550 } 238 } 551 /* 239 /* 552 * Test all pages in the range is free(means i 240 * Test all pages in the range is free(means isolated) or not. 553 * all pages in [start_pfn...end_pfn) must be 241 * all pages in [start_pfn...end_pfn) must be in the same zone. 554 * zone->lock must be held before call this. 242 * zone->lock must be held before call this. 555 * 243 * 556 * Returns the last tested pfn. 244 * Returns the last tested pfn. 557 */ 245 */ 558 static unsigned long 246 static unsigned long 559 __test_page_isolated_in_pageblock(unsigned lon 247 __test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn, 560 int flags) 248 int flags) 561 { 249 { 562 struct page *page; 250 struct page *page; 563 251 564 while (pfn < end_pfn) { 252 while (pfn < end_pfn) { >> 253 if (!pfn_valid_within(pfn)) { >> 254 pfn++; >> 255 continue; >> 256 } 565 page = pfn_to_page(pfn); 257 page = pfn_to_page(pfn); 566 if (PageBuddy(page)) 258 if (PageBuddy(page)) 567 /* 259 /* 568 * If the page is on a 260 * If the page is on a free list, it has to be on 569 * the correct MIGRATE 261 * the correct MIGRATE_ISOLATE freelist. There is no 570 * simple way to verif 262 * simple way to verify that as VM_BUG_ON(), though. 571 */ 263 */ 572 pfn += 1 << buddy_orde 264 pfn += 1 << buddy_order(page); 573 else if ((flags & MEMORY_OFFLI 265 else if ((flags & MEMORY_OFFLINE) && PageHWPoison(page)) 574 /* A HWPoisoned page c 266 /* A HWPoisoned page cannot be also PageBuddy */ 575 pfn++; 267 pfn++; 576 else if ((flags & MEMORY_OFFLI 268 else if ((flags & MEMORY_OFFLINE) && PageOffline(page) && 577 !page_count(page)) 269 !page_count(page)) 578 /* 270 /* 579 * The responsible dri 271 * The responsible driver agreed to skip PageOffline() 580 * pages when offlinin 272 * pages when offlining memory by dropping its 581 * reference in MEM_GO 273 * reference in MEM_GOING_OFFLINE. 582 */ 274 */ 583 pfn++; 275 pfn++; 584 else 276 else 585 break; 277 break; 586 } 278 } 587 279 588 return pfn; 280 return pfn; 589 } 281 } 590 282 591 /** !! 283 /* Caller should ensure that requested range is in a single zone */ 592 * test_pages_isolated - check if pageblocks i << 593 * @start_pfn: The first PFN of the i << 594 * @end_pfn: The first PFN *after* << 595 * @isol_flags: Testing mode flags << 596 * << 597 * This tests if all in the specified range ar << 598 * << 599 * If %MEMORY_OFFLINE is specified in @flags, << 600 * poisoned and offlined pages free as well. << 601 * << 602 * Caller must ensure the requested range does << 603 * << 604 * Returns 0 if true, -EBUSY if one or more pa << 605 */ << 606 int test_pages_isolated(unsigned long start_pf 284 int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn, 607 int isol_flags) 285 int isol_flags) 608 { 286 { 609 unsigned long pfn, flags; 287 unsigned long pfn, flags; 610 struct page *page; 288 struct page *page; 611 struct zone *zone; 289 struct zone *zone; 612 int ret; << 613 290 614 /* 291 /* 615 * Note: pageblock_nr_pages != MAX_PAG !! 292 * Note: pageblock_nr_pages != MAX_ORDER. Then, chunks of free pages 616 * pages are not aligned to pageblock_ !! 293 * are not aligned to pageblock_nr_pages. 617 * Then we just check migratetype firs 294 * Then we just check migratetype first. 618 */ 295 */ 619 for (pfn = start_pfn; pfn < end_pfn; p 296 for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) { 620 page = __first_valid_page(pfn, 297 page = __first_valid_page(pfn, pageblock_nr_pages); 621 if (page && !is_migrate_isolat 298 if (page && !is_migrate_isolate_page(page)) 622 break; 299 break; 623 } 300 } 624 page = __first_valid_page(start_pfn, e 301 page = __first_valid_page(start_pfn, end_pfn - start_pfn); 625 if ((pfn < end_pfn) || !page) { !! 302 if ((pfn < end_pfn) || !page) 626 ret = -EBUSY; !! 303 return -EBUSY; 627 goto out; << 628 } << 629 << 630 /* Check all pages are free or marked 304 /* Check all pages are free or marked as ISOLATED */ 631 zone = page_zone(page); 305 zone = page_zone(page); 632 spin_lock_irqsave(&zone->lock, flags); 306 spin_lock_irqsave(&zone->lock, flags); 633 pfn = __test_page_isolated_in_pagebloc 307 pfn = __test_page_isolated_in_pageblock(start_pfn, end_pfn, isol_flags); 634 spin_unlock_irqrestore(&zone->lock, fl 308 spin_unlock_irqrestore(&zone->lock, flags); 635 309 636 ret = pfn < end_pfn ? -EBUSY : 0; << 637 << 638 out: << 639 trace_test_pages_isolated(start_pfn, e 310 trace_test_pages_isolated(start_pfn, end_pfn, pfn); 640 311 641 return ret; !! 312 return pfn < end_pfn ? -EBUSY : 0; 642 } 313 } 643 314
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.