Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 3 Aug 2010 08:37:16 +0000 (UTC)
From:      Jeff Roberson <jeff@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r210789 - projects/ofed/head/sys/ofed/include/linux
Message-ID:  <201008030837.o738bGc1090163@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jeff
Date: Tue Aug  3 08:37:16 2010
New Revision: 210789
URL: http://svn.freebsd.org/changeset/base/210789

Log:
   - Use a simpler method for deriving the KVA address of a page that exists
     in the kmem or kernel objects as suggested by Alan Cox.  This is not
     only cheaper than the other method but also is compatible with
     more page sources.
  
  Sponsored by:	Isilon Systems, iX Systems, and Panasas.

Modified:
  projects/ofed/head/sys/ofed/include/linux/dma-mapping.h
  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/scatterlist.h

Modified: projects/ofed/head/sys/ofed/include/linux/dma-mapping.h
==============================================================================
--- projects/ofed/head/sys/ofed/include/linux/dma-mapping.h	Tue Aug  3 08:34:41 2010	(r210788)
+++ projects/ofed/head/sys/ofed/include/linux/dma-mapping.h	Tue Aug  3 08:37:16 2010	(r210789)
@@ -117,8 +117,6 @@ dma_set_coherent_mask(struct device *dev
 	return 0;
 }
 
-MALLOC_DECLARE(M_LINUX_DMA);
-
 static inline void *
 dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
     gfp_t flag)
@@ -132,7 +130,8 @@ dma_alloc_coherent(struct device *dev, s
 	else
 		high = BUS_SPACE_MAXADDR_32BIT;
 	align = PAGE_SIZE << get_order(size);
-	mem = contigmalloc(size, M_LINUX_DMA, flag, 0, high, align, 0);
+	mem = (void *)kmem_alloc_contig(kmem_map, size, flag, 0, high, align,
+	    0, VM_MEMATTR_DEFAULT);
 	if (mem)
 		*dma_handle = vtophys(mem);
 	else
@@ -144,7 +143,8 @@ static inline void
 dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
     dma_addr_t dma_handle)
 {
-	contigfree(cpu_addr, size, M_LINUX_DMA);
+
+	kmem_free(kmem_map, (vm_offset_t)cpu_addr, size);
 }
 
 /* XXX This only works with no iommu. */
@@ -186,7 +186,7 @@ dma_map_page(struct device *dev, struct 
     unsigned long offset, size_t size, enum dma_data_direction direction)
 {
 
-	return  VM_PAGE_TO_PHYS(page) + offset;
+	return VM_PAGE_TO_PHYS(page) + offset;
 }
 
 static inline void

Modified: projects/ofed/head/sys/ofed/include/linux/gfp.h
==============================================================================
--- projects/ofed/head/sys/ofed/include/linux/gfp.h	Tue Aug  3 08:34:41 2010	(r210788)
+++ projects/ofed/head/sys/ofed/include/linux/gfp.h	Tue Aug  3 08:37:16 2010	(r210789)
@@ -50,19 +50,20 @@
 #define	GFP_HIGHUSER_MOVABLE	M_WAITOK
 #define	GFP_IOFS	M_NOWAIT
 
+static inline void *
+page_address(struct page *page)
+{
+
+	if (page->object != kmem_object && page->object != kernel_object)
+		return (NULL);
+	return (void *)(VM_MIN_KERNEL_ADDRESS + IDX_TO_OFF(page->pindex));
+}
+
 static inline unsigned long
 _get_page(gfp_t mask)
 {
-	vm_page_t m;
-	vm_offset_t p;
 
-	p = kmem_malloc(kmem_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);
+	return kmem_malloc(kmem_map, PAGE_SIZE, mask);
 }
 
 #define	get_zeroed_page(mask)	_get_page((mask) | M_ZERO)
@@ -72,47 +73,30 @@ _get_page(gfp_t mask)
 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 = kmem_object;
-	}
+	if (page == 0)
+		return;
 	kmem_free(kmem_map, page, PAGE_SIZE);
 }
 
 static inline void
 __free_page(struct page *m)
 {
-	void *p;
 
-	if ((m->flags & PG_KVA) == 0)
+	if (m->object != kmem_object)
 		panic("__free_page:  Freed page %p not allocated via wrappers.",
 		    m);
-	p = m->object;
-	m->flags &= ~PG_KVA;
-	m->object  = kmem_object;
-	kmem_free(kmem_map, (vm_offset_t)p, PAGE_SIZE);
+	kmem_free(kmem_map, (vm_offset_t)page_address(m), PAGE_SIZE);
 }
 
 static inline void
 __free_pages(void *p, unsigned int order)
 {
-	unsigned long start;
-	unsigned long page;
-	vm_page_t m;
 	size_t size;
 
+	if (p == 0)
+		return;
 	size = PAGE_SIZE << order;
-	start = (unsigned long)p;
-	for (page = start; page < start + size; page += PAGE_SIZE) {
-		m = virt_to_page(page);
-		if (m->flags & PG_KVA) {
-			m->flags &= ~PG_KVA;
-			m->object = kmem_object;
-		}
-	}
 	kmem_free(kmem_map, (vm_offset_t)p, size);
 }
 
@@ -124,22 +108,15 @@ __free_pages(void *p, unsigned int order
 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 = PAGE_SIZE << order;
-	start = kmem_alloc_contig(kmem_map, size, gfp_mask, 0, -1,
+	page = kmem_alloc_contig(kmem_map, size, gfp_mask, 0, -1,
 	    size, 0, VM_MEMATTR_DEFAULT);
-	if (start == 0)
+	if (page == 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));
+        return (virt_to_page(page));
 }
 
 #endif	/* _LINUX_GFP_H_ */

Modified: projects/ofed/head/sys/ofed/include/linux/mm.h
==============================================================================
--- projects/ofed/head/sys/ofed/include/linux/mm.h	Tue Aug  3 08:34:41 2010	(r210788)
+++ projects/ofed/head/sys/ofed/include/linux/mm.h	Tue Aug  3 08:37:16 2010	(r210789)
@@ -37,6 +37,10 @@
 struct vm_area_struct {
 };
 
+/*
+ * Compute log2 of the power of two rounded up count of pages
+ * needed for size bytes.
+ */
 static inline int
 get_order(unsigned long size)
 {
@@ -55,10 +59,7 @@ static inline void *
 lowmem_page_address(struct page *page)
 {
 
-	if (page->flags & PG_KVA)
-		return (page->object);
-	return (NULL);
+	return page_address(page);
 }
 
-
 #endif	/* _LINUX_MM_H_ */

Modified: projects/ofed/head/sys/ofed/include/linux/scatterlist.h
==============================================================================
--- projects/ofed/head/sys/ofed/include/linux/scatterlist.h	Tue Aug  3 08:34:41 2010	(r210788)
+++ projects/ofed/head/sys/ofed/include/linux/scatterlist.h	Tue Aug  3 08:37:16 2010	(r210789)
@@ -57,13 +57,15 @@ sg_set_page(struct scatterlist *sg, stru
 	sg_page(sg) = page;
 	sg_dma_len(sg) = len;
 	sg->offset = offset;
+	if (offset > PAGE_SIZE)
+		panic("sg_set_page: Invalid offset %d\n", offset);
 }
 
 static inline void
 sg_set_buf(struct scatterlist *sg, const void *buf, unsigned int buflen)
 {
-	sg_set_page(sg, PHYS_TO_VM_PAGE(vtophys(buf)), buflen,
-	    ((uintptr_t)buf) & PAGE_MASK);
+	sg_set_page(sg, virt_to_page(buf), buflen,
+	    ((uintptr_t)buf) & ~PAGE_MASK);
 }
 
 static inline void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201008030837.o738bGc1090163>