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