Module Name:    src
Committed By:   reinoud
Date:           Tue Dec 13 12:29:19 UTC 2011

Modified Files:
        src/sys/arch/usermode/usermode: pmap.c

Log Message:
Implement a new TLB system. This fixes the TLB issues that has been plaguing
the pmap.


To generate a diff of this commit:
cvs rdiff -u -r1.75 -r1.76 src/sys/arch/usermode/usermode/pmap.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/usermode/usermode/pmap.c
diff -u src/sys/arch/usermode/usermode/pmap.c:1.75 src/sys/arch/usermode/usermode/pmap.c:1.76
--- src/sys/arch/usermode/usermode/pmap.c:1.75	Tue Dec 13 11:11:03 2011
+++ src/sys/arch/usermode/usermode/pmap.c	Tue Dec 13 12:29:19 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.75 2011/12/13 11:11:03 reinoud Exp $ */
+/* $NetBSD: pmap.c,v 1.76 2011/12/13 12:29:19 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2011 Reinoud Zandijk <rein...@netbsd.org>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.75 2011/12/13 11:11:03 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.76 2011/12/13 12:29:19 reinoud Exp $");
 
 #include "opt_memsize.h"
 #include "opt_kmempages.h"
@@ -52,7 +52,6 @@ struct pv_entry {
 	uint8_t		pv_vflags;	/* per mapping flags */
 #define PV_WIRED	0x01		/* wired mapping */
 #define PV_UNMANAGED	0x02		/* entered by pmap_kenter_ */
-#define PV_MAPPEDIN	0x04		/* is actually mapped */
 	uint8_t		pv_pflags;	/* per phys page flags */
 #define PV_REFERENCED	0x01
 #define PV_MODIFIED	0x02
@@ -66,9 +65,10 @@ struct pmap {
 	struct	pv_entry **pm_entries;
 };
 
-static struct pv_entry *pv_table;
-static struct pmap	pmap_kernel_store;
-struct pmap * const	kernel_pmap_ptr = &pmap_kernel_store;
+static struct pv_entry  *pv_table;	/* physical pages */
+static struct pv_entry **tlb;		/* current tlb mappings */
+static struct pmap	 pmap_kernel_store;
+struct pmap * const	 kernel_pmap_ptr = &pmap_kernel_store;
 
 static pmap_t active_pmap = NULL;
 
@@ -117,7 +117,7 @@ pmap_bootstrap(void)
 	struct pmap *pmap;
 	paddr_t totmem_len;
 	paddr_t fpos, file_len;
-	paddr_t pv_fpos, pm_fpos;
+	paddr_t pv_fpos, pm_fpos, tlb_fpos;
 	paddr_t wlen;
 	paddr_t user_len, barrier_len;
 	paddr_t pv_table_size;
@@ -307,6 +307,25 @@ pmap_bootstrap(void)
 	kmem_ext_cur_start += pm_entries_size;
 	fpos += pm_entries_size;
 
+	/* set up tlb space */
+	tlb = (struct pv_entry **) kmem_ext_cur_start;
+
+	tlb_fpos = fpos;
+	addr = thunk_mmap(tlb, pm_entries_size,
+		THUNK_PROT_READ | THUNK_PROT_WRITE,
+		THUNK_MAP_FILE | THUNK_MAP_FIXED | THUNK_MAP_SHARED,
+		mem_fh, tlb_fpos);
+	if (addr != (void *) tlb)
+		panic("pmap_bootstrap: can't map in tlb entries\n");
+
+	memset(tlb, 0, pm_entries_size);	/* test and clear */
+
+	dprintf_debug("kernel tlb entries initialiased correctly\n");
+
+	/* advance */
+	kmem_ext_cur_start += pm_entries_size;
+	fpos += pm_entries_size;
+
 	/* kmem used [kmem_ext_start - kmem_ext_cur_start] */
 	kmem_ext_cur_end = kmem_ext_cur_start;
 
@@ -323,6 +342,12 @@ pmap_bootstrap(void)
 		pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE, 0);
 	}
 	dprintf_debug("kernel pmap entries mem added to the kernel pmap\n");
+	for (pg = 0; pg < pm_entries_size; pg += PAGE_SIZE) {
+		pa = tlb_fpos + pg;
+		va = (vaddr_t) tlb + pg;
+		pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE, 0);
+	}
+	dprintf_debug("kernel tlb entries mem added to the kernel pmap\n");
 
 	/* add file space to uvm's FREELIST */
 	/* XXX really from 0? or from fpos to have better stats */
@@ -519,8 +544,8 @@ pmap_fault(pmap_t pmap, vaddr_t va, vm_p
 		return true;
 	}
 
-	/* if its not mapped in, we have a TLB fault */
-	if ((pv->pv_vflags & PV_MAPPEDIN) == 0) {
+	/* check the TLB, if NULL we have a TLB fault */
+	if (tlb[pv->pv_lpn] == NULL) {
 		if (pv->pv_mmap_ppl != THUNK_PROT_NONE) {
 			dprintf_debug("%s: tlb fault page lpn %"PRIiPTR"\n",
 				__func__, pv->pv_lpn);
@@ -606,9 +631,9 @@ pmap_page_activate(struct pv_entry *pv)
 		panic("pmap_page_activate: mmap failed (expected %p got %p): %d",
 		    (void *)va, addr, thunk_geterrno());
 
-	pv->pv_vflags &= ~PV_MAPPEDIN;
+	tlb[pv->pv_lpn] = NULL;
 	if (pv->pv_mmap_ppl != THUNK_PROT_NONE)
-		pv->pv_vflags |= PV_MAPPEDIN;
+		tlb[pv->pv_lpn] = pv;
 }
 
 static void
@@ -625,7 +650,8 @@ pmap_page_deactivate(struct pv_entry *pv
 		(void *) va, (void *) pa, pv->pv_mmap_ppl, (void *) addr);
 	if (addr != (void *) va)
 		panic("pmap_page_deactivate: mmap failed");
-	pv->pv_vflags &= ~PV_MAPPEDIN;
+
+	tlb[pv->pv_lpn] = NULL;
 }
 
 static void

Reply via email to