From owner-svn-src-projects@FreeBSD.ORG Sat Jul 17 01:39:44 2010 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9F2EC1065672; Sat, 17 Jul 2010 01:39:44 +0000 (UTC) (envelope-from jeff@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 8D3E98FC1A; Sat, 17 Jul 2010 01:39:44 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o6H1diSa082067; Sat, 17 Jul 2010 01:39:44 GMT (envelope-from jeff@svn.freebsd.org) Received: (from jeff@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o6H1dip8082062; Sat, 17 Jul 2010 01:39:44 GMT (envelope-from jeff@svn.freebsd.org) Message-Id: <201007170139.o6H1dip8082062@svn.freebsd.org> From: Jeff Roberson Date: Sat, 17 Jul 2010 01:39:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r210182 - projects/ofed/head/sys/ofed/include/linux X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 17 Jul 2010 01:39:44 -0000 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 #include +#include + +#include +#include +#include + +#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 #include +#include + +#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 + +#include + +#include +#include + +#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 +#include #include #include @@ -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_ */