Date: Sat, 17 Jul 2010 01:39:44 +0000 (UTC) From: Jeff Roberson <jeff@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r210182 - projects/ofed/head/sys/ofed/include/linux Message-ID: <201007170139.o6H1dip8082062@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jeff Date: Sat Jul 17 01:39:44 2010 New Revision: 210182 URL: http://svn.freebsd.org/changeset/base/210182 Log: - Linux requires a virtual address for 'lowmem' pages which counts everything on 64bit architectures. To support this we use kmem_malloc and stash the virtual address in the object pointer field of the page. This is similar to the technique used in UMA. - When multiple pages are allocated they are assumed to be physically and virtually contiguous. Emulate this behavior with contigmalloc. Sponsored by: Isilon Systems, iX Systems, and Panasas. Modified: projects/ofed/head/sys/ofed/include/linux/gfp.h projects/ofed/head/sys/ofed/include/linux/mm.h projects/ofed/head/sys/ofed/include/linux/page.h projects/ofed/head/sys/ofed/include/linux/slab.h Modified: projects/ofed/head/sys/ofed/include/linux/gfp.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/gfp.h Sat Jul 17 00:29:38 2010 (r210181) +++ projects/ofed/head/sys/ofed/include/linux/gfp.h Sat Jul 17 01:39:44 2010 (r210182) @@ -29,8 +29,19 @@ #ifndef _LINUX_GFP_H_ #define _LINUX_GFP_H_ +#include <sys/systm.h> #include <sys/malloc.h> +#include <linux/page.h> + +#include <vm/vm_object.h> +#include <vm/vm_extern.h> +#include <vm/vm_kern.h> + +#define __GFP_NOWARN 0 +#define __GFP_HIGHMEM 0 +#define __GFP_ZERO M_ZERO + #define GFP_NOWAIT M_NOWAIT #define GFP_ATOMIC (M_NOWAIT | M_USE_RESERVE) #define GFP_KERNEL M_WAITOK @@ -39,4 +50,71 @@ #define GFP_HIGHUSER_MOVABLE M_WAITOK #define GFP_IOFS M_NOWAIT +static inline unsigned long +get_zeroed_page(gfp_t mask) +{ + vm_page_t m; + vm_offset_t p; + + p = kmem_malloc(kernel_map, PAGE_SIZE, mask | M_ZERO); + if (p) { + m = virt_to_page(p); + m->flags |= PG_KVA; + m->object = (vm_object_t)p; + } + return (p); +} + +static inline void +free_page(unsigned long page) +{ + vm_page_t m; + + m = virt_to_page(page); + if (m->flags & PG_KVA) { + m->flags &= ~PG_KVA; + m->object = kernel_object; + } + kmem_free(kernel_map, page, PAGE_SIZE); +} + +static inline void +__free_pages(void *p, unsigned int order) +{ + unsigned long page; + vm_page_t m; + size_t size; + + size = order << PAGE_SHIFT; + for (page = (uintptr_t)p; p < (uintptr_t)p + size; page += PAGE_SIZE) { + m = virt_to_page(page); + if (m->flags & PG_KVA) { + m->flags &= ~PG_KVA; + m->object = kernel_object; + } + } + kmem_free(kernel_map, p, size); +} + +static inline struct page * +alloc_pages(gfp_t gfp_mask, unsigned int order) +{ + unsigned long start; + unsigned long page; + vm_page_t m; + size_t size; + + size = order << PAGE_SHIFT; + start = kmem_alloc_contig(kernel_map, size, gfp_mask, 0, -1, + PAGE_SIZE, 0, VM_MEMATTR_DEFAULT); + if (start == 0) + return (NULL); + for (page = start; page < start + size; page += PAGE_SIZE) { + m = virt_to_page(page); + m->flags |= PG_KVA; + m->object = (vm_object_t)page; + } + return (virt_to_page(start)); +} + #endif /* _LINUX_GFP_H_ */ Modified: projects/ofed/head/sys/ofed/include/linux/mm.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/mm.h Sat Jul 17 00:29:38 2010 (r210181) +++ projects/ofed/head/sys/ofed/include/linux/mm.h Sat Jul 17 01:39:44 2010 (r210182) @@ -30,8 +30,35 @@ #include <linux/spinlock.h> #include <linux/gfp.h> +#include <linux/kernel.h> + +#define PAGE_ALIGN(x) ALIGN(x, PAGE_SIZE) struct vm_area_struct { }; +static inline int +get_order(unsigned long size) +{ + int order; + + size = (size - 1) >> PAGE_SHIFT; + order = 0; + while (size) { + order++; + size >>= 1; + } + return (order); +} + +static inline void * +lowmem_page_address(struct page *page) +{ + + if (page->flags & PG_KVA) + return (page->object); + return (NULL); +} + + #endif /* _LINUX_MM_H_ */ Modified: projects/ofed/head/sys/ofed/include/linux/page.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/page.h Sat Jul 17 00:29:38 2010 (r210181) +++ projects/ofed/head/sys/ofed/include/linux/page.h Sat Jul 17 01:39:44 2010 (r210182) @@ -28,8 +28,15 @@ #ifndef _LINUX_PAGE_H_ #define _LINUX_PAGE_H_ -struct page -{ -}; +#include <linux/types.h> + +#include <sys/param.h> + +#include <vm/vm.h> +#include <vm/vm_page.h> + +#define page vm_page + +#define virt_to_page(x) PHYS_TO_VM_PAGE(vtophys((x))) #endif /* _LINUX_PAGE_H_ */ Modified: projects/ofed/head/sys/ofed/include/linux/slab.h ============================================================================== --- projects/ofed/head/sys/ofed/include/linux/slab.h Sat Jul 17 00:29:38 2010 (r210181) +++ projects/ofed/head/sys/ofed/include/linux/slab.h Sat Jul 17 01:39:44 2010 (r210182) @@ -28,6 +28,8 @@ #ifndef _LINUX_SLAB_H_ #define _LINUX_SLAB_H_ +#include <sys/param.h> +#include <sys/systm.h> #include <sys/malloc.h> #include <vm/uma.h> @@ -40,6 +42,7 @@ MALLOC_DECLARE(M_KMALLOC); #define kzalloc(size, flags) kmalloc((size), (flags) | M_ZERO) #define kfree(ptr) free(__DECONST(void *, (ptr)), M_KMALLOC) #define krealloc(ptr, size, flags) realloc((ptr), (size), M_KMALLOC, (flags)) +#define kcalloc(n, size, flags) kmalloc((n) * (size), flags | M_ZERO) struct kmem_cache { uma_zone_t cache_zone; @@ -96,16 +99,4 @@ kmem_cache_destroy(struct kmem_cache *c) free(c, M_KMALLOC); } -static inline unsigned long -get_zeroed_page(gfp_t mask) -{ - return (unsigned long)kzalloc(PAGE_SIZE, mask); -} - -static inline void -free_page(unsigned long page) -{ - kfree((void *)page); -} - #endif /* _LINUX_SLAB_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201007170139.o6H1dip8082062>