1219820Sjeff/*-
2219820Sjeff * Copyright (c) 2010 Isilon Systems, Inc.
3219820Sjeff * Copyright (c) 2010 iX Systems, Inc.
4219820Sjeff * Copyright (c) 2010 Panasas, Inc.
5328653Shselasky * Copyright (c) 2013-2017 Mellanox Technologies, Ltd.
6219820Sjeff * All rights reserved.
7219820Sjeff *
8219820Sjeff * Redistribution and use in source and binary forms, with or without
9219820Sjeff * modification, are permitted provided that the following conditions
10219820Sjeff * are met:
11219820Sjeff * 1. Redistributions of source code must retain the above copyright
12219820Sjeff *    notice unmodified, this list of conditions, and the following
13219820Sjeff *    disclaimer.
14219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright
15219820Sjeff *    notice, this list of conditions and the following disclaimer in the
16219820Sjeff *    documentation and/or other materials provided with the distribution.
17219820Sjeff *
18219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19219820Sjeff * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20219820Sjeff * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21219820Sjeff * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22219820Sjeff * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23219820Sjeff * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24219820Sjeff * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25219820Sjeff * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26219820Sjeff * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27219820Sjeff * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28289644Shselasky *
29289644Shselasky * $FreeBSD: stable/11/sys/compat/linuxkpi/common/include/linux/gfp.h 335410 2018-06-20 06:34:31Z hselasky $
30219820Sjeff */
31219820Sjeff#ifndef	_LINUX_GFP_H_
32219820Sjeff#define	_LINUX_GFP_H_
33219820Sjeff
34277396Shselasky#include <sys/cdefs.h>
35277396Shselasky#include <sys/types.h>
36219820Sjeff#include <sys/systm.h>
37219820Sjeff#include <sys/malloc.h>
38219820Sjeff
39219820Sjeff#include <linux/page.h>
40219820Sjeff
41239065Skib#include <vm/vm_param.h>
42219820Sjeff#include <vm/vm_object.h>
43219820Sjeff#include <vm/vm_extern.h>
44219820Sjeff#include <vm/vm_kern.h>
45219820Sjeff
46219820Sjeff#define	__GFP_NOWARN	0
47219820Sjeff#define	__GFP_HIGHMEM	0
48219820Sjeff#define	__GFP_ZERO	M_ZERO
49300492Shselasky#define	__GFP_NORETRY	0
50300492Shselasky#define	__GFP_RECLAIM   0
51300492Shselasky#define	__GFP_RECLAIMABLE   0
52335410Shselasky#define	__GFP_RETRY_MAYFAIL 0
53335410Shselasky#define	__GFP_MOVABLE	0
54335410Shselasky#define	__GFP_COMP	0
55219820Sjeff
56300492Shselasky#define	__GFP_IO	0
57300492Shselasky#define	__GFP_NO_KSWAPD	0
58300492Shselasky#define	__GFP_WAIT	M_WAITOK
59328653Shselasky#define	__GFP_DMA32	(1U << 24) /* LinuxKPI only */
60329969Shselasky#define	__GFP_BITS_SHIFT 25
61329969Shselasky#define	__GFP_BITS_MASK	((1 << __GFP_BITS_SHIFT) - 1)
62335410Shselasky#define	__GFP_NOFAIL	M_WAITOK
63300492Shselasky
64219820Sjeff#define	GFP_NOWAIT	M_NOWAIT
65219820Sjeff#define	GFP_ATOMIC	(M_NOWAIT | M_USE_RESERVE)
66219820Sjeff#define	GFP_KERNEL	M_WAITOK
67219820Sjeff#define	GFP_USER	M_WAITOK
68219820Sjeff#define	GFP_HIGHUSER	M_WAITOK
69219820Sjeff#define	GFP_HIGHUSER_MOVABLE	M_WAITOK
70219820Sjeff#define	GFP_IOFS	M_NOWAIT
71294839Shselasky#define	GFP_NOIO	M_NOWAIT
72328653Shselasky#define	GFP_DMA32	__GFP_DMA32
73310245Shselasky#define	GFP_TEMPORARY	M_NOWAIT
74328653Shselasky#define	GFP_NATIVE_MASK	(M_NOWAIT | M_WAITOK | M_USE_RESERVE | M_ZERO)
75335410Shselasky#define	GFP_TRANSHUGE	0
76219820Sjeff
77329969ShselaskyCTASSERT((__GFP_DMA32 & GFP_NATIVE_MASK) == 0);
78329969ShselaskyCTASSERT((__GFP_BITS_MASK & GFP_NATIVE_MASK) == GFP_NATIVE_MASK);
79329969Shselasky
80328653Shselasky/*
81328653Shselasky * Resolve a page into a virtual address:
82328653Shselasky *
83328653Shselasky * NOTE: This function only works for pages allocated by the kernel.
84328653Shselasky */
85328653Shselaskyextern void *linux_page_address(struct page *);
86328653Shselasky
87328653Shselasky#define	page_address(page) linux_page_address(page)
88328653Shselasky
89328653Shselasky/*
90328653Shselasky * Page management for unmapped pages:
91328653Shselasky */
92328653Shselaskyextern vm_page_t linux_alloc_pages(gfp_t flags, unsigned int order);
93328653Shselaskyextern void linux_free_pages(vm_page_t page, unsigned int order);
94328653Shselasky
95328653Shselaskystatic inline struct page *
96328653Shselaskyalloc_page(gfp_t flags)
97219820Sjeff{
98219820Sjeff
99328653Shselasky	return (linux_alloc_pages(flags, 0));
100219820Sjeff}
101219820Sjeff
102328653Shselaskystatic inline struct page *
103328653Shselaskyalloc_pages(gfp_t flags, unsigned int order)
104219820Sjeff{
105219820Sjeff
106328653Shselasky	return (linux_alloc_pages(flags, order));
107219820Sjeff}
108219820Sjeff
109328653Shselaskystatic inline struct page *
110328653Shselaskyalloc_pages_node(int node_id, gfp_t flags, unsigned int order)
111328653Shselasky{
112219820Sjeff
113328653Shselasky	return (linux_alloc_pages(flags, order));
114328653Shselasky}
115328653Shselasky
116219820Sjeffstatic inline void
117328653Shselasky__free_pages(struct page *page, unsigned int order)
118219820Sjeff{
119219820Sjeff
120328653Shselasky	linux_free_pages(page, order);
121219820Sjeff}
122219820Sjeff
123219820Sjeffstatic inline void
124328653Shselasky__free_page(struct page *page)
125219820Sjeff{
126219820Sjeff
127328653Shselasky	linux_free_pages(page, 0);
128219820Sjeff}
129219820Sjeff
130328653Shselasky/*
131328653Shselasky * Page management for mapped pages:
132328653Shselasky */
133328653Shselaskyextern vm_offset_t linux_alloc_kmem(gfp_t flags, unsigned int order);
134328653Shselaskyextern void linux_free_kmem(vm_offset_t, unsigned int order);
135328653Shselasky
136328653Shselaskystatic inline vm_offset_t
137328653Shselaskyget_zeroed_page(gfp_t flags)
138219820Sjeff{
139219820Sjeff
140328653Shselasky	return (linux_alloc_kmem(flags | __GFP_ZERO, 0));
141219820Sjeff}
142219820Sjeff
143328653Shselaskystatic inline vm_offset_t
144328653Shselasky__get_free_page(gfp_t flags)
145278681Shselasky{
146328653Shselasky
147328653Shselasky	return (linux_alloc_kmem(flags, 0));
148278681Shselasky}
149278681Shselasky
150328653Shselaskystatic inline vm_offset_t
151328653Shselasky__get_free_pages(gfp_t flags, unsigned int order)
152219820Sjeff{
153219820Sjeff
154328653Shselasky	return (linux_alloc_kmem(flags, order));
155219820Sjeff}
156219820Sjeff
157328653Shselaskystatic inline void
158328653Shselaskyfree_pages(uintptr_t addr, unsigned int order)
159278681Shselasky{
160328653Shselasky	if (addr == 0)
161328653Shselasky		return;
162278681Shselasky
163328653Shselasky	linux_free_kmem(addr, order);
164278681Shselasky}
165278681Shselasky
166328653Shselaskystatic inline void
167328653Shselaskyfree_page(uintptr_t addr)
168328653Shselasky{
169328653Shselasky	if (addr == 0)
170328653Shselasky		return;
171255932Salfred
172328653Shselasky	linux_free_kmem(addr, 0);
173328653Shselasky}
174255932Salfred
175328653Shselaskystatic inline bool
176328653Shselaskygfpflags_allow_blocking(const gfp_t gfp_flags)
177328653Shselasky{
178328653Shselasky	return ((gfp_flags & (M_WAITOK | M_NOWAIT)) == M_WAITOK);
179328653Shselasky}
180328653Shselasky
181300492Shselasky#define	SetPageReserved(page)	do { } while (0)	/* NOP */
182300492Shselasky#define	ClearPageReserved(page)	do { } while (0)	/* NOP */
183300492Shselasky
184219820Sjeff#endif	/* _LINUX_GFP_H_ */
185