Skip to content

Folio

include/mem/folio.h View source View on GitHub
struct folio {
    struct page               *base_page;
    _Atomic enum folio_flags  flags;
    uint8_t                   order;
    refcount_t                refcount;
    mapcount_t                mapcount;
    void                      *mapping;
    pgoff_t                   index;
    struct list_head          lru;
};
enum folio_flags : uint32_t {
    FOLIO_FLAGS_NONE = 0,
    FOLIO_FLAG_ON_LRU = (1u << 0),
    FOLIO_FLAG_ANON = (1u << 1),
    FOLIO_FLAG_MAPPED = (1u << 2),
    FOLIO_FLAG_DIRTY = (1u << 3),
    FOLIO_FLAG_UPTODATE = (1u << 4),
    FOLIO_FLAG_LOCKED = (1u << 5),
};
enum folio_tag : uintptr_t {
    FOLIO_TAG_ADDRESS_SPACE = 0,
    FOLIO_TAG_ANON = 1,
};
uint32_t page_get_folio_index(struct page *p);
bool page_is_folio_head(struct page *p);
struct folio * folio_alloc_folio_struct();
void folio_free_folio_struct(struct folio *f);
struct folio * folio_alloc_internal(uint8_t order, enum alloc_flags flags, enum alloc_behavior bh);
void folio_free(struct folio *folio);
void folio_bind_pages(struct folio *f);
void folio_unbind_pages(struct folio *f);
void folio_zero(struct folio *f);
void folio_copy(const struct folio *src, struct folio *dst);
void folio_add_lru(struct folio *f);
void folio_del_lru(struct folio *f);
void page_set_folio(struct page *p, struct folio *f);
struct folio page_get_folio(const struct page *p);
void page_clear_folio(struct page *p);
bool folio_mapped(const struct folio *f);
unsigned long folio_nr_pages(const struct folio *f);
void folio_set_tag(struct folio *f, enum folio_tag t);
enum folio_tag folio_get_tag(const struct folio *f);
bool folio_test_flag(const struct folio *f, enum folio_flags m);
void folio_set_flag(struct folio *f, enum folio_flags m);
void folio_clear_flag(struct folio *f, enum folio_flags m);
bool folio_test_set_flag(struct folio *f, enum folio_flags m);
bool folio_get(struct folio *f);
void folio_put(struct folio *f);
struct page folio_get_page(const struct folio *f, size_t n);
pfn_t folio_get_pfn(const struct folio *f);
struct folio folio_from_page(const struct page *p);
struct folio folio_from_paddr(paddr_t pa);
paddr_t folio_get_paddr(const struct folio *f);
vaddr_t folio_get_vaddr(const struct folio *f);
paddr_t folio_get_paddr_for(const struct folio *f, size_t n);
vaddr_t folio_get_vaddr_for(const struct folio *f, size_t n);
void folio_mark_dirty(struct folio *f);
void folio_mark_uptodate(struct folio *f);
void folio_set_anon(struct folio *f, struct anon_vma *av, pgoff_t index);
bool folio_is_anon(const struct folio *f);
bool folio_is_file_vma_range(const struct folio *f);
struct anon_vma folio_get_anon_vma(const struct folio *f);
struct file_vma_range folio_get_file_vma_range(const struct folio *f);
bool folio_trylock(struct folio *f);
void folio_lock(struct folio *f);
void folio_unlock(struct folio *f);
void folio_mapcount_inc(struct folio *f);
bool folio_mapcount_dec(struct folio *f);
#define FOLIO_TAG_BITS 0x7
#define folio_for_each_page_struct(f, p) \
    for (size_t __i = 0; \
         __i < folio_nr_pages(f) && ((p) = folio_get_page((f), __i), true); \
         __i++)
#define folio_for_each_page_paddr(f, p) \
    for (size_t __i = 0; __i < folio_nr_pages(f) && \
                         ((p) = folio_get_paddr_for((f), __i), true); \
         __i++)
#define folio_for_each_page_vaddr(f, p) \
    for (size_t __i = 0; __i < folio_nr_pages(f) && \
                         ((p) = folio_get_vaddr_for((f), __i), true); \
         __i++)
#define folio_alloc_1(sz) \
    folio_alloc_internal((sz), ALLOC_FLAGS_DEFAULT, ALLOC_BEHAVIOR_DEFAULT)
#define folio_alloc_2(sz, fl) \
    folio_alloc_internal((sz), (fl), ALLOC_BEHAVIOR_DEFAULT)
#define folio_alloc_3(sz, fl, bh) folio_alloc_internal((sz), (fl), (bh))
#define folio_alloc(...) \
    _DISPATCH(folio_alloc, PP_NARG(__VA_ARGS__))(__VA_ARGS__)