#ifndef __MM_ZPDESC_H__
#define __MM_ZPDESC_H__
#include <linux/migrate.h>
#include <linux/pagemap.h>
struct zpdesc {
unsigned long flags;
struct list_head lru;
unsigned long movable_ops;
union {
struct zpdesc *next;
unsigned long handle;
};
struct zspage *zspage;
unsigned int first_obj_offset;
atomic_t _refcount;
};
#define ZPDESC_MATCH(pg, zp) \
static_assert(offsetof(struct page, pg) == offsetof(struct zpdesc, zp))
ZPDESC_MATCH(flags, flags);
ZPDESC_MATCH(lru, lru);
ZPDESC_MATCH(mapping, movable_ops);
ZPDESC_MATCH(__folio_index, next);
ZPDESC_MATCH(__folio_index, handle);
ZPDESC_MATCH(private, zspage);
ZPDESC_MATCH(page_type, first_obj_offset);
ZPDESC_MATCH(_refcount, _refcount);
#undef ZPDESC_MATCH
static_assert(sizeof(struct zpdesc) <= sizeof(struct page));
#define zpdesc_page(zp) (_Generic((zp), \
const struct zpdesc *: (const struct page *)(zp), \
struct zpdesc *: (struct page *)(zp)))
#define zpdesc_folio(zp) (_Generic((zp), \
const struct zpdesc *: (const struct folio *)(zp), \
struct zpdesc *: (struct folio *)(zp)))
#define page_zpdesc(p) (_Generic((p), \
const struct page *: (const struct zpdesc *)(p), \
struct page *: (struct zpdesc *)(p)))
static inline void zpdesc_lock(struct zpdesc *zpdesc)
{
folio_lock(zpdesc_folio(zpdesc));
}
static inline bool zpdesc_trylock(struct zpdesc *zpdesc)
{
return folio_trylock(zpdesc_folio(zpdesc));
}
static inline void zpdesc_unlock(struct zpdesc *zpdesc)
{
folio_unlock(zpdesc_folio(zpdesc));
}
static inline void zpdesc_wait_locked(struct zpdesc *zpdesc)
{
folio_wait_locked(zpdesc_folio(zpdesc));
}
static inline void zpdesc_get(struct zpdesc *zpdesc)
{
folio_get(zpdesc_folio(zpdesc));
}
static inline void zpdesc_put(struct zpdesc *zpdesc)
{
folio_put(zpdesc_folio(zpdesc));
}
static inline void *kmap_local_zpdesc(struct zpdesc *zpdesc)
{
return kmap_local_page(zpdesc_page(zpdesc));
}
static inline unsigned long zpdesc_pfn(struct zpdesc *zpdesc)
{
return page_to_pfn(zpdesc_page(zpdesc));
}
static inline struct zpdesc *pfn_zpdesc(unsigned long pfn)
{
return page_zpdesc(pfn_to_page(pfn));
}
static inline void __zpdesc_set_movable(struct zpdesc *zpdesc)
{
SetPageMovableOps(zpdesc_page(zpdesc));
}
static inline void __zpdesc_set_zsmalloc(struct zpdesc *zpdesc)
{
__SetPageZsmalloc(zpdesc_page(zpdesc));
}
static inline struct zone *zpdesc_zone(struct zpdesc *zpdesc)
{
return page_zone(zpdesc_page(zpdesc));
}
static inline bool zpdesc_is_locked(struct zpdesc *zpdesc)
{
return folio_test_locked(zpdesc_folio(zpdesc));
}
#endif