svn commit: r278615 - head/sys/contrib/vchiq/interface/vchiq_arm

Oleksandr Tymoshenko gonzo at FreeBSD.org
Thu Feb 12 04:31:18 UTC 2015


Author: gonzo
Date: Thu Feb 12 04:31:17 2015
New Revision: 278615
URL: https://svnweb.freebsd.org/changeset/base/278615

Log:
  - Perform bus_dmamap_sync on pagelist structure
  - Wire pages of bulk transfer buffer when preparing pagelist

Modified:
  head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c

Modified: head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c
==============================================================================
--- head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c	Thu Feb 12 04:15:55 2015	(r278614)
+++ head/sys/contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c	Thu Feb 12 04:31:17 2015	(r278615)
@@ -353,6 +353,16 @@ vchiq_platform_handle_timeout(VCHIQ_STAT
  * Local functions
  */
 
+static void
+pagelist_page_free(vm_page_t pp)
+{
+	vm_page_lock(pp);
+	vm_page_unwire(pp, PQ_INACTIVE);
+	if (pp->wire_count == 0 && pp->object == NULL)
+		vm_page_free(pp);
+	vm_page_unlock(pp);
+}
+
 /* There is a potential problem with partial cache lines (pages?)
 ** at the ends of the block when reading. If the CPU accessed anything in
 ** the same line (page?) then it may have pulled old data into the cache,
@@ -406,8 +416,6 @@ create_pagelist(char __user *buf, size_t
 	    NULL, NULL,		 /* lockfunc, lockarg */
 	    &bi->pagelist_dma_tag);
 
-
-
 	err = bus_dmamem_alloc(bi->pagelist_dma_tag, (void **)&pagelist,
 	    BUS_DMA_COHERENT | BUS_DMA_WAITOK, &bi->pagelist_dma_map);
 	if (err) {
@@ -444,6 +452,13 @@ create_pagelist(char __user *buf, size_t
 		return (-ENOMEM);
 	}
 
+	for (i = 0; i < actual_pages; i++) {
+		vm_page_lock(pages[i]);
+		vm_page_wire(pages[i]);
+		vm_page_unhold(pages[i]);
+		vm_page_unlock(pages[i]);
+	}
+
 	pagelist->length = count;
 	pagelist->type = type;
 	pagelist->offset = offset;
@@ -496,9 +511,10 @@ create_pagelist(char __user *buf, size_t
 							 g_fragments_base);
 	}
 
-	/* XXX: optimize? INV operation for read WBINV for write? */
 	cpu_dcache_wbinv_range((vm_offset_t)buf, count);
 
+	bus_dmamap_sync(bi->pagelist_dma_tag, bi->pagelist_dma_map, BUS_DMASYNC_PREWRITE);
+
 	bi->pagelist = pagelist;
 
 	return 0;
@@ -563,12 +579,12 @@ free_pagelist(BULKINFO_T *bi, int actual
 	}
 
 	for (i = 0; i < num_pages; i++) {
-		if (pagelist->type != PAGELIST_WRITE)
+		if (pagelist->type != PAGELIST_WRITE) {
 			vm_page_dirty(pages[i]);
+			pagelist_page_free(pages[i]);
+		}
 	}
 
-	vm_page_unhold_pages(pages, num_pages);
-
 	bus_dmamap_unload(bi->pagelist_dma_tag, bi->pagelist_dma_map);
 	bus_dmamem_free(bi->pagelist_dma_tag, bi->pagelist, bi->pagelist_dma_map);
 	bus_dmamap_destroy(bi->pagelist_dma_tag, bi->pagelist_dma_map);


More information about the svn-src-head mailing list