folio_expected_ref_count(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’… 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