gfp.h revision 293419
119304Speter/*- 219304Speter * Copyright (c) 2010 Isilon Systems, Inc. 319304Speter * Copyright (c) 2010 iX Systems, Inc. 419304Speter * Copyright (c) 2010 Panasas, Inc. 519304Speter * Copyright (c) 2013 Mellanox Technologies, Ltd. 619304Speter * All rights reserved. 719304Speter * 819304Speter * Redistribution and use in source and binary forms, with or without 919304Speter * modification, are permitted provided that the following conditions 1019304Speter * are met: 1119304Speter * 1. Redistributions of source code must retain the above copyright 1219304Speter * notice unmodified, this list of conditions, and the following 13254225Speter * disclaimer. 1419304Speter * 2. Redistributions in binary form must reproduce the above copyright 1519304Speter * notice, this list of conditions and the following disclaimer in the 1619304Speter * documentation and/or other materials provided with the distribution. 1719304Speter * 1819304Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1919304Speter * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2019304Speter * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2119304Speter * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2219304Speter * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2319304Speter * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2419304Speter * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2519304Speter * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2619304Speter * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2719304Speter * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2819304Speter * 2919304Speter * $FreeBSD: head/sys/compat/linuxkpi/common/include/linux/gfp.h 293419 2016-01-08 10:04:19Z hselasky $ 3019304Speter */ 3119304Speter#ifndef _LINUX_GFP_H_ 3219304Speter#define _LINUX_GFP_H_ 3319304Speter 3419304Speter#include <sys/cdefs.h> 3519304Speter#include <sys/types.h> 3619304Speter#include <sys/systm.h> 37254225Speter#include <sys/malloc.h> 3819304Speter 3919304Speter#include <linux/page.h> 4019304Speter 4119304Speter#include <vm/vm_param.h> 4219304Speter#include <vm/vm_object.h> 4319304Speter#include <vm/vm_extern.h> 4419304Speter#include <vm/vm_kern.h> 4519304Speter 4619304Speter#define __GFP_NOWARN 0 4719304Speter#define __GFP_HIGHMEM 0 4819304Speter#define __GFP_ZERO M_ZERO 4919304Speter 5019304Speter#define GFP_NOWAIT M_NOWAIT 5119304Speter#define GFP_ATOMIC (M_NOWAIT | M_USE_RESERVE) 5219304Speter#define GFP_KERNEL M_WAITOK 5319304Speter#define GFP_USER M_WAITOK 5419304Speter#define GFP_HIGHUSER M_WAITOK 5519304Speter#define GFP_HIGHUSER_MOVABLE M_WAITOK 5619304Speter#define GFP_IOFS M_NOWAIT 5719304Speter 5819304Speterstatic inline void * 5919304Speterpage_address(struct page *page) 60254225Speter{ 61254225Speter 62254225Speter if (page->object != kmem_object && page->object != kernel_object) 63254225Speter return (NULL); 64254225Speter return ((void *)(uintptr_t)(VM_MIN_KERNEL_ADDRESS + 6519304Speter IDX_TO_OFF(page->pindex))); 6619304Speter} 6719304Speter 6819304Speterstatic inline unsigned long 6919304Speterlinux_get_page(gfp_t mask) 7019304Speter{ 7119304Speter 7219304Speter return kmem_malloc(kmem_arena, PAGE_SIZE, mask); 7319304Speter} 7419304Speter 7519304Speter#define get_zeroed_page(mask) linux_get_page((mask) | M_ZERO) 7619304Speter#define alloc_page(mask) virt_to_page(linux_get_page((mask))) 7719304Speter#define __get_free_page(mask) linux_get_page((mask)) 7819304Speter 7919304Speterstatic inline void 8019304Speterfree_page(unsigned long page) 8119304Speter{ 8219304Speter 8319304Speter if (page == 0) 8419304Speter return; 85254225Speter kmem_free(kmem_arena, page, PAGE_SIZE); 8619304Speter} 8719304Speter 8819304Speterstatic inline void 8919304Speter__free_page(struct page *m) 9019304Speter{ 9119304Speter 9219304Speter if (m->object != kmem_object) 9319304Speter panic("__free_page: Freed page %p not allocated via wrappers.", 9419304Speter m); 95254225Speter kmem_free(kmem_arena, (vm_offset_t)page_address(m), PAGE_SIZE); 96254225Speter} 9719304Speter 9819304Speterstatic inline void 9919304Speter__free_pages(struct page *m, unsigned int order) 10019304Speter{ 10119304Speter size_t size; 10219304Speter 10319304Speter if (m == NULL) 10419304Speter return; 10519304Speter size = PAGE_SIZE << order; 10619304Speter kmem_free(kmem_arena, (vm_offset_t)page_address(m), size); 10719304Speter} 10819304Speter 10919304Speterstatic inline void free_pages(uintptr_t addr, unsigned int order) 11019304Speter{ 11119304Speter if (addr == 0) 11219304Speter return; 11319304Speter __free_pages(virt_to_page((void *)addr), order); 11419304Speter} 11519304Speter 116254225Speter/* 11719304Speter * Alloc pages allocates directly from the buddy allocator on linux so 11819304Speter * order specifies a power of two bucket of pages and the results 119254225Speter * are expected to be aligned on the size as well. 120254225Speter */ 12119304Speterstatic inline struct page * 12219304Speteralloc_pages(gfp_t gfp_mask, unsigned int order) 12319304Speter{ 12419304Speter unsigned long page; 12519304Speter size_t size; 12619304Speter 12719304Speter size = PAGE_SIZE << order; 12819304Speter page = kmem_alloc_contig(kmem_arena, size, gfp_mask, 0, -1, 12919304Speter size, 0, VM_MEMATTR_DEFAULT); 130 if (page == 0) 131 return (NULL); 132 return (virt_to_page(page)); 133} 134 135static inline uintptr_t __get_free_pages(gfp_t gfp_mask, unsigned int order) 136{ 137 struct page *page; 138 139 page = alloc_pages(gfp_mask, order); 140 if (page == NULL) 141 return (0); 142 return ((uintptr_t)page_address(page)); 143} 144 145#define alloc_pages_node(node, mask, order) alloc_pages(mask, order) 146 147#define kmalloc_node(chunk, mask, node) kmalloc(chunk, mask) 148 149#endif /* _LINUX_GFP_H_ */ 150