summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_map.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/vm/vm_map.c')
-rw-r--r--sys/vm/vm_map.c127
1 files changed, 91 insertions, 36 deletions
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 425fe0d..ffffa96 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -73,6 +73,7 @@
#include <vm/vm.h>
#include <vm/vm_page.h>
#include <vm/vm_object.h>
+#include <vm/vm_kern.h>
/*
* Virtual memory maps provide for the mapping, protection,
@@ -137,6 +138,11 @@ vm_size_t kentry_data_size;
vm_map_entry_t kentry_free;
vm_map_t kmap_free;
+int kentry_count;
+vm_map_t kmap_free;
+static vm_offset_t mapvm=0;
+static int mapvmpgcnt=0;
+
static void _vm_map_clip_end __P((vm_map_t, vm_map_entry_t, vm_offset_t));
static void _vm_map_clip_start __P((vm_map_t, vm_map_entry_t, vm_offset_t));
@@ -273,27 +279,71 @@ vm_map_init(map, min, max, pageable)
* Allocates a VM map entry for insertion.
* No entry fields are filled in. This routine is
*/
-vm_map_entry_t vm_map_entry_create(map)
+static struct vm_map_entry *mappool;
+static int mappoolcnt;
+void vm_map_entry_dispose(vm_map_t map, vm_map_entry_t entry);
+
+vm_map_entry_t
+vm_map_entry_create(map)
vm_map_t map;
{
vm_map_entry_t entry;
-#ifdef DEBUG
- extern vm_map_t kernel_map, kmem_map, mb_map, pager_map;
- boolean_t isspecial;
-
- isspecial = (map == kernel_map || map == kmem_map ||
- map == mb_map || map == pager_map);
- if (isspecial && map->entries_pageable ||
- !isspecial && !map->entries_pageable)
- panic("vm_map_entry_create: bogus map");
-#endif
- if (map->entries_pageable) {
+ int s;
+ int i;
+#define KENTRY_LOW_WATER 64
+#define MAPENTRY_LOW_WATER 64
+
+ /*
+ * This is a *very* nasty (and sort of incomplete) hack!!!!
+ */
+ if (kentry_count < KENTRY_LOW_WATER) {
+ if (mapvmpgcnt && mapvm) {
+ vm_page_t m;
+ if (m = vm_page_alloc(kmem_object, mapvm-vm_map_min(kmem_map))) {
+ int newentries;
+ newentries = (NBPG/sizeof (struct vm_map_entry));
+ vm_page_wire(m);
+ m->flags &= ~PG_BUSY;
+ pmap_enter(vm_map_pmap(kmem_map), mapvm,
+ VM_PAGE_TO_PHYS(m), VM_PROT_DEFAULT, 1);
+
+ entry = (vm_map_entry_t) mapvm;
+ mapvm += NBPG;
+ --mapvmpgcnt;
+
+ for (i = 0; i < newentries; i++) {
+ vm_map_entry_dispose(kernel_map, entry);
+ entry++;
+ }
+ }
+ }
+ }
+
+ if (map == kernel_map || map == kmem_map || map == pager_map) {
+
+ if (entry = kentry_free) {
+ kentry_free = entry->next;
+ --kentry_count;
+ return entry;
+ }
+
+ if (entry = mappool) {
+ mappool = entry->next;
+ --mappoolcnt;
+ return entry;
+ }
+
+ } else {
+ if (entry = mappool) {
+ mappool = entry->next;
+ --mappoolcnt;
+ return entry;
+ }
+
MALLOC(entry, vm_map_entry_t, sizeof(struct vm_map_entry),
M_VMMAPENT, M_WAITOK);
- } else {
- if (entry = kentry_free)
- kentry_free = kentry_free->next;
}
+dopanic:
if (entry == NULL)
panic("vm_map_entry_create: out of map entries");
@@ -305,25 +355,28 @@ vm_map_entry_t vm_map_entry_create(map)
*
* Inverse of vm_map_entry_create.
*/
-void vm_map_entry_dispose(map, entry)
+void
+vm_map_entry_dispose(map, entry)
vm_map_t map;
vm_map_entry_t entry;
{
-#ifdef DEBUG
- extern vm_map_t kernel_map, kmem_map, mb_map, pager_map;
- boolean_t isspecial;
-
- isspecial = (map == kernel_map || map == kmem_map ||
- map == mb_map || map == pager_map);
- if (isspecial && map->entries_pageable ||
- !isspecial && !map->entries_pageable)
- panic("vm_map_entry_dispose: bogus map");
-#endif
- if (map->entries_pageable) {
- FREE(entry, M_VMMAPENT);
- } else {
+ extern vm_map_t kernel_map, kmem_map, pager_map;
+ int s;
+
+ if (map == kernel_map || map == kmem_map || map == pager_map ||
+ kentry_count < KENTRY_LOW_WATER) {
entry->next = kentry_free;
kentry_free = entry;
+ ++kentry_count;
+ } else {
+ if (mappoolcnt < MAPENTRY_LOW_WATER) {
+ entry->next = mappool;
+ mappool = entry;
+ ++mappoolcnt;
+ return;
+ }
+
+ FREE(entry, M_VMMAPENT);
}
}
@@ -799,7 +852,7 @@ static void _vm_map_clip_start(map, entry, start)
* See if we can simplify this entry first
*/
- vm_map_simplify_entry(map, entry);
+ /* vm_map_simplify_entry(map, entry); */
/*
* Split off the front portion --
@@ -1130,7 +1183,7 @@ vm_map_pageable(map, start, end, new_pageable)
{
register vm_map_entry_t entry;
vm_map_entry_t start_entry;
- register vm_offset_t failed;
+ register vm_offset_t failed = 0;
int rv;
vm_map_lock(map);
@@ -2546,11 +2599,13 @@ void vm_map_simplify(map, start)
if (map->first_free == this_entry)
map->first_free = prev_entry;
- SAVE_HINT(map, prev_entry);
- vm_map_entry_unlink(map, this_entry);
- prev_entry->end = this_entry->end;
- vm_object_deallocate(this_entry->object.vm_object);
- vm_map_entry_dispose(map, this_entry);
+ if (!this_entry->object.vm_object->paging_in_progress) {
+ SAVE_HINT(map, prev_entry);
+ vm_map_entry_unlink(map, this_entry);
+ prev_entry->end = this_entry->end;
+ vm_object_deallocate(this_entry->object.vm_object);
+ vm_map_entry_dispose(map, this_entry);
+ }
}
vm_map_unlock(map);
}
OpenPOWER on IntegriCloud