aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJohn Dyson <dyson@FreeBSD.org>1996-11-30 22:41:49 +0000
committerJohn Dyson <dyson@FreeBSD.org>1996-11-30 22:41:49 +0000
commit09e0c6ccdd3d1d3005b162dd7dbd77fae8d0f26e (patch)
treec2414524de2607538eaf1294e5d9ee92fc65c8d6 /sys
parentfaf215c7ad7154f80620d19d3fad0b0cab8813fc (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/vfs_bio.c100
-rw-r--r--sys/kern/vfs_cluster.c10
-rw-r--r--sys/sys/bio.h4
-rw-r--r--sys/sys/buf.h4
-rw-r--r--sys/sys/param.h9
-rw-r--r--sys/vm/vm_fault.c15
-rw-r--r--sys/vm/vm_map.c7
-rw-r--r--sys/vm/vm_map.h7
-rw-r--r--sys/vm/vm_pager.c33
9 files changed, 135 insertions, 54 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 3e6e6f94783e..a6533956dc5c 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -18,7 +18,7 @@
* 5. Modifications may be freely made to this file if the above conditions
* are met.
*
- * $Id: vfs_bio.c,v 1.105 1996/11/17 02:10:48 dyson Exp $
+ * $Id: vfs_bio.c,v 1.106 1996/11/28 04:26:04 dyson Exp $
*/
/*
@@ -51,6 +51,8 @@
#include <vm/vm_page.h>
#include <vm/vm_object.h>
#include <vm/vm_extern.h>
+#include <vm/lock.h>
+#include <vm/vm_map.h>
#include <sys/buf.h>
#include <sys/mount.h>
#include <sys/malloc.h>
@@ -92,7 +94,6 @@ int vfs_update_wakeup;
/*
* buffers base kva
*/
-caddr_t buffers_kva;
/*
* bogus page -- for I/O to/from partially complete buffers
@@ -134,7 +135,6 @@ bufinit()
for (i = 0; i < BUFFER_QUEUES; i++)
TAILQ_INIT(&bufqueues[i]);
- buffers_kva = (caddr_t) kmem_alloc_pageable(buffer_map, MAXBSIZE * nbuf);
/* finally, initialize each buffer header and stick on empty q */
for (i = 0; i < nbuf; i++) {
bp = &buf[i];
@@ -145,7 +145,6 @@ bufinit()
bp->b_wcred = NOCRED;
bp->b_qindex = QUEUE_EMPTY;
bp->b_vnbufs.le_next = NOLIST;
- bp->b_data = buffers_kva + i * MAXBSIZE;
TAILQ_INSERT_TAIL(&bufqueues[QUEUE_EMPTY], bp, b_freelist);
LIST_INSERT_HEAD(&invalhash, bp, b_hash);
}
@@ -177,6 +176,25 @@ bufinit()
}
/*
+ * Free the kva allocation for a buffer
+ * Must be called only at splbio or higher,
+ * as this is the only locking for buffer_map.
+ */
+static void
+bfreekva(struct buf * bp)
+{
+ if (bp->b_kvasize == 0)
+ return;
+
+ vm_map_delete(buffer_map,
+ (vm_offset_t) bp->b_kvabase,
+ (vm_offset_t) bp->b_kvabase + bp->b_kvasize);
+
+ bp->b_kvasize = 0;
+
+}
+
+/*
* remove the buffer from the appropriate free list
*/
void
@@ -562,6 +580,10 @@ brelse(struct buf * bp)
LIST_REMOVE(bp, b_hash);
LIST_INSERT_HEAD(&invalhash, bp, b_hash);
bp->b_dev = NODEV;
+ /*
+ * Get rid of the kva allocation *now*
+ */
+ bfreekva(bp);
if (needsbuffer) {
wakeup(&needsbuffer);
needsbuffer=0;
@@ -724,7 +746,7 @@ vfs_vmio_release(bp)
/*
* Check to see if a block is currently memory resident.
*/
-__inline struct buf *
+struct buf *
gbincore(struct vnode * vp, daddr_t blkno)
{
struct buf *bp;
@@ -812,10 +834,11 @@ vfs_bio_awrite(struct buf * bp)
* Find a buffer header which is available for use.
*/
static struct buf *
-getnewbuf(int slpflag, int slptimeo, int doingvmio)
+getnewbuf(int slpflag, int slptimeo, int size, int maxsize)
{
struct buf *bp;
int nbyteswritten = 0;
+ vm_offset_t addr;
start:
if (bufspace >= maxbufspace)
@@ -926,15 +949,43 @@ fillbuf:
bp->b_resid = 0;
bp->b_bcount = 0;
bp->b_npages = 0;
- bp->b_data = buffers_kva + (bp - buf) * MAXBSIZE;
bp->b_dirtyoff = bp->b_dirtyend = 0;
bp->b_validoff = bp->b_validend = 0;
bp->b_usecount = 4;
- if (bufspace >= maxbufspace + nbyteswritten) {
+
+ maxsize = (maxsize + PAGE_MASK) & ~PAGE_MASK;
+ bfreekva(bp);
+
+ /*
+ * See if we have buffer kva space
+ */
+ if (vm_map_findspace(buffer_map, 0, maxsize, &addr)) {
+ bp->b_flags |= B_INVAL;
+ brelse(bp);
+ goto trytofreespace;
+ }
+
+ /*
+ * See if we are below are allocated minimum
+ */
+ if (bufspace >= (maxbufspace + nbyteswritten)) {
bp->b_flags |= B_INVAL;
brelse(bp);
goto trytofreespace;
}
+
+ /*
+ * create a map entry for the buffer -- in essence
+ * reserving the kva space.
+ */
+ vm_map_insert(buffer_map, NULL, 0,
+ addr, addr + maxsize,
+ VM_PROT_ALL, VM_PROT_ALL, MAP_NOFAULT);
+
+ bp->b_data = (caddr_t) addr;
+ bp->b_kvabase = (caddr_t) addr;
+ bp->b_kvasize = maxsize;
+
return (bp);
}
@@ -1057,6 +1108,18 @@ getblk(struct vnode * vp, daddr_t blkno, int size, int slpflag, int slptimeo)
struct buf *bp;
int s;
struct bufhashhdr *bh;
+ int maxsize;
+
+ if (vp->v_mount) {
+ maxsize = vp->v_mount->mnt_stat.f_iosize;
+ /*
+ * This happens on mount points.
+ */
+ if (maxsize < size)
+ maxsize = size;
+ } else {
+ maxsize = size;
+ }
if (size > MAXBSIZE)
panic("getblk: size(%d) > MAXBSIZE(%d)\n", size, MAXBSIZE);
@@ -1086,7 +1149,7 @@ loop:
*/
if (bp->b_bcount != size) {
- if (bp->b_flags & B_VMIO) {
+ if ((bp->b_flags & B_VMIO) && (size <= bp->b_kvasize)) {
allocbuf(bp, size);
} else {
bp->b_flags |= B_NOCACHE;
@@ -1101,14 +1164,8 @@ loop:
return (bp);
} else {
vm_object_t obj;
- int doingvmio;
- if ((obj = vp->v_object) && (vp->v_flag & VVMIO)) {
- doingvmio = 1;
- } else {
- doingvmio = 0;
- }
- if ((bp = getnewbuf(slpflag, slptimeo, doingvmio)) == 0) {
+ if ((bp = getnewbuf(slpflag, slptimeo, size, maxsize)) == 0) {
if (slpflag || slptimeo) {
splx(s);
return NULL;
@@ -1138,7 +1195,7 @@ loop:
bh = BUFHASH(vp, blkno);
LIST_INSERT_HEAD(bh, bp, b_hash);
- if (doingvmio) {
+ if ((obj = vp->v_object) && (vp->v_flag & VVMIO)) {
bp->b_flags |= (B_VMIO | B_CACHE);
#if defined(VFS_BIO_DEBUG)
if (vp->v_type != VREG && vp->v_type != VBLK)
@@ -1171,7 +1228,7 @@ geteblk(int size)
int s;
s = splbio();
- while ((bp = getnewbuf(0, 0, 0)) == 0);
+ while ((bp = getnewbuf(0, 0, size, MAXBSIZE)) == 0);
splx(s);
allocbuf(bp, size);
bp->b_flags |= B_INVAL;
@@ -1201,6 +1258,9 @@ allocbuf(struct buf * bp, int size)
if (!(bp->b_flags & B_BUSY))
panic("allocbuf: buffer not busy");
+ if (bp->b_kvasize < size)
+ panic("allocbuf: buffer too small");
+
if ((bp->b_flags & B_VMIO) == 0) {
caddr_t origbuf;
int origbufsize;
@@ -1227,7 +1287,7 @@ allocbuf(struct buf * bp, int size)
free(bp->b_data, M_BIOBUF);
bufspace -= bp->b_bufsize;
bufmallocspace -= bp->b_bufsize;
- bp->b_data = (caddr_t) buffers_kva + (bp - buf) * MAXBSIZE;
+ bp->b_data = bp->b_kvabase;
bp->b_bufsize = 0;
bp->b_bcount = 0;
bp->b_flags &= ~B_MALLOC;
@@ -1268,7 +1328,7 @@ allocbuf(struct buf * bp, int size)
if (bp->b_flags & B_MALLOC) {
origbuf = bp->b_data;
origbufsize = bp->b_bufsize;
- bp->b_data = (caddr_t) buffers_kva + (bp - buf) * MAXBSIZE;
+ bp->b_data = bp->b_kvabase;
bufspace -= bp->b_bufsize;
bufmallocspace -= bp->b_bufsize;
bp->b_bufsize = 0;
diff --git a/sys/kern/vfs_cluster.c b/sys/kern/vfs_cluster.c
index 386d9813e5ed..d45663ad6a37 100644
--- a/sys/kern/vfs_cluster.c
+++ b/sys/kern/vfs_cluster.c
@@ -33,7 +33,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_cluster.c 8.7 (Berkeley) 2/13/94
- * $Id: vfs_cluster.c,v 1.37 1996/07/27 18:49:18 dyson Exp $
+ * $Id: vfs_cluster.c,v 1.38 1996/10/06 07:50:04 dyson Exp $
*/
#include <sys/param.h>
@@ -385,6 +385,10 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run)
VM_PAGE_BITS_ALL)
bp->b_pages[j] = bogus_page;
}
+ if (bp->b_bufsize > bp->b_kvasize)
+ panic("cluster_rbuild: b_bufsize(%d) > b_kvasize(%d)\n",
+ bp->b_bufsize, bp->b_kvasize);
+ bp->b_kvasize = bp->b_bufsize;
pmap_qenter(trunc_page((vm_offset_t) bp->b_data),
(vm_page_t *)bp->b_pages, bp->b_npages);
@@ -690,6 +694,10 @@ cluster_wbuild(vp, size, start_lbn, len)
}
pmap_qenter(trunc_page((vm_offset_t) bp->b_data),
(vm_page_t *) bp->b_pages, bp->b_npages);
+ if (bp->b_bufsize > bp->b_kvasize)
+ panic("cluster_wbuild: b_bufsize(%d) > b_kvasize(%d)\n",
+ bp->b_bufsize, bp->b_kvasize);
+ bp->b_kvasize = bp->b_bufsize;
totalwritten += bp->b_bufsize;
bp->b_dirtyoff = 0;
bp->b_dirtyend = bp->b_bufsize;
diff --git a/sys/sys/bio.h b/sys/sys/bio.h
index 3244a7e81a1c..ee7d2135e17a 100644
--- a/sys/sys/bio.h
+++ b/sys/sys/bio.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)buf.h 8.9 (Berkeley) 3/30/95
- * $Id: buf.h,v 1.33 1996/09/06 05:35:00 gibbs Exp $
+ * $Id: buf.h,v 1.34 1996/10/13 14:36:37 phk Exp $
*/
#ifndef _SYS_BUF_H_
@@ -80,6 +80,8 @@ struct buf {
struct {
caddr_t b_addr; /* Memory, superblocks, indirect etc. */
} b_un;
+ caddr_t b_kvabase; /* base kva for buffer */
+ int b_kvasize; /* size of kva for buffer */
void *b_saveaddr; /* Original b_addr for physio. */
daddr_t b_lblkno; /* Logical block number. */
daddr_t b_blkno; /* Underlying physical block number. */
diff --git a/sys/sys/buf.h b/sys/sys/buf.h
index 3244a7e81a1c..ee7d2135e17a 100644
--- a/sys/sys/buf.h
+++ b/sys/sys/buf.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)buf.h 8.9 (Berkeley) 3/30/95
- * $Id: buf.h,v 1.33 1996/09/06 05:35:00 gibbs Exp $
+ * $Id: buf.h,v 1.34 1996/10/13 14:36:37 phk Exp $
*/
#ifndef _SYS_BUF_H_
@@ -80,6 +80,8 @@ struct buf {
struct {
caddr_t b_addr; /* Memory, superblocks, indirect etc. */
} b_un;
+ caddr_t b_kvabase; /* base kva for buffer */
+ int b_kvasize; /* size of kva for buffer */
void *b_saveaddr; /* Original b_addr for physio. */
daddr_t b_lblkno; /* Logical block number. */
daddr_t b_blkno; /* Underlying physical block number. */
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 7e7a0372c453..60a16ac0c91e 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)param.h 8.3 (Berkeley) 4/4/95
- * $Id: param.h,v 1.15 1996/05/02 14:21:03 phk Exp $
+ * $Id: param.h,v 1.16 1996/11/28 04:07:44 dyson Exp $
*/
#ifndef _SYS_PARAM_H_
@@ -146,11 +146,8 @@
* it smaller make make some file systems unmountable. Also, MAXBSIZE
* must be less than MAXPHYS!!!
*/
-#if defined(MSDOSFS)
-#define MAXBSIZE 32768
-#else
-#define MAXBSIZE 16384
-#endif
+#define MAXBSIZE 65536
+#define DFLTBSIZE 8192
#define MAXFRAG 8
/*
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 1119c62d3850..f395d9701d7c 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -66,7 +66,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_fault.c,v 1.56 1996/07/30 03:08:07 dyson Exp $
+ * $Id: vm_fault.c,v 1.57 1996/09/08 20:44:37 dyson Exp $
*/
/*
@@ -81,6 +81,7 @@
#include <sys/signalvar.h>
#include <sys/resourcevar.h>
#include <sys/vmmeter.h>
+#include <sys/buf.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -103,10 +104,6 @@ int vm_fault_additional_pages __P((vm_page_t, int, int, vm_page_t *, int *));
#define VM_FAULT_READ_BEHIND 3
#define VM_FAULT_READ (VM_FAULT_READ_AHEAD+VM_FAULT_READ_BEHIND+1)
-int vm_fault_free_1;
-int vm_fault_copy_save_1;
-int vm_fault_copy_save_2;
-
/*
* vm_fault:
*
@@ -200,6 +197,11 @@ RetryFault:;
return (result);
}
+ if (entry->nofault) {
+ panic("vm_fault: fault on nofault entry, addr: %lx",
+ vaddr);
+ }
+
vp = vnode_pager_lock(first_object);
lookup_still_valid = TRUE;
@@ -565,7 +567,6 @@ readrest:
first_m = m;
m->dirty = VM_PAGE_BITS_ALL;
m = NULL;
- ++vm_fault_copy_save_1;
} else {
/*
* Oh, well, lets copy it.
@@ -639,7 +640,6 @@ readrest:
PAGE_WAKEUP(m);
vm_page_free(m);
m = NULL;
- ++vm_fault_free_1;
tm->dirty = VM_PAGE_BITS_ALL;
first_m->dirty = VM_PAGE_BITS_ALL;
}
@@ -651,7 +651,6 @@ readrest:
vm_page_rename(m, other_object, other_pindex);
m->dirty = VM_PAGE_BITS_ALL;
m->valid = VM_PAGE_BITS_ALL;
- ++vm_fault_copy_save_2;
}
}
}
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 5a04287a7480..48071a0daa57 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_map.c,v 1.56 1996/09/08 23:49:47 dyson Exp $
+ * $Id: vm_map.c,v 1.57 1996/09/14 11:54:55 bde Exp $
*/
/*
@@ -689,6 +689,11 @@ vm_map_insert(map, object, offset, start, end, prot, max, cow)
else
new_entry->copy_on_write = FALSE;
+ if (cow & MAP_NOFAULT)
+ new_entry->nofault = TRUE;
+ else
+ new_entry->nofault = FALSE;
+
if (map->is_main_map) {
new_entry->inheritance = VM_INHERIT_DEFAULT;
new_entry->protection = prot;
diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h
index fd04d87de264..40569ef0ed78 100644
--- a/sys/vm/vm_map.h
+++ b/sys/vm/vm_map.h
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_map.h,v 1.14 1996/07/27 03:23:59 dyson Exp $
+ * $Id: vm_map.h,v 1.15 1996/07/30 03:08:11 dyson Exp $
*/
/*
@@ -106,9 +106,9 @@ struct vm_map_entry {
vm_ooffset_t offset; /* offset into object */
boolean_t is_a_map:1, /* Is "object" a map? */
is_sub_map:1, /* Is "object" a submap? */
- /* Only in sharing maps: */
copy_on_write:1, /* is data copy-on-write */
- needs_copy:1; /* does object need to be copied */
+ needs_copy:1, /* does object need to be copied */
+ nofault:1; /* should never fault */
/* Only in task maps: */
vm_prot_t protection; /* protection code */
vm_prot_t max_protection; /* maximum protection */
@@ -208,6 +208,7 @@ typedef struct {
*/
#define MAP_COPY_NEEDED 0x1
#define MAP_COPY_ON_WRITE 0x2
+#define MAP_NOFAULT 0x4
#ifdef KERNEL
extern vm_offset_t kentry_data;
diff --git a/sys/vm/vm_pager.c b/sys/vm/vm_pager.c
index b8db9ac4cb9b..de81090bd6c0 100644
--- a/sys/vm/vm_pager.c
+++ b/sys/vm/vm_pager.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_pager.c,v 1.23 1996/05/18 03:38:05 dyson Exp $
+ * $Id: vm_pager.c,v 1.24 1996/09/08 20:44:49 dyson Exp $
*/
/*
@@ -278,6 +278,22 @@ pager_cache(object, should_cache)
}
/*
+ * initialize a physical buffer
+ */
+
+static void
+initpbuf(struct buf *bp) {
+ bzero(bp, sizeof *bp);
+ bp->b_rcred = NOCRED;
+ bp->b_wcred = NOCRED;
+ bp->b_qindex = QUEUE_NONE;
+ bp->b_data = (caddr_t) (MAXPHYS * (bp - swbuf)) + swapbkva;
+ bp->b_kvabase = bp->b_data;
+ bp->b_kvasize = MAXPHYS;
+ bp->b_vnbufs.le_next = NOLIST;
+}
+
+/*
* allocate a physical buffer
*/
struct buf *
@@ -295,12 +311,7 @@ getpbuf()
TAILQ_REMOVE(&bswlist, bp, b_freelist);
splx(s);
- bzero(bp, sizeof *bp);
- bp->b_rcred = NOCRED;
- bp->b_wcred = NOCRED;
- bp->b_qindex = QUEUE_NONE;
- bp->b_data = (caddr_t) (MAXPHYS * (bp - swbuf)) + swapbkva;
- bp->b_vnbufs.le_next = NOLIST;
+ initpbuf(bp);
return bp;
}
@@ -321,12 +332,8 @@ trypbuf()
TAILQ_REMOVE(&bswlist, bp, b_freelist);
splx(s);
- bzero(bp, sizeof *bp);
- bp->b_rcred = NOCRED;
- bp->b_wcred = NOCRED;
- bp->b_qindex = QUEUE_NONE;
- bp->b_data = (caddr_t) (MAXPHYS * (bp - swbuf)) + swapbkva;
- bp->b_vnbufs.le_next = NOLIST;
+ initpbuf(bp);
+
return bp;
}