#ifndef _LINUXKPI_LINUX_GFP_H_
#define _LINUXKPI_LINUX_GFP_H_
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <linux/page.h>
#include <linux/topology.h>
#include <vm/vm_param.h>
#include <vm/vm_object.h>
#include <vm/vm_extern.h>
#include <vm/vm_kern.h>
#define __GFP_NOWARN 0
#define __GFP_HIGHMEM 0
#define __GFP_ZERO M_ZERO
#define __GFP_NOMEMALLOC 0
#define __GFP_RECLAIM 0
#define __GFP_RECLAIMABLE 0
#define __GFP_RETRY_MAYFAIL 0
#define __GFP_MOVABLE 0
#define __GFP_COMP 0
#define __GFP_KSWAPD_RECLAIM 0
#define __GFP_IO 0
#define __GFP_NO_KSWAPD 0
#define __GFP_KSWAPD_RECLAIM 0
#define __GFP_WAIT M_WAITOK
#define __GFP_DMA32 (1U << 24)
#define __GFP_NORETRY (1U << 25)
#define __GFP_BITS_SHIFT 26
#define __GFP_BITS_MASK ((1 << __GFP_BITS_SHIFT) - 1)
#define __GFP_NOFAIL M_WAITOK
#define GFP_NOWAIT M_NOWAIT
#define GFP_ATOMIC (M_NOWAIT | M_USE_RESERVE)
#define GFP_KERNEL M_WAITOK
#define GFP_USER M_WAITOK
#define GFP_HIGHUSER M_WAITOK
#define GFP_HIGHUSER_MOVABLE M_WAITOK
#define GFP_IOFS M_NOWAIT
#define GFP_NOIO M_NOWAIT
#define GFP_NOFS M_NOWAIT
#define GFP_DMA32 __GFP_DMA32
#define GFP_TEMPORARY M_NOWAIT
#define GFP_NATIVE_MASK (M_NOWAIT | M_WAITOK | M_USE_RESERVE | M_ZERO)
#define GFP_TRANSHUGE 0
#define GFP_TRANSHUGE_LIGHT 0
CTASSERT((__GFP_DMA32 & GFP_NATIVE_MASK) == 0);
CTASSERT((__GFP_BITS_MASK & GFP_NATIVE_MASK) == GFP_NATIVE_MASK);
struct page_frag_cache {
void *va;
int pagecnt_bias;
};
struct page *linux_alloc_pages(gfp_t flags, unsigned int order);
void linux_free_pages(struct page *page, unsigned int order);
void *linuxkpi_page_frag_alloc(struct page_frag_cache *, size_t, gfp_t);
void linuxkpi_page_frag_free(void *);
void linuxkpi__page_frag_cache_drain(struct page *, size_t);
static inline struct page *
alloc_page(gfp_t flags)
{
return (linux_alloc_pages(flags, 0));
}
static inline struct page *
alloc_pages(gfp_t flags, unsigned int order)
{
return (linux_alloc_pages(flags, order));
}
static inline struct page *
alloc_pages_node(int node_id, gfp_t flags, unsigned int order)
{
return (linux_alloc_pages(flags, order));
}
static inline void
__free_pages(struct page *page, unsigned int order)
{
linux_free_pages(page, order);
}
static inline void
__free_page(struct page *page)
{
linux_free_pages(page, 0);
}
static inline struct page *
dev_alloc_pages(unsigned int order)
{
return (linux_alloc_pages(GFP_ATOMIC, order));
}
struct folio *folio_alloc(gfp_t gfp, unsigned int order);
vm_offset_t linux_alloc_kmem(gfp_t flags, unsigned int order);
void linux_free_kmem(vm_offset_t, unsigned int order);
static inline vm_offset_t
get_zeroed_page(gfp_t flags)
{
return (linux_alloc_kmem(flags | __GFP_ZERO, 0));
}
static inline vm_offset_t
__get_free_page(gfp_t flags)
{
return (linux_alloc_kmem(flags, 0));
}
static inline vm_offset_t
__get_free_pages(gfp_t flags, unsigned int order)
{
return (linux_alloc_kmem(flags, order));
}
static inline void
free_pages(uintptr_t addr, unsigned int order)
{
if (addr == 0)
return;
linux_free_kmem(addr, order);
}
static inline void
free_page(uintptr_t addr)
{
if (addr == 0)
return;
linux_free_kmem(addr, 0);
}
static inline void *
page_frag_alloc(struct page_frag_cache *pfc, size_t fragsz, gfp_t gfp)
{
return (linuxkpi_page_frag_alloc(pfc, fragsz, gfp));
}
static inline void
page_frag_free(void *addr)
{
linuxkpi_page_frag_free(addr);
}
static inline void
__page_frag_cache_drain(struct page *page, size_t count)
{
linuxkpi__page_frag_cache_drain(page, count);
}
static inline bool
gfpflags_allow_blocking(const gfp_t gfp_flags)
{
return ((gfp_flags & (M_WAITOK | M_NOWAIT)) == M_WAITOK);
}
#define SetPageReserved(page) do { } while (0)
#define ClearPageReserved(page) do { } while (0)
#endif