Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 6 Dec 2010 12:09:23 +0530
From:      "Jayachandran C." <c.jayachandran@gmail.com>
To:        freebsd-mips@freebsd.org, Alan Cox <alc@cs.rice.edu>
Subject:   uma_small_alloc from direct mapped memory.
Message-ID:  <AANLkTi=Rn_L%2BLtGyAay7HJQco6ne-WgRxri-BH=A9q1m@mail.gmail.com>

next in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
Hi all,

The attached patch uses the mechanism used to allocate page table
pages for UMA small allocations too.  This will make sure that all the
small UMA allocations comes from KSEG0 pages in 32 bit and XKPHYS in
64bit.

This reduces TLB misses in kernel code significantly, and can give
major performance advantage for applications that spent a lot of time
in kernel.

Please let me know your comments.

Thanks,
JC.

[-- Attachment #2 --]
Index: sys/mips/include/pmap.h
===================================================================
--- sys/mips/include/pmap.h	(revision 216147)
+++ sys/mips/include/pmap.h	(working copy)
@@ -163,6 +163,9 @@
 int pmap_compute_pages_to_dump(void);
 void pmap_flush_pvcache(vm_page_t m);
 int pmap_emulate_modified(pmap_t pmap, vm_offset_t va);
+void pmap_grow_direct_page_cache(void);
+vm_page_t pmap_alloc_direct_page(unsigned int index, int req);
+
 #endif				/* _KERNEL */
 
 #endif				/* !LOCORE */
Index: sys/mips/include/vmparam.h
===================================================================
--- sys/mips/include/vmparam.h	(revision 216157)
+++ sys/mips/include/vmparam.h	(working copy)
@@ -149,6 +149,8 @@
 #define	VM_INITIAL_PAGEIN	16
 #endif
 
+#define	UMA_MD_SMALL_ALLOC
+
 /*
  * max number of non-contig chunks of physical RAM you can have
  */
Index: sys/mips/mips/vm_machdep.c
===================================================================
--- sys/mips/mips/vm_machdep.c	(revision 216147)
+++ sys/mips/mips/vm_machdep.c	(working copy)
@@ -538,8 +538,57 @@
 void
 swi_vm(void *dummy)
 {
+
+	if (busdma_swi_pending)
+		busdma_swi();
 }
 
+void *
+uma_small_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
+{
+	static vm_pindex_t color;
+	vm_paddr_t pa;
+	vm_page_t m;
+	int pflags;
+	void *va;
+
+	*flags = UMA_SLAB_PRIV;
+
+	if ((wait & (M_NOWAIT|M_USE_RESERVE)) == M_NOWAIT)
+		pflags = VM_ALLOC_INTERRUPT;
+	else
+		pflags = VM_ALLOC_SYSTEM;
+
+	for (;;) {
+		m = pmap_alloc_direct_page(color++, pflags);
+		if (m == NULL) {
+			if (wait & M_NOWAIT)
+				return (NULL);
+			else
+				pmap_grow_direct_page_cache();
+		} else
+			break;
+	}
+
+	pa = VM_PAGE_TO_PHYS(m);
+	va = (void *)MIPS_PHYS_TO_DIRECT(pa);
+	if ((wait & M_ZERO) && (m->flags & PG_ZERO) == 0)
+		bzero(va, PAGE_SIZE);
+	return (va);
+}
+
+void
+uma_small_free(void *mem, int size, u_int8_t flags)
+{
+	vm_page_t m;
+
+	m = PHYS_TO_VM_PAGE(MIPS_DIRECT_TO_PHYS((vm_offset_t)mem));
+	m->wire_count--;
+	vm_page_free(m);
+	atomic_subtract_int(&cnt.v_wire_count, 1);
+}
+
+
 int
 cpu_set_user_tls(struct thread *td, void *tls_base)
 {
Index: sys/mips/mips/pmap.c
===================================================================
--- sys/mips/mips/pmap.c	(revision 216157)
+++ sys/mips/mips/pmap.c	(working copy)
@@ -185,8 +185,6 @@
 static vm_page_t _pmap_allocpte(pmap_t pmap, unsigned ptepindex, int flags);
 static int pmap_unuse_pt(pmap_t, vm_offset_t, vm_page_t);
 static int init_pte_prot(vm_offset_t va, vm_page_t m, vm_prot_t prot);
-static vm_page_t pmap_alloc_pte_page(unsigned int index, int req);
-static void pmap_grow_pte_page_cache(void);
 
 #ifdef SMP
 static void pmap_invalidate_page_action(void *arg);
@@ -1062,8 +1060,8 @@
 	bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
 }
 
-static void
-pmap_grow_pte_page_cache()
+void
+pmap_grow_direct_page_cache()
 {
 
 #ifdef __mips_n64
@@ -1073,8 +1071,8 @@
 #endif
 }
 
-static vm_page_t
-pmap_alloc_pte_page(unsigned int index, int req)
+vm_page_t
+pmap_alloc_direct_page(unsigned int index, int req)
 {
 	vm_page_t m;
 
@@ -1107,8 +1105,8 @@
 	/*
 	 * allocate the page directory page
 	 */
-	while ((ptdpg = pmap_alloc_pte_page(NUSERPGTBLS, VM_ALLOC_NORMAL)) == NULL)
-	       pmap_grow_pte_page_cache();
+	while ((ptdpg = pmap_alloc_direct_page(NUSERPGTBLS, VM_ALLOC_NORMAL)) == NULL)
+	       pmap_grow_direct_page_cache();
 
 	ptdva = MIPS_PHYS_TO_DIRECT(VM_PAGE_TO_PHYS(ptdpg));
 	pmap->pm_segtab = (pd_entry_t *)ptdva;
@@ -1141,11 +1139,11 @@
 	/*
 	 * Find or fabricate a new pagetable page
 	 */
-	if ((m = pmap_alloc_pte_page(ptepindex, VM_ALLOC_NORMAL)) == NULL) {
+	if ((m = pmap_alloc_direct_page(ptepindex, VM_ALLOC_NORMAL)) == NULL) {
 		if (flags & M_WAITOK) {
 			PMAP_UNLOCK(pmap);
 			vm_page_unlock_queues();
-			pmap_grow_pte_page_cache();
+			pmap_grow_direct_page_cache();
 			vm_page_lock_queues();
 			PMAP_LOCK(pmap);
 		}
@@ -1313,7 +1311,7 @@
 #ifdef __mips_n64
 		if (*pdpe == 0) {
 			/* new intermediate page table entry */
-			nkpg = pmap_alloc_pte_page(nkpt, VM_ALLOC_INTERRUPT);
+			nkpg = pmap_alloc_direct_page(nkpt, VM_ALLOC_INTERRUPT);
 			if (nkpg == NULL)
 				panic("pmap_growkernel: no memory to grow kernel");
 			*pdpe = (pd_entry_t)MIPS_PHYS_TO_DIRECT(VM_PAGE_TO_PHYS(nkpg));
@@ -1333,7 +1331,7 @@
 		/*
 		 * This index is bogus, but out of the way
 		 */
-		nkpg = pmap_alloc_pte_page(nkpt, VM_ALLOC_INTERRUPT);
+		nkpg = pmap_alloc_direct_page(nkpt, VM_ALLOC_INTERRUPT);
 		if (!nkpg)
 			panic("pmap_growkernel: no memory to grow kernel");
 		nkpt++;

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?AANLkTi=Rn_L%2BLtGyAay7HJQco6ne-WgRxri-BH=A9q1m>