Module Name: src
Committed By: matt
Date: Sun Aug 9 22:13:07 UTC 2009
Modified Files:
src/sys/uvm: uvm_map.c
Log Message:
If PMAP_MAP_POOLPAGE is defined, use it to map kernel map entries. This
avoids TLB pollution on those platforms that define it.
To generate a diff of this commit:
cvs rdiff -u -r1.275 -r1.276 src/sys/uvm/uvm_map.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/uvm/uvm_map.c
diff -u src/sys/uvm/uvm_map.c:1.275 src/sys/uvm/uvm_map.c:1.276
--- src/sys/uvm/uvm_map.c:1.275 Sat Aug 1 16:35:51 2009
+++ src/sys/uvm/uvm_map.c Sun Aug 9 22:13:07 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_map.c,v 1.275 2009/08/01 16:35:51 yamt Exp $ */
+/* $NetBSD: uvm_map.c,v 1.276 2009/08/09 22:13:07 matt Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.275 2009/08/01 16:35:51 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.276 2009/08/09 22:13:07 matt Exp $");
#include "opt_ddb.h"
#include "opt_uvmhist.h"
@@ -1345,6 +1345,7 @@
args->uma_uobj = uobj;
args->uma_uoffset = uoffset;
+ UVMHIST_LOG(maphist, "<- done!", 0,0,0,0);
return 0;
}
@@ -4638,13 +4639,15 @@
uvm_kmapent_alloc(struct vm_map *map, int flags)
{
struct vm_page *pg;
- struct uvm_map_args args;
struct uvm_kmapent_hdr *ukh;
struct vm_map_entry *entry;
+#ifndef PMAP_MAP_POOLPAGE
+ struct uvm_map_args args;
uvm_flag_t mapflags = UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL,
UVM_INH_NONE, UVM_ADV_RANDOM, flags | UVM_FLAG_NOMERGE);
- vaddr_t va;
int error;
+#endif
+ vaddr_t va;
int i;
KDASSERT(UVM_KMAPENT_CHUNK > 2);
@@ -4652,7 +4655,9 @@
KASSERT(vm_map_pmap(map) == pmap_kernel());
UVMMAP_EVCNT_INCR(uke_alloc);
+#ifndef PMAP_MAP_POOLPAGE
entry = NULL;
+#endif
again:
/*
* try to grab an entry from freelist.
@@ -4684,6 +4689,10 @@
goto again;
}
+#ifdef PMAP_MAP_POOLPAGE
+ va = PMAP_MAP_POOLPAGE(VM_PAGE_TO_PHYS(pg));
+ KASSERT(va != NULL);
+#else
error = uvm_map_prepare(map, 0, PAGE_SIZE, NULL, UVM_UNKNOWN_OFFSET,
0, mapflags, &args);
if (error) {
@@ -4697,27 +4706,35 @@
VM_PROT_READ|VM_PROT_WRITE|PMAP_KMPAGE);
pmap_update(vm_map_pmap(map));
+#endif
ukh = (void *)va;
/*
- * use the first entry for ukh itsself.
+ * use the last entry for ukh itsself.
*/
- entry = &ukh->ukh_entries[0];
+ i = UVM_KMAPENT_CHUNK - 1;
+#ifndef PMAP_MAP_POOLPAGE
+ entry = &ukh->ukh_entries[i--];
entry->flags = UVM_MAP_KERNEL | UVM_MAP_KMAPENT;
error = uvm_map_enter(map, &args, entry);
KASSERT(error == 0);
+#endif
ukh->ukh_nused = UVM_KMAPENT_CHUNK;
ukh->ukh_map = map;
ukh->ukh_freelist = NULL;
- for (i = UVM_KMAPENT_CHUNK - 1; i >= 2; i--) {
+ for (; i >= 1; i--) {
struct vm_map_entry *xentry = &ukh->ukh_entries[i];
xentry->flags = UVM_MAP_KERNEL;
uvm_kmapent_put(ukh, xentry);
}
+#ifdef PMAP_MAP_POOLPAGE
+ KASSERT(ukh->ukh_nused == 1);
+#else
KASSERT(ukh->ukh_nused == 2);
+#endif
mutex_spin_enter(&uvm_kentry_lock);
LIST_INSERT_HEAD(&vm_map_to_kernel(map)->vmk_kentry_free,
@@ -4725,12 +4742,13 @@
mutex_spin_exit(&uvm_kentry_lock);
/*
- * return second entry.
+ * return first entry.
*/
- entry = &ukh->ukh_entries[1];
+ entry = &ukh->ukh_entries[0];
entry->flags = UVM_MAP_KERNEL;
UVMMAP_EVCNT_INCR(ukh_alloc);
+
return entry;
}
@@ -4744,10 +4762,12 @@
struct uvm_kmapent_hdr *ukh;
struct vm_page *pg;
struct vm_map *map;
+#ifndef PMAP_UNMAP_POOLPAGE
struct pmap *pmap;
+ struct vm_map_entry *deadentry;
+#endif
vaddr_t va;
paddr_t pa;
- struct vm_map_entry *deadentry;
UVMMAP_EVCNT_INCR(uke_free);
ukh = UVM_KHDR_FIND(entry);
@@ -4755,7 +4775,11 @@
mutex_spin_enter(&uvm_kentry_lock);
uvm_kmapent_put(ukh, entry);
+#ifdef PMAP_UNMAP_POOLPAGE
+ if (ukh->ukh_nused > 0) {
+#else
if (ukh->ukh_nused > 1) {
+#endif
if (ukh->ukh_nused == UVM_KMAPENT_CHUNK - 1)
LIST_INSERT_HEAD(
&vm_map_to_kernel(map)->vmk_kentry_free,
@@ -4778,13 +4802,19 @@
LIST_REMOVE(ukh, ukh_listq);
mutex_spin_exit(&uvm_kentry_lock);
+ va = (vaddr_t)ukh;
+
+#ifdef PMAP_UNMAP_POOLPAGE
+ KASSERT(ukh->ukh_nused == 0);
+ pa = PMAP_UNMAP_POOLPAGE(va);
+ KASSERT(pa != 0);
+#else
KASSERT(ukh->ukh_nused == 1);
/*
* remove map entry for ukh itsself.
*/
- va = (vaddr_t)ukh;
KASSERT((va & PAGE_MASK) == 0);
vm_map_lock(map);
uvm_unmap_remove(map, va, va + PAGE_SIZE, &deadentry, NULL, 0);
@@ -4804,6 +4834,7 @@
pmap_kremove(va, PAGE_SIZE);
pmap_update(vm_map_pmap(map));
vm_map_unlock(map);
+#endif /* !PMAP_UNMAP_POOLPAGE */
pg = PHYS_TO_VM_PAGE(pa);
uvm_pagefree(pg);
UVMMAP_EVCNT_INCR(ukh_free);