mm/page_isolation.c
Source file repositories/reference/linux-study-clean/mm/page_isolation.c
File Facts
- System
- Linux kernel
- Corpus path
mm/page_isolation.c- Extension
.c- Size
- 19951 bytes
- Lines
- 644
- Domain
- Core OS
- Bucket
- Memory Management
- Inferred role
- Core OS: implementation source
- Status
- source implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/mm.hlinux/page-isolation.hlinux/pageblock-flags.hlinux/memory.hlinux/hugetlb.hlinux/page_owner.hlinux/migrate.hinternal.htrace/events/page_isolation.h
Detected Declarations
function page_is_unmovablefunction pagefunction set_migratetype_isolatefunction scoped_guardfunction unset_migratetype_isolatefunction move_freepages_blockfunction __first_valid_pagefunction isolate_single_pageblockfunction __first_valid_pagefunction start_isolate_page_rangefunction undo_isolate_page_rangefunction freefunction test_pages_isolated
Annotated Snippet
if (folio_test_hugetlb(folio)) {
struct hstate *h;
if (!IS_ENABLED(CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION))
return true;
/*
* The huge page may be freed so can not
* use folio_hstate() directly.
*/
h = size_to_hstate(folio_size(folio));
if (h && !hugepage_migration_supported(h))
return true;
} else if (!folio_test_lru(folio)) {
return true;
}
*step = folio_nr_pages(folio) - folio_page_idx(folio, page);
return false;
}
/*
* We can't use page_count without pin a page
* because another CPU can free compound page.
* This check already skips compound tails of THP
* because their page->_refcount is zero at all time.
*/
if (!page_ref_count(page)) {
if (PageBuddy(page))
*step = (1 << buddy_order(page));
return false;
}
/*
* The HWPoisoned page may be not in buddy system, and
* page_count() is not 0.
*/
if ((mode == PB_ISOLATE_MODE_MEM_OFFLINE) && PageHWPoison(page))
return false;
/*
* We treat all PageOffline() pages as movable when offlining
* to give drivers a chance to decrement their reference count
* in MEM_GOING_OFFLINE in order to indicate that these pages
* can be offlined as there are no direct references anymore.
* For actually unmovable PageOffline() where the driver does
* not support this, we will fail later when trying to actually
* move these pages that still have a reference count > 0.
* (false negatives in this function only)
*/
if ((mode == PB_ISOLATE_MODE_MEM_OFFLINE) && PageOffline(page))
return false;
if (PageLRU(page) || page_has_movable_ops(page))
return false;
/*
* If there are RECLAIMABLE pages, we need to check
* it. But now, memory offline itself doesn't call
* shrink_node_slabs() and it still to be fixed.
*/
return true;
}
/*
* This function checks whether the range [start_pfn, end_pfn) includes
* unmovable pages or not. The range must fall into a single pageblock and
* consequently belong to a single zone.
*
* PageLRU check without isolation or lru_lock could race so that
* MIGRATE_MOVABLE block might include unmovable pages. Similarly, pages
* with movable_ops can only be identified some time after they were
* allocated. So you can't expect this function should be exact.
*
* Returns a page without holding a reference. If the caller wants to
* dereference that page (e.g., dumping), it has to make sure that it
* cannot get removed (e.g., via memory unplug) concurrently.
*
*/
static struct page *has_unmovable_pages(unsigned long start_pfn, unsigned long end_pfn,
enum pb_isolate_mode mode)
{
struct page *page = pfn_to_page(start_pfn);
struct zone *zone = page_zone(page);
VM_BUG_ON(pageblock_start_pfn(start_pfn) !=
pageblock_start_pfn(end_pfn - 1));
if (is_migrate_cma_page(page)) {
Annotation
- Immediate include surface: `linux/mm.h`, `linux/page-isolation.h`, `linux/pageblock-flags.h`, `linux/memory.h`, `linux/hugetlb.h`, `linux/page_owner.h`, `linux/migrate.h`, `internal.h`.
- Detected declarations: `function page_is_unmovable`, `function page`, `function set_migratetype_isolate`, `function scoped_guard`, `function unset_migratetype_isolate`, `function move_freepages_block`, `function __first_valid_page`, `function isolate_single_pageblock`, `function __first_valid_page`, `function start_isolate_page_range`.
- Atlas domain: Core OS / Memory Management.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.