gfp.h revision 255932
1228753Smm/*-
2228753Smm * Copyright (c) 2010 Isilon Systems, Inc.
3228753Smm * Copyright (c) 2010 iX Systems, Inc.
4228753Smm * Copyright (c) 2010 Panasas, Inc.
5228753Smm * All rights reserved.
6228753Smm *
7228753Smm * Redistribution and use in source and binary forms, with or without
8228753Smm * modification, are permitted provided that the following conditions
9228753Smm * are met:
10228753Smm * 1. Redistributions of source code must retain the above copyright
11228753Smm *    notice unmodified, this list of conditions, and the following
12228753Smm *    disclaimer.
13228753Smm * 2. Redistributions in binary form must reproduce the above copyright
14228753Smm *    notice, this list of conditions and the following disclaimer in the
15228753Smm *    documentation and/or other materials provided with the distribution.
16228753Smm *
17228753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18228753Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19228753Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20228753Smm * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21228753Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22228753Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23228753Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24228753Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25228753Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26228753Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27248616Smm */
28238856Smm
29238856Smm#ifndef	_LINUX_GFP_H_
30238856Smm#define	_LINUX_GFP_H_
31232153Smm
32232153Smm#include <sys/systm.h>
33232153Smm#include <sys/malloc.h>
34228753Smm
35232153Smm#include <linux/page.h>
36232153Smm
37232153Smm#include <vm/vm_param.h>
38238856Smm#include <vm/vm_object.h>
39238856Smm#include <vm/vm_extern.h>
40238856Smm#include <vm/vm_kern.h>
41238856Smm
42238856Smm#define	__GFP_NOWARN	0
43238856Smm#define	__GFP_HIGHMEM	0
44238856Smm#define	__GFP_ZERO	M_ZERO
45238856Smm
46238856Smm#define	GFP_NOWAIT	M_NOWAIT
47238856Smm#define	GFP_ATOMIC	(M_NOWAIT | M_USE_RESERVE)
48232153Smm#define	GFP_KERNEL	M_WAITOK
49228753Smm#define	GFP_USER	M_WAITOK
50232153Smm#define	GFP_HIGHUSER	M_WAITOK
51232153Smm#define	GFP_HIGHUSER_MOVABLE	M_WAITOK
52232153Smm#define	GFP_IOFS	M_NOWAIT
53228753Smm
54228753Smmstatic inline void *
55228753Smmpage_address(struct page *page)
56228753Smm{
57228753Smm
58228753Smm	if (page->object != kmem_object && page->object != kernel_object)
59228753Smm		return (NULL);
60228753Smm	return ((void *)(uintptr_t)(VM_MIN_KERNEL_ADDRESS +
61228753Smm	    IDX_TO_OFF(page->pindex)));
62228753Smm}
63228763Smm
64228753Smmstatic inline unsigned long
65228753Smm_get_page(gfp_t mask)
66228753Smm{
67228753Smm
68228753Smm	return kmem_malloc(kmem_arena, PAGE_SIZE, mask);
69232153Smm}
70232153Smm
71228753Smm#define	get_zeroed_page(mask)	_get_page((mask) | M_ZERO)
72228753Smm#define	alloc_page(mask)	virt_to_page(_get_page((mask)))
73228753Smm#define	__get_free_page(mask)	_get_page((mask))
74228753Smm
75228753Smmstatic inline void
76228753Smmfree_page(unsigned long page)
77228753Smm{
78228753Smm
79228753Smm	if (page == 0)
80228753Smm		return;
81228753Smm	kmem_free(kmem_arena, page, PAGE_SIZE);
82228753Smm}
83228753Smm
84228753Smmstatic inline void
85228753Smm__free_page(struct page *m)
86228753Smm{
87228753Smm
88228753Smm	if (m->object != kmem_object)
89228753Smm		panic("__free_page:  Freed page %p not allocated via wrappers.",
90228753Smm		    m);
91228753Smm	kmem_free(kmem_arena, (vm_offset_t)page_address(m), PAGE_SIZE);
92228753Smm}
93248616Smm
94228753Smmstatic inline void
95228753Smm__free_pages(void *p, unsigned int order)
96228753Smm{
97228753Smm	size_t size;
98228753Smm
99228753Smm	if (p == 0)
100228753Smm		return;
101228753Smm	size = PAGE_SIZE << order;
102228753Smm	kmem_free(kmem_arena, (vm_offset_t)p, size);
103228753Smm}
104228753Smm
105228753Smm/*
106232153Smm * Alloc pages allocates directly from the buddy allocator on linux so
107228753Smm * order specifies a power of two bucket of pages and the results
108228753Smm * are expected to be aligned on the size as well.
109228753Smm */
110228753Smmstatic inline struct page *
111228753Smmalloc_pages(gfp_t gfp_mask, unsigned int order)
112228753Smm{
113228753Smm	unsigned long page;
114228753Smm	size_t size;
115228753Smm
116228753Smm	size = PAGE_SIZE << order;
117228753Smm	page = kmem_alloc_contig(kmem_arena, size, gfp_mask, 0, -1,
118228753Smm	    size, 0, VM_MEMATTR_DEFAULT);
119228753Smm	if (page == 0)
120228753Smm		return (NULL);
121228753Smm        return (virt_to_page(page));
122228753Smm}
123228753Smm
124228753Smm#define alloc_pages_node(node, mask, order)     alloc_pages(mask, order)
125228753Smm
126228753Smm#define kmalloc_node(chunk, mask, node)         kmalloc(chunk, mask)
127228753Smm
128228753Smm#endif	/* _LINUX_GFP_H_ */
129228753Smm