summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2013-06-28 03:51:20 +0000
committerjeff <jeff@FreeBSD.org>2013-06-28 03:51:20 +0000
commite725dd5c1ef985f6374f7a36ebdaaf10964b0131 (patch)
tree1ec9ab556a4e03f63542c71cdcc9e56ac39f7ef0 /sys/vm
parent5aabb39c86af06392b2155209b47c6511f6f8167 (diff)
downloadFreeBSD-src-e725dd5c1ef985f6374f7a36ebdaaf10964b0131.zip
FreeBSD-src-e725dd5c1ef985f6374f7a36ebdaaf10964b0131.tar.gz
- Add a general purpose resource allocator, vmem, from NetBSD. It was
originally inspired by the Solaris vmem detailed in the proceedings of usenix 2001. The NetBSD version was heavily refactored for bugs and simplicity. - Use this resource allocator to allocate the buffer and transient maps. Buffer cache defrags are reduced by 25% when used by filesystems with mixed block sizes. Ultimately this may permit dynamic buffer cache sizing on low KVA machines. Discussed with: alc, kib, attilio Tested by: pho Sponsored by: EMC / Isilon Storage Division
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm.h4
-rw-r--r--sys/vm/vm_init.c38
-rw-r--r--sys/vm/vm_kern.c2
-rw-r--r--sys/vm/vm_kern.h4
-rw-r--r--sys/vm/vm_object.c6
-rw-r--r--sys/vm/vm_pager.c12
-rw-r--r--sys/vm/vm_pager.h3
7 files changed, 29 insertions, 40 deletions
diff --git a/sys/vm/vm.h b/sys/vm/vm.h
index 106c510..bfb4a60 100644
--- a/sys/vm/vm.h
+++ b/sys/vm/vm.h
@@ -134,10 +134,6 @@ struct kva_md_info {
vm_offset_t buffer_eva;
vm_offset_t clean_sva;
vm_offset_t clean_eva;
- vm_offset_t pager_sva;
- vm_offset_t pager_eva;
- vm_offset_t bio_transient_sva;
- vm_offset_t bio_transient_eva;
};
extern struct kva_md_info kmi;
diff --git a/sys/vm/vm_init.c b/sys/vm/vm_init.c
index 62e9891..2c4bcb6 100644
--- a/sys/vm/vm_init.c
+++ b/sys/vm/vm_init.c
@@ -76,6 +76,7 @@ __FBSDID("$FreeBSD$");
#include <sys/pipe.h>
#include <sys/bio.h>
#include <sys/buf.h>
+#include <sys/vmem.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -120,6 +121,7 @@ vm_mem_init(dummy)
/*
* Initialize other VM packages
*/
+ vmem_startup();
vm_object_init();
vm_map_startup();
kmem_init(virtual_avail, virtual_end);
@@ -183,29 +185,31 @@ again:
if ((vm_size_t)((char *)v - firstaddr) != size)
panic("startup: table size inconsistency");
+ size = (long)nbuf * BKVASIZE + (long)nswbuf * MAXPHYS +
+ (long)bio_transient_maxcnt * MAXPHYS;
clean_map = kmem_suballoc(kernel_map, &kmi->clean_sva, &kmi->clean_eva,
- (long)nbuf * BKVASIZE + (long)nswbuf * MAXPHYS +
- (long)bio_transient_maxcnt * MAXPHYS, TRUE);
- buffer_map = kmem_suballoc(clean_map, &kmi->buffer_sva,
- &kmi->buffer_eva, (long)nbuf * BKVASIZE, FALSE);
- buffer_map->system_map = 1;
+ size, TRUE);
+
+ size = (long)nbuf * BKVASIZE;
+ kmi->buffer_sva = kmem_alloc_nofault(clean_map, size);
+ kmi->buffer_eva = kmi->buffer_sva + size;
+ vmem_init(buffer_arena, "buffer arena", kmi->buffer_sva, size,
+ PAGE_SIZE, 0, 0);
+
+ size = (long)nswbuf * MAXPHYS;
+ swapbkva = kmem_alloc_nofault(clean_map, size);
+ if (!swapbkva)
+ panic("Not enough clean_map VM space for pager buffers");
+
if (bio_transient_maxcnt != 0) {
- bio_transient_map = kmem_suballoc(clean_map,
- &kmi->bio_transient_sva, &kmi->bio_transient_eva,
- (long)bio_transient_maxcnt * MAXPHYS, FALSE);
- bio_transient_map->system_map = 1;
+ size = (long)bio_transient_maxcnt * MAXPHYS;
+ vmem_init(transient_arena, "transient arena",
+ kmem_alloc_nofault(clean_map, size),
+ size, PAGE_SIZE, 0, 0);
}
- pager_map = kmem_suballoc(clean_map, &kmi->pager_sva, &kmi->pager_eva,
- (long)nswbuf * MAXPHYS, FALSE);
- pager_map->system_map = 1;
exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
exec_map_entries * round_page(PATH_MAX + ARG_MAX), FALSE);
pipe_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, maxpipekva,
FALSE);
-
- /*
- * XXX: Mbuf system machine-specific initializations should
- * go here, if anywhere.
- */
}
diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c
index 7c7ccc1..42cd699 100644
--- a/sys/vm/vm_kern.c
+++ b/sys/vm/vm_kern.c
@@ -89,8 +89,6 @@ vm_map_t kernel_map;
vm_map_t kmem_map;
vm_map_t exec_map;
vm_map_t pipe_map;
-vm_map_t buffer_map;
-vm_map_t bio_transient_map;
const void *zero_region;
CTASSERT((ZERO_REGION_SIZE & PAGE_MASK) == 0);
diff --git a/sys/vm/vm_kern.h b/sys/vm/vm_kern.h
index 5730cef..1479e5f 100644
--- a/sys/vm/vm_kern.h
+++ b/sys/vm/vm_kern.h
@@ -64,11 +64,13 @@
#define _VM_VM_KERN_H_ 1
/* Kernel memory management definitions. */
-extern vm_map_t buffer_map;
extern vm_map_t kernel_map;
extern vm_map_t kmem_map;
extern vm_map_t exec_map;
extern vm_map_t pipe_map;
+extern struct vmem *buffer_arena;
+extern struct vmem *transient_arena;
+extern vm_offset_t swapbkva;
extern u_long vm_kmem_size;
#endif /* _VM_VM_KERN_H_ */
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 97d8557..1c20ca6 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -2231,12 +2231,6 @@ vm_object_in_map(vm_object_t object)
/* sx_sunlock(&allproc_lock); */
if (_vm_object_in_map(kernel_map, object, 0))
return 1;
- if (_vm_object_in_map(kmem_map, object, 0))
- return 1;
- if (_vm_object_in_map(pager_map, object, 0))
- return 1;
- if (_vm_object_in_map(buffer_map, object, 0))
- return 1;
return 0;
}
diff --git a/sys/vm/vm_pager.c b/sys/vm/vm_pager.c
index 989c318..c7d038b 100644
--- a/sys/vm/vm_pager.c
+++ b/sys/vm/vm_pager.c
@@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/vm_param.h>
+#include <vm/vm_kern.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_pager.h>
@@ -174,11 +175,10 @@ static const int npagers = sizeof(pagertab) / sizeof(pagertab[0]);
* cleaning requests (NPENDINGIO == 64) * the maximum swap cluster size
* (MAXPHYS == 64k) if you want to get the most efficiency.
*/
-vm_map_t pager_map;
-static int bswneeded;
-static vm_offset_t swapbkva; /* swap buffers kva */
-struct mtx pbuf_mtx;
+struct mtx_padalign pbuf_mtx;
static TAILQ_HEAD(swqueue, buf) bswlist;
+static int bswneeded;
+vm_offset_t swapbkva; /* swap buffers kva */
void
vm_pager_init()
@@ -215,10 +215,6 @@ vm_pager_bufferinit()
cluster_pbuf_freecnt = nswbuf / 2;
vnode_pbuf_freecnt = nswbuf / 2 + 1;
-
- swapbkva = kmem_alloc_nofault(pager_map, nswbuf * MAXPHYS);
- if (!swapbkva)
- panic("Not enough pager_map VM space for physical buffers");
}
/*
diff --git a/sys/vm/vm_pager.h b/sys/vm/vm_pager.h
index b5d923c..aa1b7f0 100644
--- a/sys/vm/vm_pager.h
+++ b/sys/vm/vm_pager.h
@@ -95,9 +95,8 @@ extern struct pagerops mgtdevicepagerops;
#ifdef _KERNEL
-extern vm_map_t pager_map;
extern struct pagerops *pagertab[];
-extern struct mtx pbuf_mtx;
+extern struct mtx_padalign pbuf_mtx;
vm_object_t vm_pager_allocate(objtype_t, void *, vm_ooffset_t, vm_prot_t,
vm_ooffset_t, struct ucred *);
OpenPOWER on IntegriCloud