18d59ecb2SHans Petter Selasky /*-
28d59ecb2SHans Petter Selasky * Copyright (c) 2010 Isilon Systems, Inc.
38d59ecb2SHans Petter Selasky * Copyright (c) 2010 iX Systems, Inc.
48d59ecb2SHans Petter Selasky * Copyright (c) 2010 Panasas, Inc.
51cdefd08SHans Petter Selasky * Copyright (c) 2013-2017 Mellanox Technologies, Ltd.
68d59ecb2SHans Petter Selasky * All rights reserved.
78d59ecb2SHans Petter Selasky *
88d59ecb2SHans Petter Selasky * Redistribution and use in source and binary forms, with or without
98d59ecb2SHans Petter Selasky * modification, are permitted provided that the following conditions
108d59ecb2SHans Petter Selasky * are met:
118d59ecb2SHans Petter Selasky * 1. Redistributions of source code must retain the above copyright
128d59ecb2SHans Petter Selasky * notice unmodified, this list of conditions, and the following
138d59ecb2SHans Petter Selasky * disclaimer.
148d59ecb2SHans Petter Selasky * 2. Redistributions in binary form must reproduce the above copyright
158d59ecb2SHans Petter Selasky * notice, this list of conditions and the following disclaimer in the
168d59ecb2SHans Petter Selasky * documentation and/or other materials provided with the distribution.
178d59ecb2SHans Petter Selasky *
188d59ecb2SHans Petter Selasky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
198d59ecb2SHans Petter Selasky * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
208d59ecb2SHans Petter Selasky * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
218d59ecb2SHans Petter Selasky * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
228d59ecb2SHans Petter Selasky * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
238d59ecb2SHans Petter Selasky * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
248d59ecb2SHans Petter Selasky * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
258d59ecb2SHans Petter Selasky * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
268d59ecb2SHans Petter Selasky * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
278d59ecb2SHans Petter Selasky * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
288d59ecb2SHans Petter Selasky */
29307f78f3SVladimir Kondratyev #ifndef _LINUXKPI_LINUX_GFP_H_
30307f78f3SVladimir Kondratyev #define _LINUXKPI_LINUX_GFP_H_
318d59ecb2SHans Petter Selasky
328d59ecb2SHans Petter Selasky #include <sys/types.h>
338d59ecb2SHans Petter Selasky #include <sys/systm.h>
348d59ecb2SHans Petter Selasky #include <sys/malloc.h>
358d59ecb2SHans Petter Selasky
368d59ecb2SHans Petter Selasky #include <linux/page.h>
378d59ecb2SHans Petter Selasky
388d59ecb2SHans Petter Selasky #include <vm/vm_param.h>
398d59ecb2SHans Petter Selasky #include <vm/vm_object.h>
408d59ecb2SHans Petter Selasky #include <vm/vm_extern.h>
418d59ecb2SHans Petter Selasky #include <vm/vm_kern.h>
428d59ecb2SHans Petter Selasky
438d59ecb2SHans Petter Selasky #define __GFP_NOWARN 0
448d59ecb2SHans Petter Selasky #define __GFP_HIGHMEM 0
458d59ecb2SHans Petter Selasky #define __GFP_ZERO M_ZERO
46299f2920SHans Petter Selasky #define __GFP_NORETRY 0
47bfe6bfd7SJean-Sébastien Pédron #define __GFP_NOMEMALLOC 0
48299f2920SHans Petter Selasky #define __GFP_RECLAIM 0
49299f2920SHans Petter Selasky #define __GFP_RECLAIMABLE 0
50f03ae7e8SHans Petter Selasky #define __GFP_RETRY_MAYFAIL 0
51f03ae7e8SHans Petter Selasky #define __GFP_MOVABLE 0
52f03ae7e8SHans Petter Selasky #define __GFP_COMP 0
533d40cdf0SBen Widawsky #define __GFP_KSWAPD_RECLAIM 0
54299f2920SHans Petter Selasky
55299f2920SHans Petter Selasky #define __GFP_IO 0
56299f2920SHans Petter Selasky #define __GFP_NO_KSWAPD 0
57937a05baSJustin Hibbits #define __GFP_KSWAPD_RECLAIM 0
58299f2920SHans Petter Selasky #define __GFP_WAIT M_WAITOK
59269d8c86SHans Petter Selasky #define __GFP_DMA32 (1U << 24) /* LinuxKPI only */
607c860473SHans Petter Selasky #define __GFP_BITS_SHIFT 25
617c860473SHans Petter Selasky #define __GFP_BITS_MASK ((1 << __GFP_BITS_SHIFT) - 1)
62f03ae7e8SHans Petter Selasky #define __GFP_NOFAIL M_WAITOK
638d59ecb2SHans Petter Selasky
648d59ecb2SHans Petter Selasky #define GFP_NOWAIT M_NOWAIT
658d59ecb2SHans Petter Selasky #define GFP_ATOMIC (M_NOWAIT | M_USE_RESERVE)
668a8e86b8SJean-Sébastien Pédron #define GFP_KERNEL M_WAITOK
678d59ecb2SHans Petter Selasky #define GFP_USER M_WAITOK
688d59ecb2SHans Petter Selasky #define GFP_HIGHUSER M_WAITOK
698d59ecb2SHans Petter Selasky #define GFP_HIGHUSER_MOVABLE M_WAITOK
708d59ecb2SHans Petter Selasky #define GFP_IOFS M_NOWAIT
71fe68f570SHans Petter Selasky #define GFP_NOIO M_NOWAIT
72c0c1c599SJean-Sébastien Pédron #define GFP_NOFS M_NOWAIT
73269d8c86SHans Petter Selasky #define GFP_DMA32 __GFP_DMA32
74be48ab92SHans Petter Selasky #define GFP_TEMPORARY M_NOWAIT
75269d8c86SHans Petter Selasky #define GFP_NATIVE_MASK (M_NOWAIT | M_WAITOK | M_USE_RESERVE | M_ZERO)
76f03ae7e8SHans Petter Selasky #define GFP_TRANSHUGE 0
773d40cdf0SBen Widawsky #define GFP_TRANSHUGE_LIGHT 0
788d59ecb2SHans Petter Selasky
797c860473SHans Petter Selasky CTASSERT((__GFP_DMA32 & GFP_NATIVE_MASK) == 0);
807c860473SHans Petter Selasky CTASSERT((__GFP_BITS_MASK & GFP_NATIVE_MASK) == GFP_NATIVE_MASK);
817c860473SHans Petter Selasky
8255038a63SBjoern A. Zeeb struct page_frag_cache {
8355038a63SBjoern A. Zeeb void *va;
8455038a63SBjoern A. Zeeb int pagecnt_bias;
8555038a63SBjoern A. Zeeb };
8655038a63SBjoern A. Zeeb
871cdefd08SHans Petter Selasky /*
881cdefd08SHans Petter Selasky * Page management for unmapped pages:
891cdefd08SHans Petter Selasky */
90*ecd1d1f1SBjoern A. Zeeb struct page *linux_alloc_pages(gfp_t flags, unsigned int order);
91*ecd1d1f1SBjoern A. Zeeb void linux_free_pages(struct page *page, unsigned int order);
9255038a63SBjoern A. Zeeb void *linuxkpi_page_frag_alloc(struct page_frag_cache *, size_t, gfp_t);
9355038a63SBjoern A. Zeeb void linuxkpi_page_frag_free(void *);
9455038a63SBjoern A. Zeeb void linuxkpi__page_frag_cache_drain(struct page *, size_t);
951cdefd08SHans Petter Selasky
961cdefd08SHans Petter Selasky static inline struct page *
alloc_page(gfp_t flags)971cdefd08SHans Petter Selasky alloc_page(gfp_t flags)
988d59ecb2SHans Petter Selasky {
998d59ecb2SHans Petter Selasky
1001cdefd08SHans Petter Selasky return (linux_alloc_pages(flags, 0));
1018d59ecb2SHans Petter Selasky }
1028d59ecb2SHans Petter Selasky
1031cdefd08SHans Petter Selasky static inline struct page *
alloc_pages(gfp_t flags,unsigned int order)1041cdefd08SHans Petter Selasky alloc_pages(gfp_t flags, unsigned int order)
1058d59ecb2SHans Petter Selasky {
1068d59ecb2SHans Petter Selasky
1071cdefd08SHans Petter Selasky return (linux_alloc_pages(flags, order));
1088d59ecb2SHans Petter Selasky }
1098d59ecb2SHans Petter Selasky
1101cdefd08SHans Petter Selasky static inline struct page *
alloc_pages_node(int node_id,gfp_t flags,unsigned int order)1111cdefd08SHans Petter Selasky alloc_pages_node(int node_id, gfp_t flags, unsigned int order)
1128d59ecb2SHans Petter Selasky {
1138d59ecb2SHans Petter Selasky
1141cdefd08SHans Petter Selasky return (linux_alloc_pages(flags, order));
1158d59ecb2SHans Petter Selasky }
1168d59ecb2SHans Petter Selasky
1178d59ecb2SHans Petter Selasky static inline void
__free_pages(struct page * page,unsigned int order)1181cdefd08SHans Petter Selasky __free_pages(struct page *page, unsigned int order)
1198d59ecb2SHans Petter Selasky {
1208d59ecb2SHans Petter Selasky
1211cdefd08SHans Petter Selasky linux_free_pages(page, order);
1228d59ecb2SHans Petter Selasky }
1238d59ecb2SHans Petter Selasky
1248d59ecb2SHans Petter Selasky static inline void
__free_page(struct page * page)1251cdefd08SHans Petter Selasky __free_page(struct page *page)
1268d59ecb2SHans Petter Selasky {
1278d59ecb2SHans Petter Selasky
1281cdefd08SHans Petter Selasky linux_free_pages(page, 0);
1298d59ecb2SHans Petter Selasky }
1308d59ecb2SHans Petter Selasky
131738c02baSBjoern A. Zeeb static inline struct page *
dev_alloc_pages(unsigned int order)132738c02baSBjoern A. Zeeb dev_alloc_pages(unsigned int order)
133738c02baSBjoern A. Zeeb {
134738c02baSBjoern A. Zeeb return (linux_alloc_pages(GFP_ATOMIC, order));
135738c02baSBjoern A. Zeeb }
136738c02baSBjoern A. Zeeb
1378d59ecb2SHans Petter Selasky /*
1381cdefd08SHans Petter Selasky * Page management for mapped pages:
1398d59ecb2SHans Petter Selasky */
140*ecd1d1f1SBjoern A. Zeeb vm_offset_t linux_alloc_kmem(gfp_t flags, unsigned int order);
141*ecd1d1f1SBjoern A. Zeeb void linux_free_kmem(vm_offset_t, unsigned int order);
1428d59ecb2SHans Petter Selasky
1431cdefd08SHans Petter Selasky static inline vm_offset_t
get_zeroed_page(gfp_t flags)1441cdefd08SHans Petter Selasky get_zeroed_page(gfp_t flags)
1451cdefd08SHans Petter Selasky {
1461cdefd08SHans Petter Selasky
1471cdefd08SHans Petter Selasky return (linux_alloc_kmem(flags | __GFP_ZERO, 0));
1488d59ecb2SHans Petter Selasky }
1498d59ecb2SHans Petter Selasky
1501cdefd08SHans Petter Selasky static inline vm_offset_t
__get_free_page(gfp_t flags)1511cdefd08SHans Petter Selasky __get_free_page(gfp_t flags)
1528d59ecb2SHans Petter Selasky {
1538d59ecb2SHans Petter Selasky
1541cdefd08SHans Petter Selasky return (linux_alloc_kmem(flags, 0));
1558d59ecb2SHans Petter Selasky }
1568d59ecb2SHans Petter Selasky
1571cdefd08SHans Petter Selasky static inline vm_offset_t
__get_free_pages(gfp_t flags,unsigned int order)1581cdefd08SHans Petter Selasky __get_free_pages(gfp_t flags, unsigned int order)
1591cdefd08SHans Petter Selasky {
1601cdefd08SHans Petter Selasky
1611cdefd08SHans Petter Selasky return (linux_alloc_kmem(flags, order));
1621cdefd08SHans Petter Selasky }
1631cdefd08SHans Petter Selasky
1641cdefd08SHans Petter Selasky static inline void
free_pages(uintptr_t addr,unsigned int order)1651cdefd08SHans Petter Selasky free_pages(uintptr_t addr, unsigned int order)
1661cdefd08SHans Petter Selasky {
1671cdefd08SHans Petter Selasky if (addr == 0)
1681cdefd08SHans Petter Selasky return;
1691cdefd08SHans Petter Selasky
1701cdefd08SHans Petter Selasky linux_free_kmem(addr, order);
1711cdefd08SHans Petter Selasky }
1721cdefd08SHans Petter Selasky
1731cdefd08SHans Petter Selasky static inline void
free_page(uintptr_t addr)1741cdefd08SHans Petter Selasky free_page(uintptr_t addr)
1751cdefd08SHans Petter Selasky {
1761cdefd08SHans Petter Selasky if (addr == 0)
1771cdefd08SHans Petter Selasky return;
1781cdefd08SHans Petter Selasky
1791cdefd08SHans Petter Selasky linux_free_kmem(addr, 0);
1801cdefd08SHans Petter Selasky }
1811cdefd08SHans Petter Selasky
18255038a63SBjoern A. Zeeb static inline void *
page_frag_alloc(struct page_frag_cache * pfc,size_t fragsz,gfp_t gfp)18355038a63SBjoern A. Zeeb page_frag_alloc(struct page_frag_cache *pfc, size_t fragsz, gfp_t gfp)
18455038a63SBjoern A. Zeeb {
18555038a63SBjoern A. Zeeb
18655038a63SBjoern A. Zeeb return (linuxkpi_page_frag_alloc(pfc, fragsz, gfp));
18755038a63SBjoern A. Zeeb }
18855038a63SBjoern A. Zeeb
18955038a63SBjoern A. Zeeb static inline void
page_frag_free(void * addr)19055038a63SBjoern A. Zeeb page_frag_free(void *addr)
19155038a63SBjoern A. Zeeb {
19255038a63SBjoern A. Zeeb
19355038a63SBjoern A. Zeeb linuxkpi_page_frag_free(addr);
19455038a63SBjoern A. Zeeb }
19555038a63SBjoern A. Zeeb
19655038a63SBjoern A. Zeeb static inline void
__page_frag_cache_drain(struct page * page,size_t count)19755038a63SBjoern A. Zeeb __page_frag_cache_drain(struct page *page, size_t count)
19855038a63SBjoern A. Zeeb {
19955038a63SBjoern A. Zeeb
20055038a63SBjoern A. Zeeb linuxkpi__page_frag_cache_drain(page, count);
20155038a63SBjoern A. Zeeb }
20255038a63SBjoern A. Zeeb
2031cdefd08SHans Petter Selasky static inline bool
gfpflags_allow_blocking(const gfp_t gfp_flags)2041cdefd08SHans Petter Selasky gfpflags_allow_blocking(const gfp_t gfp_flags)
2051cdefd08SHans Petter Selasky {
2061cdefd08SHans Petter Selasky return ((gfp_flags & (M_WAITOK | M_NOWAIT)) == M_WAITOK);
2071cdefd08SHans Petter Selasky }
2088d59ecb2SHans Petter Selasky
209299f2920SHans Petter Selasky #define SetPageReserved(page) do { } while (0) /* NOP */
210299f2920SHans Petter Selasky #define ClearPageReserved(page) do { } while (0) /* NOP */
211299f2920SHans Petter Selasky
212307f78f3SVladimir Kondratyev #endif /* _LINUXKPI_LINUX_GFP_H_ */
213