内存管理-38-页标志-2-page_flags.h 展开-6.1
1. 展开文件
enum pageflags { PG_locked, PG_referenced, PG_uptodate, PG_dirty, PG_lru, PG_active, PG_workingset, PG_waiters, PG_error, PG_slab, PG_owner_priv_1, PG_arch_1, PG_reserved, PG_private, PG_private_2, PG_writeback, PG_head, PG_mappedtodisk, PG_reclaim, PG_swapbacked, PG_unevictable, PG_mlocked, PG_young, PG_idle, PG_arch_2, PG_skip_kasan_poison, PG_oem_reserved_1, PG_oem_reserved_2, PG_oem_reserved_3, PG_oem_reserved_4, __NR_PAGEFLAGS, PG_readahead = PG_reclaim, PG_anon_exclusive = PG_mappedtodisk, PG_checked = PG_owner_priv_1, PG_swapcache = PG_owner_priv_1, PG_fscache = PG_private_2, PG_pinned = PG_owner_priv_1, PG_savepinned = PG_dirty, PG_foreign = PG_owner_priv_1, PG_xen_remapped = PG_owner_priv_1, PG_slob_free = PG_private, PG_double_map = PG_workingset, PG_isolated = PG_reclaim, PG_reported = PG_uptodate, PG_vmemmap_self_hosted = PG_owner_priv_1, }; static inline const struct page *page_fixed_fake_head(const struct page *page) { return page; } static __always_inline int page_is_fake_head(struct page *page) { return page_fixed_fake_head(page) != page; } static inline unsigned long _compound_head(const struct page *page) { unsigned long head = READ_ONCE(page->compound_head); if (unlikely(head & 1)) return head - 1; return (unsigned long)page_fixed_fake_head(page); } static __always_inline int PageTail(struct page *page) { return READ_ONCE(page->compound_head) & 1 || page_is_fake_head(page); } static __always_inline int PageCompound(struct page *page) { return test_bit(PG_head, &page->flags) || READ_ONCE(page->compound_head) & 1; } static inline int PagePoisoned(const struct page *page) { return READ_ONCE(page->flags) == -1l; } static inline void page_init_poison(struct page *page, size_t size) { } static unsigned long *folio_flags(struct folio *folio, unsigned n) { struct page *page = &folio->page; VM_BUG_ON_PGFLAGS(PageTail(page), page); VM_BUG_ON_PGFLAGS(n > 0 && !test_bit(PG_head, &page->flags), page); return &page[n].flags; } /* 这里面忽略了 VM_BUG_ON_PGFLAGS() 相关的校验,不同的类型校验还不一样, 更准确的改的是 _compound_head(page)->flags,这里为了简便写成 page->flags */ static __always_inline bool folio_test_locked(struct folio *folio) { return test_bit(PG_locked, folio_flags(folio, 0)); } static __always_inline int PageLocked(struct page *page) { return test_bit(PG_locked, page->flags); } static __always_inline void __folio_set_locked(struct folio *folio) { __set_bit(PG_locked, folio_flags(folio, 0)); } static __always_inline void __SetPageLocked(struct page *page) { __set_bit(PG_locked, page->flags); } static __always_inline void __folio_clear_locked(struct folio *folio) { __clear_bit(PG_locked, folio_flags(folio, 0)); } static __always_inline void __ClearPageLocked(struct page *page) { __clear_bit(PG_locked, page->flags); } static __always_inline bool folio_test_waiters(struct folio *folio) { return test_bit(PG_waiters, folio_flags(folio, 0)); } static __always_inline int PageWaiters(struct page *page) { return test_bit(PG_waiters, page->flags); } static __always_inline void folio_set_waiters(struct folio *folio) { set_bit(PG_waiters, folio_flags(folio, 0)); } static __always_inline void SetPageWaiters(struct page *page) { set_bit(PG_waiters, page->flags); } static __always_inline void folio_clear_waiters(struct folio *folio) { clear_bit(PG_waiters, folio_flags(folio, 0)); } static __always_inline void ClearPageWaiters(struct page *page) { clear_bit(PG_waiters, page->flags); } static __always_inline bool folio_test_error(struct folio *folio) { return test_bit(PG_error, folio_flags(folio, 0)); } static __always_inline int PageError(struct page *page) { return test_bit(PG_error, pageflags); } static __always_inline void folio_set_error(struct folio *folio) { set_bit(PG_error, folio_flags(folio, 0)); } static __always_inline void SetPageError(struct page *page) { set_bit(PG_error, page->flags); } static __always_inline void folio_clear_error(struct folio *folio) { clear_bit(PG_error, folio_flags(folio, 0)); } static __always_inline void ClearPageError(struct page *page) { clear_bit(PG_error, page->flags); } static __always_inline bool folio_test_clear_error(struct folio *folio) { return test_and_clear_bit(PG_error, folio_flags(folio, 0)); } static __always_inline int TestClearPageError(struct page *page) { return test_and_clear_bit(PG_error, page->flags); } static __always_inline bool folio_test_referenced(struct folio *folio) { return test_bit(PG_referenced, folio_flags(folio, 0)); } static __always_inline int PageReferenced(struct page *page) { return test_bit(PG_referenced, page->flags); } static __always_inline void folio_set_referenced(struct folio *folio) { set_bit(PG_referenced, folio_flags(folio, 0)); } static __always_inline void SetPageReferenced(struct page *page) { set_bit(PG_referenced, page->flags); } static __always_inline void folio_clear_referenced(struct folio *folio) { clear_bit(PG_referenced, folio_flags(folio, 0)); } static __always_inline void ClearPageReferenced(struct page *page) { clear_bit(PG_referenced, page->flags); } static __always_inline bool folio_test_clear_referenced(struct folio *folio) { return test_and_clear_bit(PG_referenced, folio_flags(folio, 0)); static __always_inline int TestClearPageReferenced(struct page *page) { return test_and_clear_bit(PG_referenced, page->flags); } static __always_inline void __folio_set_referenced(struct folio *folio) { __set_bit(PG_referenced, folio_flags(folio, 0)); } static __always_inline void __SetPageReferenced(struct page *page) { __set_bit(PG_referenced, page->flags); } static __always_inline bool folio_test_dirty(struct folio *folio) { return test_bit(PG_dirty, folio_flags(folio, 0)); } static __always_inline int PageDirty(struct page *page) { return test_bit(PG_dirty, page->flags); } static __always_inline void folio_set_dirty(struct folio *folio) { set_bit(PG_dirty, folio_flags(folio, 0)); } static __always_inline void SetPageDirty(struct page *page) { set_bit(PG_dirty, page->flags); } static __always_inline void folio_clear_dirty(struct folio *folio) { clear_bit(PG_dirty, folio_flags(folio, 0)); } static __always_inline void ClearPageDirty(struct page *page) { clear_bit(PG_dirty, page->flags); } static __always_inline bool folio_test_set_dirty(struct folio *folio) { return test_and_set_bit(PG_dirty, folio_flags(folio, 0)); } static __always_inline int TestSetPageDirty(struct page *page) { return test_and_set_bit(PG_dirty, page->flags); } static __always_inline bool folio_test_clear_dirty(struct folio *folio) { return test_and_clear_bit(PG_dirty, folio_flags(folio, 0)); } static __always_inline int TestClearPageDirty(struct page *page) { return test_and_clear_bit(PG_dirty, page->flags); } static __always_inline void __folio_clear_dirty(struct folio *folio) { __clear_bit(PG_dirty, folio_flags(folio, 0)); } static __always_inline void __ClearPageDirty(struct page *page) { __clear_bit(PG_dirty, page->flags); } static __always_inline bool folio_test_lru(struct folio *folio) { return test_bit(PG_lru, folio_flags(folio, 0)); } static __always_inline int PageLRU(struct page *page) { return test_bit(PG_lru, page->flags); } static __always_inline void folio_set_lru(struct folio *folio) { set_bit(PG_lru, folio_flags(folio, 0)); } static __always_inline void SetPageLRU(struct page *page) { set_bit(PG_lru, page->flags); } static __always_inline void folio_clear_lru(struct folio *folio) { clear_bit(PG_lru, folio_flags(folio, 0)); } static __always_inline void ClearPageLRU(struct page *page) { clear_bit(PG_lru, page->flags); } static __always_inline void __folio_clear_lru(struct folio *folio) { __clear_bit(PG_lru, folio_flags(folio, 0)); } static __always_inline void __ClearPageLRU(struct page *page) { __clear_bit(PG_lru, page->flags); } static __always_inline bool folio_test_clear_lru(struct folio *folio) { return test_and_clear_bit(PG_lru, folio_flags(folio, 0)); } static __always_inline int TestClearPageLRU(struct page *page) { return test_and_clear_bit(PG_lru, page->flags); } static __always_inline bool folio_test_active(struct folio *folio) { return test_bit(PG_active, folio_flags(folio, 0)); } static __always_inline int PageActive(struct page *page) { return test_bit(PG_active, page->flags); } static __always_inline void folio_set_active(struct folio *folio) { set_bit(PG_active, folio_flags(folio, 0)); } static __always_inline void SetPageActive(struct page *page) { set_bit(PG_active, page->flags); } static __always_inline void folio_clear_active(struct folio *folio) { clear_bit(PG_active, folio_flags(folio, 0)); } static __always_inline void ClearPageActive(struct page *page) { clear_bit(PG_active, page->flags); } static __always_inline void __folio_clear_active(struct folio *folio) { __clear_bit(PG_active, folio_flags(folio, 0)); } static __always_inline void __ClearPageActive(struct page *page) { __clear_bit(PG_active, page->flags); } static __always_inline bool folio_test_clear_active(struct folio *folio) { return test_and_clear_bit(PG_active, folio_flags(folio, 0)); } static __always_inline int TestClearPageActive(struct page *page) { return test_and_clear_bit(PG_active, page->flags); } static __always_inline bool folio_test_workingset(struct folio *folio) { return test_bit(PG_workingset, folio_flags(folio, 0)); } static __always_inline int PageWorkingset(struct page *page) { return test_bit(PG_workingset, page->flags); } static __always_inline void folio_set_workingset(struct folio *folio) { set_bit(PG_workingset, folio_flags(folio, 0)); } static __always_inline void SetPageWorkingset(struct page *page) { set_bit(PG_workingset, page->flags); } static __always_inline void folio_clear_workingset(struct folio *folio) { clear_bit(PG_workingset, folio_flags(folio, 0)); } static __always_inline void ClearPageWorkingset(struct page *page) { clear_bit(PG_workingset, page->flags); } static __always_inline bool folio_test_clear_workingset(struct folio *folio) { return test_and_clear_bit(PG_workingset, folio_flags(folio, 0)); } static __always_inline int TestClearPageWorkingset(struct page *page) { return test_and_clear_bit(PG_workingset, page->flags); } static __always_inline bool folio_test_slab(struct folio *folio) { return test_bit(PG_slab, folio_flags(folio, 0)); } static __always_inline int PageSlab(struct page *page) { return test_bit(PG_slab, pageflags); } static __always_inline void __folio_set_slab(struct folio *folio) { __set_bit(PG_slab, folio_flags(folio, 0)); } static __always_inline void __SetPageSlab(struct page *page) { __set_bit(PG_slab, page->flags); } static __always_inline void __folio_clear_slab(struct folio *folio) { __clear_bit(PG_slab, folio_flags(folio, 0)); } static __always_inline void __ClearPageSlab(struct page *page) { __clear_bit(PG_slab, page->flags); } static __always_inline bool folio_test_slob_free(struct folio *folio) { return test_bit(PG_slob_free, folio_flags(folio, 0)); } static __always_inline int PageSlobFree(struct page *page) { return test_bit(PG_slob_free, pageflags); } static __always_inline void __folio_set_slob_free(struct folio *folio) { __set_bit(PG_slob_free, folio_flags(folio, 0)); } static __always_inline void __SetPageSlobFree(struct page *page) { __set_bit(PG_slob_free, page->flags); } static __always_inline void __folio_clear_slob_free(struct folio *folio) { __clear_bit(PG_slob_free, folio_flags(folio, 0)); } static __always_inline void __ClearPageSlobFree(struct page *page) { __clear_bit(PG_slob_free, page->flags); } static __always_inline bool folio_test_checked(struct folio *folio) { return test_bit(PG_checked, folio_flags(folio, 0)); } static __always_inline int PageChecked(struct page *page) { return test_bit(PG_checked, page->flags); } static __always_inline void folio_set_checked(struct folio *folio) { set_bit(PG_checked, folio_flags(folio, 0)); } static __always_inline void SetPageChecked(struct page *page) { set_bit(PG_checked, page->flags); } static __always_inline void folio_clear_checked(struct folio *folio) { clear_bit(PG_checked, folio_flags(folio, 0)); } static __always_inline void ClearPageChecked(struct page *page) { clear_bit(PG_checked, page->flags); } static __always_inline bool folio_test_pinned(struct folio *folio) { return test_bit(PG_pinned, folio_flags(folio, 0)); } static __always_inline int PagePinned(struct page *page) { return test_bit(PG_pinned, page->flags); } static __always_inline void folio_set_pinned(struct folio *folio) { set_bit(PG_pinned, folio_flags(folio, 0)); } static __always_inline void SetPagePinned(struct page *page) { set_bit(PG_pinned, page->flags); } static __always_inline void folio_clear_pinned(struct folio *folio) { clear_bit(PG_pinned, folio_flags(folio, 0)); } static __always_inline void ClearPagePinned(struct page *page) { clear_bit(PG_pinned, page->flags); } static __always_inline bool folio_test_set_pinned(struct folio *folio) { return test_and_set_bit(PG_pinned, folio_flags(folio, 0)); } static __always_inline int TestSetPagePinned(struct page *page) { return test_and_set_bit(PG_pinned, page->flags); } static __always_inline bool folio_test_clear_pinned(struct folio *folio) { return test_and_clear_bit(PG_pinned, folio_flags(folio, 0)); } static __always_inline int TestClearPagePinned(struct page *page) { return test_and_clear_bit(PG_pinned, page->flags); } static __always_inline bool folio_test_savepinned(struct folio *folio) { return test_bit(PG_savepinned, folio_flags(folio, 0)); } static __always_inline int PageSavePinned(struct page *page) { return test_bit(PG_savepinned, page->flags); } static __always_inline void folio_set_savepinned(struct folio *folio) { set_bit(PG_savepinned, folio_flags(folio, 0)); } static __always_inline void SetPageSavePinned(struct page *page) { set_bit(PG_savepinned, page->flags); } static __always_inline void folio_clear_savepinned(struct folio *folio) { clear_bit(PG_savepinned, folio_flags(folio, 0)); } static __always_inline void ClearPageSavePinned(struct page *page) { clear_bit(PG_savepinned, page->flags); }; static __always_inline bool folio_test_foreign(struct folio *folio) { return test_bit(PG_foreign, folio_flags(folio, 0)); } static __always_inline int PageForeign(struct page *page) { return test_bit(PG_foreign, page->flags); } static __always_inline void folio_set_foreign(struct folio *folio) { set_bit(PG_foreign, folio_flags(folio, 0)); } static __always_inline void SetPageForeign(struct page *page) { set_bit(PG_foreign, page->flags); } static __always_inline void folio_clear_foreign(struct folio *folio) { clear_bit(PG_foreign, folio_flags(folio, 0)); } static __always_inline void ClearPageForeign(struct page *page) { clear_bit(PG_foreign, page->flags); }; static __always_inline bool folio_test_xen_remapped(struct folio *folio) { return test_bit(PG_xen_remapped, folio_flags(folio, 0)); } static __always_inline int PageXenRemapped(struct page *page) { return test_bit(PG_xen_remapped, page->flags); } static __always_inline void folio_set_xen_remapped(struct folio *folio) { set_bit(PG_xen_remapped, folio_flags(folio, 0)); } static __always_inline void SetPageXenRemapped(struct page *page) { set_bit(PG_xen_remapped, page->flags); } static __always_inline void folio_clear_xen_remapped(struct folio *folio) { clear_bit(PG_xen_remapped, folio_flags(folio, 0)); } static __always_inline void ClearPageXenRemapped(struct page *page) { clear_bit(PG_xen_remapped, page->flags); } static __always_inline bool folio_test_clear_xen_remapped(struct folio *folio) { return test_and_clear_bit(PG_xen_remapped, folio_flags(folio, 0)); } static __always_inline int TestClearPageXenRemapped(struct page *page) { return test_and_clear_bit(PG_xen_remapped, page->flags); } static __always_inline bool folio_test_reserved(struct folio *folio) { return test_bit(PG_reserved, folio_flags(folio, 0)); } static __always_inline int PageReserved(struct page *page) { return test_bit(PG_reserved, page->flags); } static __always_inline void folio_set_reserved(struct folio *folio) { set_bit(PG_reserved, folio_flags(folio, 0)); } static __always_inline void SetPageReserved(struct page *page) { set_bit(PG_reserved, page->flags); } static __always_inline void folio_clear_reserved(struct folio *folio) { clear_bit(PG_reserved, folio_flags(folio, 0)); } static __always_inline void ClearPageReserved(struct page *page) { clear_bit(PG_reserved, page->flags); } static __always_inline void __folio_clear_reserved(struct folio *folio) { __clear_bit(PG_reserved, folio_flags(folio, 0)); } static __always_inline void __ClearPageReserved(struct page *page) { __clear_bit(PG_reserved, page->flags); } static __always_inline void __folio_set_reserved(struct folio *folio) { __set_bit(PG_reserved, folio_flags(folio, 0)); } static __always_inline void __SetPageReserved(struct page *page) { __set_bit(PG_reserved, page->flags); } static __always_inline bool folio_test_swapbacked(struct folio *folio) { return test_bit(PG_swapbacked, folio_flags(folio, 0)); } static __always_inline int PageSwapBacked(struct page *page) { return test_bit(PG_swapbacked, pageflags); } static __always_inline void folio_set_swapbacked(struct folio *folio) { set_bit(PG_swapbacked, folio_flags(folio, 0)); } static __always_inline void SetPageSwapBacked(struct page *page) { set_bit(PG_swapbacked, page->flags); } static __always_inline void folio_clear_swapbacked(struct folio *folio) { clear_bit(PG_swapbacked, folio_flags(folio, 0)); } static __always_inline void ClearPageSwapBacked(struct page *page) { clear_bit(PG_swapbacked, page->flags); } static __always_inline void __folio_clear_swapbacked(struct folio *folio) { __clear_bit(PG_swapbacked, folio_flags(folio, 0)); } static __always_inline void __ClearPageSwapBacked(struct page *page) { __clear_bit(PG_swapbacked, page->flags); } static __always_inline void __folio_set_swapbacked(struct folio *folio) { __set_bit(PG_swapbacked, folio_flags(folio, 0)); } static __always_inline void __SetPageSwapBacked(struct page *page) { __set_bit(PG_swapbacked, page->flags); } static __always_inline bool folio_test_private(struct folio *folio) { return test_bit(PG_private, folio_flags(folio, 0)); } static __always_inline int PagePrivate(struct page *page) { return test_bit(PG_private, page->flags); } static __always_inline void folio_set_private(struct folio *folio) { set_bit(PG_private, folio_flags(folio, 0)); } static __always_inline void SetPagePrivate(struct page *page) { set_bit(PG_private, page->flags); } static __always_inline void folio_clear_private(struct folio *folio) { clear_bit(PG_private, folio_flags(folio, 0)); } static __always_inline void ClearPagePrivate(struct page *page) { clear_bit(PG_private, page->flags); } static __always_inline bool folio_test_private_2(struct folio *folio) { return test_bit(PG_private_2, folio_flags(folio, 0)); } static __always_inline int PagePrivate2(struct page *page) { return test_bit(PG_private_2, page->flags); } static __always_inline void folio_set_private_2(struct folio *folio) { set_bit(PG_private_2, folio_flags(folio, 0)); } static __always_inline void SetPagePrivate2(struct page *page) { set_bit(PG_private_2, page->flags); } static __always_inline void folio_clear_private_2(struct folio *folio) { clear_bit(PG_private_2, folio_flags(folio, 0)); } static __always_inline void ClearPagePrivate2(struct page *page) { clear_bit(PG_private_2, page->flags); } static __always_inline bool folio_test_set_private_2(struct folio *folio) { return test_and_set_bit(PG_private_2, folio_flags(folio, 0)); } static __always_inline int TestSetPagePrivate2(struct page *page) { return test_and_set_bit(PG_private_2, page->flags); } static __always_inline bool folio_test_clear_private_2(struct folio *folio) { return test_and_clear_bit(PG_private_2, folio_flags(folio, 0)); } static __always_inline int TestClearPagePrivate2(struct page *page) { return test_and_clear_bit(PG_private_2, page->flags); } static __always_inline bool folio_test_owner_priv_1(struct folio *folio) { return test_bit(PG_owner_priv_1, folio_flags(folio, 0)); } static __always_inline int PageOwnerPriv1(struct page *page) { return test_bit(PG_owner_priv_1, page->flags); } static __always_inline void folio_set_owner_priv_1(struct folio *folio) { set_bit(PG_owner_priv_1, folio_flags(folio, 0)); } static __always_inline void SetPageOwnerPriv1(struct page *page) { set_bit(PG_owner_priv_1, page->flags); } static __always_inline void folio_clear_owner_priv_1(struct folio *folio) { clear_bit(PG_owner_priv_1, folio_flags(folio, 0)); } static __always_inline void ClearPageOwnerPriv1(struct page *page) { clear_bit(PG_owner_priv_1, page->flags); } static __always_inline bool folio_test_clear_owner_priv_1(struct folio *folio) { return test_and_clear_bit(PG_owner_priv_1, folio_flags(folio, 0)); } static __always_inline int TestClearPageOwnerPriv1(struct page *page) { return test_and_clear_bit(PG_owner_priv_1, page->flags); } static __always_inline bool folio_test_writeback(struct folio *folio) { return test_bit(PG_writeback, folio_flags(folio, 0)); } static __always_inline int PageWriteback(struct page *page) { return test_bit(PG_writeback, pageflags); } static __always_inline bool folio_test_set_writeback(struct folio *folio) { return test_and_set_bit(PG_writeback, folio_flags(folio, 0)); } static __always_inline int TestSetPageWriteback(struct page *page) { return test_and_set_bit(PG_writeback, page->flags); } static __always_inline bool folio_test_clear_writeback(struct folio *folio) { return test_and_clear_bit(PG_writeback, folio_flags(folio, 0)); } static __always_inline int TestClearPageWriteback(struct page *page) { return test_and_clear_bit(PG_writeback, page->flags); } static __always_inline bool folio_test_mappedtodisk(struct folio *folio) { return test_bit(PG_mappedtodisk, folio_flags(folio, 0)); } static __always_inline int PageMappedToDisk(struct page *page) { return test_bit(PG_mappedtodisk, pageflags); } static __always_inline void folio_set_mappedtodisk(struct folio *folio) { set_bit(PG_mappedtodisk, folio_flags(folio, 0)); } static __always_inline void SetPageMappedToDisk(struct page *page) { set_bit(PG_mappedtodisk, page->flags); } static __always_inline void folio_clear_mappedtodisk(struct folio *folio) { clear_bit(PG_mappedtodisk, folio_flags(folio, 0)); } static __always_inline void ClearPageMappedToDisk(struct page *page) { clear_bit(PG_mappedtodisk, page->flags); } static __always_inline bool folio_test_reclaim(struct folio *folio) { return test_bit(PG_reclaim, folio_flags(folio, 0)); } static __always_inline int PageReclaim(struct page *page) { return test_bit(PG_reclaim, pageflags); } static __always_inline void folio_set_reclaim(struct folio *folio) { set_bit(PG_reclaim, folio_flags(folio, 0)); } static __always_inline void SetPageReclaim(struct page *page) { set_bit(PG_reclaim, page->flags); } static __always_inline void folio_clear_reclaim(struct folio *folio) { clear_bit(PG_reclaim, folio_flags(folio, 0)); } static __always_inline void ClearPageReclaim(struct page *page) { clear_bit(PG_reclaim, page->flags); } static __always_inline bool folio_test_clear_reclaim(struct folio *folio) { return test_and_clear_bit(PG_reclaim, folio_flags(folio, 0)); } static __always_inline int TestClearPageReclaim(struct page *page) { return test_and_clear_bit(PG_reclaim, page->flags); } static __always_inline bool folio_test_readahead(struct folio *folio) { return test_bit(PG_readahead, folio_flags(folio, 0)); } static __always_inline int PageReadahead(struct page *page) { return test_bit(PG_readahead, page->flags); } static __always_inline void folio_set_readahead(struct folio *folio) { set_bit(PG_readahead, folio_flags(folio, 0)); } static __always_inline void SetPageReadahead(struct page *page) { set_bit(PG_readahead, page->flags); } static __always_inline void folio_clear_readahead(struct folio *folio) { clear_bit(PG_readahead, folio_flags(folio, 0)); } static __always_inline void ClearPageReadahead(struct page *page) { clear_bit(PG_readahead, page->flags); } static __always_inline bool folio_test_clear_readahead(struct folio *folio) { return test_and_clear_bit(PG_readahead, folio_flags(folio, 0)); } static __always_inline int TestClearPageReadahead(struct page *page) { return test_and_clear_bit(PG_readahead, page->flags); } static inline bool folio_test_highmem(const struct folio *folio) { return false; } static inline int PageHighMem(const struct page *page) { return 0; } static inline void folio_set_highmem(struct folio *folio) { } static inline void SetPageHighMem(struct page *page) { } static inline void folio_clear_highmem(struct folio *folio) { } static inline void ClearPageHighMem(struct page *page) { } static __always_inline bool folio_test_swapcache(struct folio *folio) { return folio_test_swapbacked(folio) && test_bit(PG_swapcache, folio_flags(folio, 0)); } static __always_inline bool PageSwapCache(struct page *page) { return folio_test_swapcache((_Generic((page), const struct page *: (const struct folio *)_compound_head(page), struct page *: (struct folio *)_compound_head(page)))); } static __always_inline void folio_set_swapcache(struct folio *folio) { set_bit(PG_swapcache, folio_flags(folio, 0)); } static __always_inline void SetPageSwapCache(struct page *page) { set_bit(PG_swapcache, page->flags); } static __always_inline void folio_clear_swapcache(struct folio *folio) { clear_bit(PG_swapcache, folio_flags(folio, 0)); } static __always_inline void ClearPageSwapCache(struct page *page) { clear_bit(PG_swapcache, page->flags); } static __always_inline bool folio_test_unevictable(struct folio *folio) { return test_bit(PG_unevictable, folio_flags(folio, 0)); } static __always_inline int PageUnevictable(struct page *page) { return test_bit(PG_unevictable, page->flags); } static __always_inline void folio_set_unevictable(struct folio *folio) { set_bit(PG_unevictable, folio_flags(folio, 0)); } static __always_inline void SetPageUnevictable(struct page *page) { set_bit(PG_unevictable, page->flags); } static __always_inline void folio_clear_unevictable(struct folio *folio) { clear_bit(PG_unevictable, folio_flags(folio, 0)); } static __always_inline void ClearPageUnevictable(struct page *page) { clear_bit(PG_unevictable, page->flags); } static __always_inline void __folio_clear_unevictable(struct folio *folio) { __clear_bit(PG_unevictable, folio_flags(folio, 0)); } static __always_inline void __ClearPageUnevictable(struct page *page) { __clear_bit(PG_unevictable, page->flags); } static __always_inline bool folio_test_clear_unevictable(struct folio *folio) { return test_and_clear_bit(PG_unevictable, folio_flags(folio, 0)); } static __always_inline int TestClearPageUnevictable(struct page *page) { return test_and_clear_bit(PG_unevictable, page->flags); } static __always_inline bool folio_test_mlocked(struct folio *folio) { return test_bit(PG_mlocked, folio_flags(folio, 0)); } static __always_inline int PageMlocked(struct page *page) { return test_bit(PG_mlocked, pageflags); } static __always_inline void folio_set_mlocked(struct folio *folio) { set_bit(PG_mlocked, folio_flags(folio, 0)); } static __always_inline void SetPageMlocked(struct page *page) { set_bit(PG_mlocked, page->flags); } static __always_inline void folio_clear_mlocked(struct folio *folio) { clear_bit(PG_mlocked, folio_flags(folio, 0)); } static __always_inline void ClearPageMlocked(struct page *page) { clear_bit(PG_mlocked, page->flags); } static __always_inline void __folio_clear_mlocked(struct folio *folio) { __clear_bit(PG_mlocked, folio_flags(folio, 0)); } static __always_inline void __ClearPageMlocked(struct page *page) { __clear_bit(PG_mlocked, page->flags); } static __always_inline bool folio_test_set_mlocked(struct folio *folio) { return test_and_set_bit(PG_mlocked, folio_flags(folio, 0)); } static __always_inline int TestSetPageMlocked(struct page *page) { return test_and_set_bit(PG_mlocked, page->flags); } static __always_inline bool folio_test_clear_mlocked(struct folio *folio) { return test_and_clear_bit(PG_mlocked, folio_flags(folio, 0)); } static __always_inline int TestClearPageMlocked(struct page *page) { return test_and_clear_bit(PG_mlocked, page->flags); } static inline bool folio_test_uncached(const struct folio *folio) { return false; } static inline int PageUncached(const struct page *page) { return 0; } static inline void folio_set_uncached(struct folio *folio) { } static inline void SetPageUncached(struct page *page) { } static inline void folio_clear_uncached(struct folio *folio) { } static inline void ClearPageUncached(struct page *page) { } static inline bool folio_test_hwpoison(const struct folio *folio) { return false; } static inline int PageHWPoison(const struct page *page) { return 0; } static inline void folio_set_hwpoison(struct folio *folio) { } static inline void SetPageHWPoison(struct page *page) { } static inline void folio_clear_hwpoison(struct folio *folio) { } static inline void ClearPageHWPoison(struct page *page) { } static __always_inline bool folio_test_young(struct folio *folio) { return test_bit(PG_young, folio_flags(folio, 0)); } static __always_inline int PageYoung(struct page *page) { return test_bit(PG_young, page->flags); } static __always_inline void folio_set_young(struct folio *folio) { set_bit(PG_young, folio_flags(folio, 0)); } static __always_inline void SetPageYoung(struct page *page) { set_bit(PG_young, page->flags); } static __always_inline bool folio_test_clear_young(struct folio *folio) { return test_and_clear_bit(PG_young, folio_flags(folio, 0)); } static __always_inline int TestClearPageYoung(struct page *page) { return test_and_clear_bit(PG_young, page->flags); } static __always_inline bool folio_test_idle(struct folio *folio) { return test_bit(PG_idle, folio_flags(folio, 0)); } static __always_inline int PageIdle(struct page *page) { return test_bit(PG_idle, page->flags); } static __always_inline void folio_set_idle(struct folio *folio) { set_bit(PG_idle, folio_flags(folio, 0)); } static __always_inline void SetPageIdle(struct page *page) { set_bit(PG_idle, page->flags); } static __always_inline void folio_clear_idle(struct folio *folio) { clear_bit(PG_idle, folio_flags(folio, 0)); } static __always_inline void ClearPageIdle(struct page *page) { clear_bit(PG_idle, page->flags); } static __always_inline bool folio_test_skip_kasan_poison(struct folio *folio) { return test_bit(PG_skip_kasan_poison, folio_flags(folio, 0)); } static __always_inline int PageSkipKASanPoison(struct page *page) { return test_bit(PG_skip_kasan_poison, page->flags); } static __always_inline void folio_set_skip_kasan_poison(struct folio *folio) { set_bit(PG_skip_kasan_poison, folio_flags(folio, 0)); } static __always_inline void SetPageSkipKASanPoison(struct page *page) { set_bit(PG_skip_kasan_poison, page->flags); } static __always_inline void folio_clear_skip_kasan_poison(struct folio *folio) { clear_bit(PG_skip_kasan_poison, folio_flags(folio, 0)); } static __always_inline void ClearPageSkipKASanPoison(struct page *page) { clear_bit(PG_skip_kasan_poison, page->flags); } static __always_inline bool folio_test_reported(struct folio *folio) { return test_bit(PG_reported, folio_flags(folio, 0)); } static __always_inline int PageReported(struct page *page) { return test_bit(PG_reported, page->flags); } static __always_inline void __folio_set_reported(struct folio *folio) { __set_bit(PG_reported, folio_flags(folio, 0)); } static __always_inline void __SetPageReported(struct page *page) { __set_bit(PG_reported, page->flags); } static __always_inline void __folio_clear_reported(struct folio *folio) { __clear_bit(PG_reported, folio_flags(folio, 0)); } static __always_inline void __ClearPageReported(struct page *page) { __clear_bit(PG_reported, page->flags); } static __always_inline bool folio_test_vmemmap_self_hosted(struct folio *folio) { return test_bit(PG_vmemmap_self_hosted, folio_flags(folio, 0)); } static __always_inline int PageVmemmapSelfHosted(struct page *page) { return test_bit(PG_vmemmap_self_hosted, page->flags); } static __always_inline void folio_set_vmemmap_self_hosted(struct folio *folio) { set_bit(PG_vmemmap_self_hosted, folio_flags(folio, 0)); } static __always_inline void SetPageVmemmapSelfHosted(struct page *page) { set_bit(PG_vmemmap_self_hosted, page->flags); } static __always_inline void folio_clear_vmemmap_self_hosted(struct folio *folio) { clear_bit(PG_vmemmap_self_hosted, folio_flags(folio, 0)); } static __always_inline void ClearPageVmemmapSelfHosted(struct page *page) { clear_bit(PG_vmemmap_self_hosted, page->flags); } static __always_inline bool folio_mapping_flags(struct folio *folio) { return ((unsigned long)folio->mapping & (0x1 | 0x2)) != 0; } static __always_inline int PageMappingFlags(struct page *page) { return ((unsigned long)page->mapping & (0x1 | 0x2)) != 0; } static __always_inline bool folio_test_anon(struct folio *folio) { return ((unsigned long)folio->mapping & 0x1) != 0; } static __always_inline bool PageAnon(struct page *page) { return folio_test_anon((_Generic((page), const struct page *: (const struct folio *)_compound_head(page), struct page *: (struct folio *)_compound_head(page)))); } static __always_inline bool __folio_test_movable(const struct folio *folio) { return ((unsigned long)folio->mapping & PAGE_MAPPING_FLAGS) == PAGE_MAPPING_MOVABLE; } static __always_inline int __PageMovable(struct page *page) { return ((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) == PAGE_MAPPING_MOVABLE; } static inline bool folio_test_ksm(const struct folio *folio) { return false; } static inline int PageKsm(const struct page *page) { return 0; } u64 stable_page_flags(struct page *page); static inline bool folio_test_uptodate(struct folio *folio) { bool ret = test_bit(PG_uptodate, folio_flags(folio, 0)); if (ret) smp_rmb(); return ret; } static inline int PageUptodate(struct page *page) { return folio_test_uptodate((_Generic((page), const struct page *: (const struct folio *)_compound_head(page), struct page *: (struct folio *)_compound_head(page)))); } static __always_inline void __folio_mark_uptodate(struct folio *folio) { smp_wmb(); __set_bit(PG_uptodate, folio_flags(folio, 0)); } static __always_inline void folio_mark_uptodate(struct folio *folio) { smp_wmb(); set_bit(PG_uptodate, folio_flags(folio, 0)); } static __always_inline void __SetPageUptodate(struct page *page) { __folio_mark_uptodate((struct folio *)page); } static __always_inline void SetPageUptodate(struct page *page) { folio_mark_uptodate((struct folio *)page); } static __always_inline void folio_clear_uptodate(struct folio *folio) { clear_bit(PG_uptodate, folio_flags(folio, 0)); } static __always_inline void ClearPageUptodate(struct page *page) { clear_bit(PG_uptodate, page->flags); } bool __folio_start_writeback(struct folio *folio, bool keep_write); bool set_page_writeback(struct page *page); static inline void set_page_writeback_keepwrite(struct page *page) { __folio_start_writeback((_Generic((page), const struct page *: (const struct folio *)_compound_head(page), struct page *: (struct folio *)_compound_head(page))), true); } static inline bool test_set_page_writeback(struct page *page) { return set_page_writeback(page); } static __always_inline bool folio_test_head(struct folio *folio) { return test_bit(PG_head, folio_flags(folio, 0)); } static __always_inline int PageHead(struct page *page) { ({ VM_BUG_ON_PGFLAGS(PagePoisoned(page), page); page; }); return test_bit(PG_head, &page->flags) && !page_is_fake_head(page); } static __always_inline void __folio_set_head(struct folio *folio) { __set_bit(PG_head, folio_flags(folio, 0)); } static __always_inline void __SetPageHead(struct page *page) { __set_bit(PG_head, page->flags); } static __always_inline void __folio_clear_head(struct folio *folio) { __clear_bit(PG_head, folio_flags(folio, 0)); } static __always_inline void __ClearPageHead(struct page *page) { __clear_bit(PG_head, page->flags); } static __always_inline void folio_clear_head(struct folio *folio) { clear_bit(PG_head, folio_flags(folio, 0)); } static __always_inline void ClearPageHead(struct page *page) { clear_bit(PG_head, page->flags); } static inline bool folio_test_large(struct folio *folio) { return folio_test_head(folio); } static __always_inline void set_compound_head(struct page *page, struct page *head) { WRITE_ONCE(page->compound_head, (unsigned long)head + 1); } static __always_inline void clear_compound_head(struct page *page) { WRITE_ONCE(page->compound_head, 0); } static inline void ClearPageCompound(struct page *page) { BUG_ON(!PageHead(page)); ClearPageHead(page); } static inline bool folio_test_hugetlb(const struct folio *folio) { return false; } static inline int PageHuge(const struct page *page) { return 0; } static inline bool folio_test_headhuge(const struct folio *folio) { return false; } static inline int PageHeadHuge(const struct page *page) { return 0; } static inline int PageTransHuge(struct page *page) { VM_BUG_ON_PAGE(PageTail(page), page); return PageHead(page); } static inline bool folio_test_transhuge(struct folio *folio) { return folio_test_head(folio); } static inline int PageTransCompound(struct page *page) { return PageCompound(page); } static inline int PageTransTail(struct page *page) { return PageTail(page); } static __always_inline bool folio_test_double_map(struct folio *folio) { return test_bit(PG_double_map, folio_flags(folio, 1)); } static __always_inline int PageDoubleMap(struct page *page) { return test_bit(PG_double_map, page->flags); } static __always_inline void folio_set_double_map(struct folio *folio) { set_bit(PG_double_map, folio_flags(folio, 1)); } static __always_inline void SetPageDoubleMap(struct page *page) { set_bit(PG_double_map, page->flags); } static __always_inline void folio_clear_double_map(struct folio *folio) { clear_bit(PG_double_map, folio_flags(folio, 1)); } static __always_inline void ClearPageDoubleMap(struct page *page) { clear_bit(PG_double_map, page->flags); } static __always_inline bool folio_test_set_double_map(struct folio *folio) { return test_and_set_bit(PG_double_map, folio_flags(folio, 1)); } static __always_inline int TestSetPageDoubleMap(struct page *page) { return test_and_set_bit(PG_double_map, page->flags); } static __always_inline bool folio_test_clear_double_map(struct folio *folio) { return test_and_clear_bit(PG_double_map, folio_flags(folio, 1)); } static __always_inline int TestClearPageDoubleMap(struct page *page) { return test_and_clear_bit(PG_double_map, page->flags); } static inline bool folio_test_has_hwpoisoned(const struct folio *folio) { return false; } static inline int PageHasHWPoisoned(const struct page *page) { return 0; } static inline void folio_set_has_hwpoisoned(struct folio *folio) { } static inline void SetPageHasHWPoisoned(struct page *page) { } static inline void folio_clear_has_hwpoisoned(struct folio *folio) { } static inline void ClearPageHasHWPoisoned(struct page *page) { } static inline bool folio_test_set_has_hwpoisoned(struct folio *folio) { return 0; } static inline int TestSetPageHasHWPoisoned(struct page *page) { return 0; } static inline bool folio_test_clear_has_hwpoisoned(struct folio *folio) { return 0; } static inline int TestClearPageHasHWPoisoned(struct page *page) { return 0; } static inline bool is_page_hwpoison(struct page *page) { if (PageHWPoison(page)) return true; return PageHuge(page) && PageHWPoison(((typeof(page))_compound_head(page))); } static inline int page_has_type(struct page *page) { return (int)page->page_type < -128; } static __always_inline int PageBuddy(struct page *page) { return ((page->page_type & (PAGE_TYPE_BASE | PG_buddy)) == PAGE_TYPE_BASE); } static __always_inline void __SetPageBuddy(struct page *page) { VM_BUG_ON_PAGE(!((page->page_type & (PAGE_TYPE_BASE | 0)) == PAGE_TYPE_BASE), page); page->page_type &= ~PG_buddy; } static __always_inline void __ClearPageBuddy(struct page *page) { VM_BUG_ON_PAGE(!PageBuddy(page), page); page->page_type |= PG_buddy; } static __always_inline int PageOffline(struct page *page) { return ((page->page_type & (PAGE_TYPE_BASE | PG_offline)) == PAGE_TYPE_BASE); } static __always_inline void __SetPageOffline(struct page *page) { VM_BUG_ON_PAGE(!((page->page_type & (PAGE_TYPE_BASE | 0)) == PAGE_TYPE_BASE), page); page->page_type &= ~PG_offline; } static __always_inline void __ClearPageOffline(struct page *page) { VM_BUG_ON_PAGE(!PageOffline(page), page); page->page_type |= PG_offline; } extern void page_offline_freeze(void); extern void page_offline_thaw(void); extern void page_offline_begin(void); extern void page_offline_end(void); static __always_inline int PageTable(struct page *page) { return ((page->page_type & (PAGE_TYPE_BASE | PG_table)) == PAGE_TYPE_BASE); } static __always_inline void __SetPageTable(struct page *page) { VM_BUG_ON_PAGE(!((page->page_type & (PAGE_TYPE_BASE | 0)) == PAGE_TYPE_BASE), page); page->page_type &= ~PG_table; } static __always_inline void __ClearPageTable(struct page *page) { VM_BUG_ON_PAGE(!PageTable(page), page); page->page_type |= PG_table; } static __always_inline int PageGuard(struct page *page) { return ((page->page_type & (PAGE_TYPE_BASE | PG_guard)) == PAGE_TYPE_BASE); } static __always_inline void __SetPageGuard(struct page *page) { VM_BUG_ON_PAGE(!((page->page_type & (PAGE_TYPE_BASE | 0)) == PAGE_TYPE_BASE), page); page->page_type &= ~PG_guard; } static __always_inline void __ClearPageGuard(struct page *page) { VM_BUG_ON_PAGE(!PageGuard(page), page); page->page_type |= PG_guard; } extern bool is_free_buddy_page(struct page *page); static __always_inline bool folio_test_isolated(struct folio *folio) { return test_bit(PG_isolated, folio_flags(folio, 0)); } static __always_inline int PageIsolated(struct page *page) { return test_bit(PG_isolated, page->flags); } static __always_inline void folio_set_isolated(struct folio *folio) { set_bit(PG_isolated, folio_flags(folio, 0)); } static __always_inline void SetPageIsolated(struct page *page) { set_bit(PG_isolated, page->flags); } static __always_inline void folio_clear_isolated(struct folio *folio) { clear_bit(PG_isolated, folio_flags(folio, 0)); } static __always_inline void ClearPageIsolated(struct page *page) { clear_bit(PG_isolated, page->flags); }; static __always_inline int PageAnonExclusive(struct page *page) { VM_BUG_ON_PGFLAGS(!PageAnon(page), page); VM_BUG_ON_PGFLAGS(PageHuge(page) && !PageHead(page), page); return test_bit(PG_anon_exclusive, page->flags); } static __always_inline void SetPageAnonExclusive(struct page *page) { VM_BUG_ON_PGFLAGS(!PageAnon(page) || PageKsm(page), page); VM_BUG_ON_PGFLAGS(PageHuge(page) && !PageHead(page), page); set_bit(PG_anon_exclusive, page->flags); } static __always_inline void ClearPageAnonExclusive(struct page *page) { VM_BUG_ON_PGFLAGS(!PageAnon(page) || PageKsm(page), page); VM_BUG_ON_PGFLAGS(PageHuge(page) && !PageHead(page), page); clear_bit(PG_anon_exclusive, page->flags); } static __always_inline void __ClearPageAnonExclusive(struct page *page) { VM_BUG_ON_PGFLAGS(!PageAnon(page), page); VM_BUG_ON_PGFLAGS(PageHuge(page) && !PageHead(page), page); __clear_bit(PG_anon_exclusive, page->flags); } static inline int page_has_private(struct page *page) { return !!(page->flags & (1UL << PG_private | 1UL << PG_private_2)); } static inline bool folio_has_private(struct folio *folio) { return page_has_private(&folio->page); }
2. 特殊实现
2.1 PageUptodate
/* * PageUptodate - 检查给定 page 的 PG_uptodate 标志是否置位 * * PG_uptodate 的语义:该页面的内容是"最新的"(与磁盘/来源一致、已被正确填充)。 * - 对 page cache:读操作完成后置位,表示页面数据有效可直接使用 * - 对新分配的匿名页:COW 复制完成后由 __SetPageUptodate 置位 * - 未置位时:页面内容可能是垃圾数据,不能返回给用户态 * * 参数: * page - 待检查的 struct page 指针(可能是 compound page 的 tail page) * * 返回值: * 非零 = uptodate(内容有效) * 0 = 不是 uptodate(内容无效/正在加载) */ static inline int PageUptodate(struct page *page) { /* * 拆解这条复杂表达式: * * 第一层:_compound_head(page) * 若 page 是 compound page 的 tail page,返回其 head page 指针; * 若 page 本身就是 head page 或普通页,返回自身。 * 原因:PG_uptodate 标志只存储在 head page 的 flags 中(PF_HEAD 策略),对 tail page * 查询时必须先回溯到 head page。 * * 第二层:_Generic(...) * C11 泛型选择表达式,根据 page 参数的 const 修饰情况,将 _compound_head 返回的 struct page* 转 * 换为对应的 struct folio*: * - page 是 const struct page* --> 转换为 const struct folio* * - page 是 struct page* --> 转换为 struct folio* * 目的:保持 const 正确性(const 输入不会产生非 const 的 folio 指针),同时消除编译器的 const 丢弃警告。 * * struct folio 实质上就是 struct page 的第一个成员(头页),二者地址相同,这个强制转换在内存布局上是安全的。 * * 第三层:folio_test_uptodate(folio) * 测试 folio(即 head page)的 PG_uptodate 标志位。 * 由 PAGEFLAG 宏体系生成,本质是:test_bit(PG_uptodate, &folio->page.flags) * * 整体等价于(伪代码): * head = compound_head(page); * return test_bit(PG_uptodate, &head->flags); */ return folio_test_uptodate( (_Generic((page), const struct page *: (const struct folio *)_compound_head(page), struct page *: (struct folio *)_compound_head(page) )) ); }
2.2 PageLocked
实际定位为:
static __always_inline int PageLocked(struct page *page) { return test_bit(PG_locked, &({ VM_BUG_ON_PGFLAGS(0 && PageTail(page), page); ({ VM_BUG_ON_PGFLAGS(PagePoisoned(((typeof(page))_compound_head(page))), ((typeof(page))_compound_head(page))); ((typeof(page))_compound_head(page)); }); })->flags); }
posted on 2026-08-06 21:02 Hello-World3 阅读(7) 评论(0) 收藏 举报
浙公网安备 33010602011771号