gfp.h revision 271127
1207753Smm/*-
2207753Smm * Copyright (c) 2010 Isilon Systems, Inc.
3207753Smm * Copyright (c) 2010 iX Systems, Inc.
4207753Smm * Copyright (c) 2010 Panasas, Inc.
5207753Smm * Copyright (c) 2013 Mellanox Technologies, Ltd.
6207753Smm * All rights reserved.
7207753Smm *
8207753Smm * Redistribution and use in source and binary forms, with or without
9207753Smm * modification, are permitted provided that the following conditions
10207753Smm * are met:
11207753Smm * 1. Redistributions of source code must retain the above copyright
12207753Smm *    notice unmodified, this list of conditions, and the following
13207753Smm *    disclaimer.
14207753Smm * 2. Redistributions in binary form must reproduce the above copyright
15207753Smm *    notice, this list of conditions and the following disclaimer in the
16207753Smm *    documentation and/or other materials provided with the distribution.
17207753Smm *
18207753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19207753Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20312518Sdelphij * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21207753Smm * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22207753Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23312518Sdelphij * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24207753Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25207753Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26207753Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27312518Sdelphij * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28207753Smm */
29207753Smm
30207753Smm#ifndef	_LINUX_GFP_H_
31207753Smm#define	_LINUX_GFP_H_
32207753Smm
33207753Smm#include <sys/systm.h>
34207753Smm#include <sys/malloc.h>
35207753Smm
36312518Sdelphij#include <linux/page.h>
37207753Smm
38207753Smm#include <vm/vm_param.h>
39207753Smm#include <vm/vm_object.h>
40207753Smm#include <vm/vm_extern.h>
41207753Smm#include <vm/vm_kern.h>
42207753Smm
43207753Smm#define	__GFP_NOWARN	0
44207753Smm#define	__GFP_HIGHMEM	0
45207753Smm#define	__GFP_ZERO	M_ZERO
46207753Smm
47207753Smm#define	GFP_NOWAIT	M_NOWAIT
48207753Smm#define	GFP_ATOMIC	(M_NOWAIT | M_USE_RESERVE)
49207753Smm#define	GFP_KERNEL	M_WAITOK
50207753Smm#define	GFP_USER	M_WAITOK
51207753Smm#define	GFP_HIGHUSER	M_WAITOK
52207753Smm#define	GFP_HIGHUSER_MOVABLE	M_WAITOK
53207753Smm#define	GFP_IOFS	M_NOWAIT
54207753Smm
55207753Smmstatic inline void *
56207753Smmpage_address(struct page *page)
57207753Smm{
58207753Smm
59207753Smm	if (page->object != kmem_object && page->object != kernel_object)
60207753Smm		return (NULL);
61207753Smm	return ((void *)(uintptr_t)(VM_MIN_KERNEL_ADDRESS +
62207753Smm	    IDX_TO_OFF(page->pindex)));
63207753Smm}
64207753Smm
65207753Smmstatic inline unsigned long
66207753Smm_get_page(gfp_t mask)
67207753Smm{
68207753Smm
69207753Smm	return kmem_malloc(kmem_arena, PAGE_SIZE, mask);
70207753Smm}
71207753Smm
72207753Smm#define	get_zeroed_page(mask)	_get_page((mask) | M_ZERO)
73207753Smm#define	alloc_page(mask)	virt_to_page(_get_page((mask)))
74207753Smm#define	__get_free_page(mask)	_get_page((mask))
75207753Smm
76207753Smmstatic inline void
77207753Smmfree_page(unsigned long page)
78207753Smm{
79207753Smm
80207753Smm	if (page == 0)
81207753Smm		return;
82207753Smm	kmem_free(kmem_arena, page, PAGE_SIZE);
83207753Smm}
84207753Smm
85207753Smmstatic inline void
86207753Smm__free_page(struct page *m)
87207753Smm{
88207753Smm
89207753Smm	if (m->object != kmem_object)
90207753Smm		panic("__free_page:  Freed page %p not allocated via wrappers.",
91207753Smm		    m);
92207753Smm	kmem_free(kmem_arena, (vm_offset_t)page_address(m), PAGE_SIZE);
93207753Smm}
94207753Smm
95207753Smmstatic inline void
96207753Smm__free_pages(struct page *m, unsigned int order)
97207753Smm{
98207753Smm	size_t size;
99207753Smm
100207753Smm	if (m == NULL)
101207753Smm		return;
102207753Smm	size = PAGE_SIZE << order;
103207753Smm	kmem_free(kmem_arena, (vm_offset_t)page_address(m), size);
104207753Smm}
105207753Smm
106207753Smm/*
107207753Smm * Alloc pages allocates directly from the buddy allocator on linux so
108207753Smm * order specifies a power of two bucket of pages and the results
109207753Smm * are expected to be aligned on the size as well.
110207753Smm */
111207753Smmstatic inline struct page *
112207753Smmalloc_pages(gfp_t gfp_mask, unsigned int order)
113207753Smm{
114207753Smm	unsigned long page;
115207753Smm	size_t size;
116207753Smm
117207753Smm	size = PAGE_SIZE << order;
118207753Smm	page = kmem_alloc_contig(kmem_arena, size, gfp_mask, 0, -1,
119207753Smm	    size, 0, VM_MEMATTR_DEFAULT);
120207753Smm	if (page == 0)
121207753Smm		return (NULL);
122207753Smm        return (virt_to_page(page));
123207753Smm}
124207753Smm
125207753Smm#define alloc_pages_node(node, mask, order)     alloc_pages(mask, order)
126207753Smm
127292588Sdelphij#define kmalloc_node(chunk, mask, node)         kmalloc(chunk, mask)
128207753Smm
129207753Smm#endif	/* _LINUX_GFP_H_ */
130207753Smm