folio_expected_ref_count(9)
π folio_expected_ref_count β like, the kernel API manual, but make it make sense
okay so bestie, welcome to folio_expected_ref_count(9), a real one from the Kernel API Manual. Buckle up, we're doing reference counting and honestly? it's giving detective energy πβ¨
πΈ NAME πΈ
folio_expected_ref_count β bestie, it calculates the expected folio refcount. that's the whole gig. no cap. π
β¨ SYNOPSIS β¨
int folio_expected_ref_count (const struct folio *folio );
π¦ ARGUMENTS π¦
folioβ the folio. yeah. that's it. that's the argument. she's literally just a folio π«Ά
π DESCRIPTION π
okay so the whole point of this function is: it calculates the expected folio refcount, and it's thorough about it β it takes references from the pagecache, the swapcache, PG_private and page table mappings into account. π
that makes it super useful in combination with folio_ref_count to detect unexpected references (e.g., GUP or other temporary references). it's giving "who invited you??" energy and honestly we love that for us π₯
ngl though, it does currently not consider references from the LRU cache. important caveat, bestie, write it down π. but β if the folio was isolated from the LRU (which is the case during migration or split), then the LRU cache does not apply. so like, no worries in that scenario β¨
now for the stability tea β:
- Calling this function on an unmapped folio β
!folio_mappedβ that is locked will return a stable result. slay, iconic, consistent π - Calling this function on a mapped folio will not result in a stable result, because nothing stops additional page table mappings from coming (e.g., fork) or going (e.g., munmap). it's a whole revolving door situation π
- Calling this function without the folio lock will also not result in a stable result: for example, the folio might get dropped from the swapcache concurrently. rude of it, honestly π
but here's the hopeful part π₯Ή β however, even when called without the folio lock or on a mapped folio, this function can be used to detect unexpected references early (for example, if it makes sense to even lock the folio and unmap it). so she's still useful, she's just doing her best under chaotic conditions π§
π the caller must add any reference (e.g., from folio_try_get) it might be holding itself to the result. don't forget. like, genuinely. this is the one that'll get you.
π RETURN π
the expected folio refcount. that's the whole vibe. π
β SEE ALSO β
Kernel file ./include/linux/mm.h β and then, bestie, we have a whole constellation of friends, no cap:
folio_page_idx(9), vma_flag_t(9), fault_flag_allow_retry_first(9), vma_kernel_pagesize(9), folio_order(9), folio_reset_order(9), folio_mapcount(9), folio_mapped(9), thp_order(9), thp_size(9), folio_get(9), folio_put(9), folio_put_refs(9), folios_put(9), vma_flags_is_cow_mapping(9), vma_is_cow_mapping(9), vma_desc_is_cow_mapping(9), folio_pfn(9), folio_mk_pte(9), folio_mk_pmd(9), folio_mk_pud(9), folio_maybe_dma_pinned(9), is_zero_page(9), is_zero_folio(9), folio_nr_pages(9), folio_next(9), folio_shift(9), folio_size(9), folio_maybe_mapped_shared(9), zap_vma(9), ptdesc_address(9), ptdesc_set_kernel(9), ptdesc_clear_kernel(9), ptdesc_test_kernel(9), pagetable_alloc(9), pagetable_free(9), vma_lookup(9), vma_start_pgoff(9), vma_end_pgoff(9), vma_last_pgoff(9), vma_start_anon_pgoff(9), vma_end_anon_pgoff(9), vma_last_anon_pgoff(9), mmap_action_remap(9), mmap_action_remap_full(9), mmap_action_ioremap(9), mmap_action_ioremap_full(9), mmap_action_simple_ioremap(9), mmap_action_map_kernel_pages(9), mmap_action_map_kernel_pages_full(9), range_is_subset(9), range_in_vma(9), range_in_vma_desc(9), clear_pages(9) πβ¨
and that's the page, bestie!! π«Ά this one shipped from source/version ./include/linux, dated October 2026 β so you know it's fresh π
periodt. go forth and count your refs responsibly π€π
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms