svn commit: r210182 - projects/ofed/head/sys/ofed/include/linux
Jeff Roberson
jeff at FreeBSD.org
Sat Jul 17 01:39:44 UTC 2010
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_ */
More information about the svn-src-projects
mailing list