Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 11 Jan 1998 13:19:38 -0500 (EST)
From:      "John S. Dyson" <dyson@FreeBSD.ORG>
To:        garyj@muc.de
Cc:        andreas@klemm.gtn.com, current@FreeBSD.ORG
Subject:   Re: strange errors with -current, compile problems ...
Message-ID:  <199801111819.NAA01653@dyson.iquest.net>
In-Reply-To: <199801111019.LAA26754@peedub.muc.de> from Gary Jennejohn at "Jan 11, 98 11:19:54 am"

next in thread | previous in thread | raw e-mail | index | archive | help

Gary Jennejohn said:
> Andreas Klemm writes:
> >I didn't get xmail compiled, imake terminated with signal 10 or
> >12. I could fix this only by doing a make world from -current
> >sources of last Monday.
> >
> >Now everything works fine again.
> >
> 
> I had the same problem (imake core dumping). I had to switch to a
> kernel from before John Dyson's latest commits. I can't swear that
> John's changes are the cause because I didn't pursue it any further.
> 
> I failed to "make world" after updating the kernel; this may be the
> cause of my problems.
> 
For a *fun time*, try my patches against -current below :-).  Let me
know if things are any better (if you can)...  I'll be committing
a large part of them today/tonight.

-- 
John                  | Never try to teach a pig to sing,
dyson@freebsd.org     | it just makes you look stupid,
jdyson@nc.com         | and it irritates the pig.


Index: i386/i386/pmap.c
===================================================================
RCS file: /local/home/ncvs/src/sys/i386/i386/pmap.c,v
retrieving revision 1.176
diff -C2 -r1.176 pmap.c
*** pmap.c	1997/12/22 10:06:09	1.176
--- pmap.c	1998/01/11 09:06:50
***************
*** 414,418 ****
  	/* 2 = local apic */
  	/* 16-31 = io apics */
! 	SMP_prvpt[2] = (pt_entry_t)(PG_V | PG_RW | pgeflag | ((u_long)cpu_apic_address & PG_FRAME));
  
  	for (i = 0; i < mp_napics; i++) {
--- 414,418 ----
  	/* 2 = local apic */
  	/* 16-31 = io apics */
! 	SMP_prvpt[2] = (pt_entry_t)(PG_V | PG_RW | PG_G | ((u_long)cpu_apic_address & PG_FRAME));
  
  	for (i = 0; i < mp_napics; i++) {
***************
*** 426,430 ****
  			/* use this slot if available */
  			if (((u_long)SMP_prvpt[j + 16] & PG_FRAME) == 0) {
! 				SMP_prvpt[j + 16] = (pt_entry_t)(PG_V | PG_RW | pgeflag |
  				    ((u_long)io_apic_address[i] & PG_FRAME));
  				ioapic[i] = (ioapic_t *)&SMP_ioapic[j * PAGE_SIZE];
--- 426,430 ----
  			/* use this slot if available */
  			if (((u_long)SMP_prvpt[j + 16] & PG_FRAME) == 0) {
! 				SMP_prvpt[j + 16] = (pt_entry_t)(PG_V | PG_RW | PG_G |
  				    ((u_long)io_apic_address[i] & PG_FRAME));
  				ioapic[i] = (ioapic_t *)&SMP_ioapic[j * PAGE_SIZE];
***************
*** 929,939 ****
--- 929,943 ----
  			panic("pmap_dispose_proc: upage already missing???");
  		*(ptek + i) = 0;
+ #if !defined(SMP)
  		if (cpu_class >= CPUCLASS_586)
  			invlpg((vm_offset_t) p->p_addr + i * PAGE_SIZE);
+ #endif
  		vm_page_unwire(m);
  		vm_page_free(m);
  	}
  
+ #if defined(SMP)
  	if (cpu_class < CPUCLASS_586)
+ #endif
  		invltlb();
  
***************
*** 996,1005 ****
  			m->flags |= PG_BUSY;
  		}
- 		vm_page_wire(m);
  		splx(s);
  
- 		pmap_kenter(((vm_offset_t) p->p_addr) + i * PAGE_SIZE,
- 			VM_PAGE_TO_PHYS(m));
- 
  		if (m->valid != VM_PAGE_BITS_ALL) {
  			int rv;
--- 1000,1005 ----
***************
*** 1009,1015 ****
--- 1009,1025 ----
  			m->valid = VM_PAGE_BITS_ALL;
  		}
+ 
+ 		vm_page_wire(m);
+ 
+ 		pmap_kenter(((vm_offset_t) p->p_addr) + i * PAGE_SIZE,
+ 			VM_PAGE_TO_PHYS(m));
+ 		if (cpu_class >= CPUCLASS_586)
+ 			invlpg((vm_offset_t) p->p_addr + i * PAGE_SIZE);
+ 
  		PAGE_WAKEUP(m);
  		m->flags |= PG_MAPPED|PG_WRITEABLE;
  	}
+ 	if (cpu_class < CPUCLASS_586)
+ 		invltlb();
  }
  
***************
*** 1932,1936 ****
  		}
  		if (!update_needed &&
! 			((!curproc || (&curproc->p_vmspace->vm_pmap == pv->pv_pmap)) ||
  			(pv->pv_pmap == kernel_pmap))) {
  			update_needed = 1;
--- 1942,1947 ----
  		}
  		if (!update_needed &&
! 			(((((unsigned)pv->pv_pmap->pm_pdir[PTDPTDI]) & PG_FRAME) ==
! 			(((unsigned) PTDpde) & PG_FRAME)) ||
  			(pv->pv_pmap == kernel_pmap))) {
  			update_needed = 1;
***************
*** 1945,1951 ****
  	ppv->pv_vm_page->flags &= ~(PG_MAPPED|PG_WRITEABLE);
  
- 
  	if (update_needed)
  		invltlb();
  	splx(s);
  	return;
--- 1956,1962 ----
  	ppv->pv_vm_page->flags &= ~(PG_MAPPED|PG_WRITEABLE);
  
  	if (update_needed)
  		invltlb();
+ 
  	splx(s);
  	return;
Index: i386/isa/wd.c
===================================================================
RCS file: /local/home/ncvs/src/sys/i386/isa/wd.c,v
retrieving revision 1.146
diff -C2 -r1.146 wd.c
*** wd.c	1997/12/06 14:27:20	1.146
--- wd.c	1998/01/11 07:09:00
***************
*** 206,210 ****
--- 206,212 ----
  	int	b_errcnt;
  	int	b_active;
+ 	int b_flags;	/* flags for blocking concurrent opens */
  } wdtab[NWDC];
+ #define WDC_OPENING 0x1
  
  struct wddma wddma[NWDC];
***************
*** 411,414 ****
--- 413,418 ----
  		return (0);
  
+ 	bzero(&wdtab[dvp->id_unit], sizeof wdtab[dvp->id_unit]);
+ 
  #ifdef CMD640
  	if (eide_quirks & Q_CMD640B) {
***************
*** 431,434 ****
--- 435,440 ----
  			continue;
  
+ 		bzero(&wdutab[lunit], sizeof wdutab[lunit]);
+ 
  		unit = wdup->id_physid;
  
***************
*** 1066,1069 ****
--- 1072,1076 ----
  	du = wddrives[dkunit(bp->b_dev)];
  
+ 	dmastat = 0;
  	/* finish off DMA */
  	if (du->dk_flags & (DKFL_DMA|DKFL_USEDMA)) {
***************
*** 1279,1283 ****
  	register unsigned int lunit;
  	register struct disk *du;
! 	int	error;
  
  	lunit = dkunit(dev);
--- 1286,1290 ----
  	register unsigned int lunit;
  	register struct disk *du;
! 	int s, error, ctrlr;
  
  	lunit = dkunit(dev);
***************
*** 1288,1299 ****
  		return (ENXIO);
  
- 	/* Finish flushing IRQs left over from wdattach(). */
  #ifdef CMD640
! 	if (wdtab[du->dk_ctrlr_cmd640].b_active == 2)
! 		wdtab[du->dk_ctrlr_cmd640].b_active = 0;
  #else
! 	if (wdtab[du->dk_ctrlr].b_active == 2)
! 		wdtab[du->dk_ctrlr].b_active = 0;
  #endif
  
  	du->dk_flags &= ~DKFL_BADSCAN;
--- 1295,1313 ----
  		return (ENXIO);
  
  #ifdef CMD640
! 	ctrlr = du->dk_ctrlr_cmd640;
  #else
! 	ctrlr = du->dk_ctrlr;
  #endif
+ 	s = splbio();
+ 	while (wdtab[ctrlr].b_flags & WDC_OPENING) {
+ 		tsleep(&wdtab[ctrlr].b_flags, PRIBIO, "wdcopn", 10);
+ 	}
+ 	wdtab[ctrlr].b_flags |= WDC_OPENING;
+ 	splx(s);
+ 
+ 	/* Finish flushing IRQs left over from wdattach(). */
+ 	if (wdtab[ctrlr].b_active == 2)
+ 		wdtab[ctrlr].b_active = 0;
  
  	du->dk_flags &= ~DKFL_BADSCAN;
***************
*** 1321,1324 ****
--- 1335,1341 ----
  	du->dk_flags &= ~DKFL_LABELLING;
  	wdsleep(du->dk_ctrlr, "wdopn2");
+ 
+ 	wdtab[ctrlr].b_flags &= ~WDC_OPENING;
+ 	wakeup(&wdtab[ctrlr].b_flags);
  	return (error);
  #else
***************
*** 1340,1343 ****
--- 1357,1362 ----
  		if (error != 0) {
  			du->dk_flags &= ~DKFL_LABELLING;
+ 			wdtab[ctrlr].b_flags &= ~WDC_OPENING;
+ 			wakeup(&wdtab[ctrlr].b_flags);
  			return (error);
  		}
***************
*** 1346,1349 ****
--- 1365,1370 ----
  		if (dkslice(dev) == WHOLE_DISK_SLICE) {
  			dsopen(dev, fmt, du->dk_slices);
+ 			wdtab[ctrlr].b_flags &= ~WDC_OPENING;
+ 			wakeup(&wdtab[ctrlr].b_flags);
  			return (0);
  		}
***************
*** 1376,1381 ****
  			log(LOG_WARNING, "wd%d: cannot find label (%s)\n",
  			    lunit, msg);
! 			if (part != RAW_PART)
  				return (EINVAL);  /* XXX needs translation */
  			/*
  			 * Soon return.  This is how slices without labels
--- 1397,1405 ----
  			log(LOG_WARNING, "wd%d: cannot find label (%s)\n",
  			    lunit, msg);
! 			if (part != RAW_PART) {
! 				wdtab[ctrlr].b_flags &= ~WDC_OPENING;
! 				wakeup(&wdtab[ctrlr].b_flags);
  				return (EINVAL);  /* XXX needs translation */
+ 			}
  			/*
  			 * Soon return.  This is how slices without labels
***************
*** 1439,1447 ****
  		}
  	}
! 	if (part >= du->dk_dd.d_npartitions && part != RAW_PART)
  		return (ENXIO);
  
  	dsopen(dev, fmt, du->dk_slices);
  
  	return (0);
  #endif
--- 1463,1476 ----
  		}
  	}
! 	if (part >= du->dk_dd.d_npartitions && part != RAW_PART) {
! 		wdtab[ctrlr].b_flags &= ~WDC_OPENING;
! 		wakeup(&wdtab[ctrlr].b_flags);
  		return (ENXIO);
+ 	}
  
  	dsopen(dev, fmt, du->dk_slices);
  
+ 	wdtab[ctrlr].b_flags &= ~WDC_OPENING;
+ 	wakeup(&wdtab[ctrlr].b_flags);
  	return (0);
  #endif
Index: kern/imgact_aout.c
===================================================================
RCS file: /local/home/ncvs/src/sys/kern/imgact_aout.c,v
retrieving revision 1.37
diff -C2 -r1.37 imgact_aout.c
*** imgact_aout.c	1998/01/06 05:15:25	1.37
--- imgact_aout.c	1998/01/07 07:45:43
***************
*** 37,40 ****
--- 37,41 ----
  #include <sys/sysent.h>
  #include <sys/vnode.h>
+ #include <sys/systm.h>
  
  #include <vm/vm.h>
***************
*** 44,47 ****
--- 45,49 ----
  #include <vm/pmap.h>
  #include <vm/vm_map.h>
+ #include <vm/vm_object.h>
  #include <vm/vm_extern.h>
  
***************
*** 54,58 ****
  	const struct exec *a_out = (const struct exec *) imgp->image_header;
  	struct vmspace *vmspace;
! 	vm_offset_t vmaddr;
  	unsigned long virtual_offset;
  	unsigned long file_offset;
--- 56,62 ----
  	const struct exec *a_out = (const struct exec *) imgp->image_header;
  	struct vmspace *vmspace;
! 	struct vnode *vp;
! 	vm_object_t object;
! 	vm_offset_t text_end, data_end;
  	unsigned long virtual_offset;
  	unsigned long file_offset;
***************
*** 146,187 ****
  	vmspace = imgp->proc->p_vmspace;
  
! 	/*
! 	 * Map text/data read/execute
! 	 */
! 	vmaddr = virtual_offset;
! 	error =
! 	    vm_mmap(&vmspace->vm_map,			/* map */
! 		&vmaddr,				/* address */
! 		a_out->a_text + a_out->a_data,		/* size */
! 		VM_PROT_READ | VM_PROT_EXECUTE,		/* protection */
! 		VM_PROT_ALL,				/* max protection */
! 		MAP_PRIVATE | MAP_FIXED,		/* flags */
! 		(caddr_t)imgp->vp,			/* vnode */
! 		file_offset);				/* offset */
  	if (error)
  		return (error);
  
! 	/*
! 	 * allow writing of data
! 	 */
! 	vm_map_protect(&vmspace->vm_map,
! 		vmaddr + a_out->a_text,
! 		vmaddr + a_out->a_text + a_out->a_data,
! 		VM_PROT_ALL,
! 		FALSE);
! 
! 	if (bss_size != 0) {
! 		/*
! 		 * Allocate demand-zeroed area for uninitialized data
! 		 * "bss" = 'block started by symbol' - named after the IBM 7090
! 		 *	instruction of the same name.
! 		 */
! 		vmaddr = virtual_offset + a_out->a_text + a_out->a_data;
! 		error = vm_map_find(&vmspace->vm_map, NULL, 0,
! 			&vmaddr, bss_size, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0);
  		if (error)
  			return (error);
  	}
  
  	/* Fill in process VM information */
  	vmspace->vm_tsize = a_out->a_text >> PAGE_SHIFT;
--- 150,190 ----
  	vmspace = imgp->proc->p_vmspace;
  
! 	vp = imgp->vp;
! 	object = vp->v_object;
! 	vm_object_reference(object);
! 
! 	text_end = virtual_offset + a_out->a_text;
! 	error = vm_map_insert(&vmspace->vm_map, object,
! 		file_offset,
! 		virtual_offset, text_end,
! 		VM_PROT_READ | VM_PROT_EXECUTE, VM_PROT_ALL,
! 		MAP_COPY_NEEDED | MAP_COPY_ON_WRITE);
  	if (error)
  		return (error);
  
! 	data_end = text_end + a_out->a_data;
! 	if (a_out->a_data) {
! 		vm_object_reference(object);
! 		error = vm_map_insert(&vmspace->vm_map, object,
! 			file_offset + a_out->a_text,
! 			text_end, data_end,
! 			VM_PROT_ALL, VM_PROT_ALL,
! 			MAP_COPY_NEEDED | MAP_COPY_ON_WRITE);
  		if (error)
  			return (error);
  	}
  
+ 	pmap_object_init_pt(&vmspace->vm_pmap, virtual_offset,
+ 		object, (vm_pindex_t) OFF_TO_IDX(file_offset),
+ 		a_out->a_text + a_out->a_data, 0);
+ 
+ 	if (bss_size) {
+ 		error = vm_map_insert(&vmspace->vm_map, NULL, 0,
+ 			data_end, data_end + bss_size,
+ 			VM_PROT_ALL, VM_PROT_ALL, 0);
+ 		if (error)
+ 			return (error);
+ 	}
+ 		
  	/* Fill in process VM information */
  	vmspace->vm_tsize = a_out->a_text >> PAGE_SHIFT;
Index: kern/kern_exec.c
===================================================================
RCS file: /local/home/ncvs/src/sys/kern/kern_exec.c,v
retrieving revision 1.73
diff -C2 -r1.73 kern_exec.c
*** kern_exec.c	1998/01/06 05:15:34	1.73
--- kern_exec.c	1998/01/07 07:41:25
***************
*** 55,58 ****
--- 55,59 ----
  #include <sys/lock.h>
  #include <vm/pmap.h>
+ #include <vm/vm_page.h>
  #include <vm/vm_map.h>
  #include <vm/vm_kern.h>
***************
*** 60,63 ****
--- 61,66 ----
  #include <vm/vm_object.h>
  #include <vm/vm_zone.h>
+ #include <vm/vm_pager.h>
+ #include <vm/vm_pageout.h>
  
  #include <machine/reg.h>
***************
*** 65,69 ****
  static int *exec_copyout_strings __P((struct image_params *));
  
! static int exec_check_permissions(struct image_params *);
  
  /*
--- 68,74 ----
  static int *exec_copyout_strings __P((struct image_params *));
  
! static int exec_check_permissions __P((struct image_params *));
! static int exec_map_first_page __P((struct image_params *));
! static void exec_unmap_first_page __P((struct image_params *));
  
  /*
***************
*** 115,119 ****
  	imgp->uap = uap;
  	imgp->attr = &attr;
- 	imgp->image_header = NULL;
  	imgp->argc = imgp->envc = 0;
  	imgp->argv0 = NULL;
--- 120,123 ----
***************
*** 123,126 ****
--- 127,132 ----
  	imgp->interpreter_name[0] = '\0';
  	imgp->auxargs = NULL;
+ 	imgp->vp = NULL;
+ 	imgp->firstpage = NULL;
  
  	/*
***************
*** 128,132 ****
  	 *	environment strings
  	 */
! 	imgp->stringbase = (char *)kmem_alloc_wait(exec_map, ARG_MAX);
  	if (imgp->stringbase == NULL) {
  		error = ENOMEM;
--- 134,138 ----
  	 *	environment strings
  	 */
! 	imgp->stringbase = (char *)kmem_alloc_wait(exec_map, ARG_MAX + PAGE_SIZE);
  	if (imgp->stringbase == NULL) {
  		error = ENOMEM;
***************
*** 135,138 ****
--- 141,145 ----
  	imgp->stringp = imgp->stringbase;
  	imgp->stringspace = ARG_MAX;
+ 	imgp->image_header = imgp->stringbase + ARG_MAX;
  
  	/*
***************
*** 148,152 ****
  	error = namei(ndp);
  	if (error) {
! 		kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase, ARG_MAX);
  		goto exec_fail;
  	}
--- 155,160 ----
  	error = namei(ndp);
  	if (error) {
! 		kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase,
! 			ARG_MAX + PAGE_SIZE);
  		goto exec_fail;
  	}
***************
*** 163,198 ****
  	}
  
! 	/*
! 	 * Get the image header, which we define here as meaning the first
! 	 * page of the executable.
! 	 */
! 	if (imgp->vp->v_object && imgp->vp->v_mount &&
! 	    imgp->vp->v_mount->mnt_stat.f_iosize >= PAGE_SIZE &&
! 	    imgp->vp->v_object->un_pager.vnp.vnp_size >=
! 	    imgp->vp->v_mount->mnt_stat.f_iosize) {
! 		/*
! 		 * Get a buffer with (at least) the first page.
! 		 */
! 		error = bread(imgp->vp, 0, imgp->vp->v_mount->mnt_stat.f_iosize,
! 		     p->p_ucred, &bp);
! 		imgp->image_header = bp->b_data;
! 	} else {
! 		int resid;
! 
! 		/*
! 		 * The filesystem block size is too small, so do this the hard
! 		 * way. Malloc some space and read PAGE_SIZE worth of the image
! 		 * header into it.
! 		 */
! 		imgp->image_header = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
! 		error = vn_rdwr(UIO_READ, imgp->vp,
! 			(void *)imgp->image_header, PAGE_SIZE, 0,
! 		    UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid, p);
! 		/*
! 		 * Clear out any remaining junk.
! 		 */
! 		if (!error && resid)
! 			bzero((char *)imgp->image_header + PAGE_SIZE - resid, resid);
! 	}
  	VOP_UNLOCK(imgp->vp, 0, p);
  	if (error)
--- 171,175 ----
  	}
  
! 	error = exec_map_first_page(imgp);
  	VOP_UNLOCK(imgp->vp, 0, p);
  	if (error)
***************
*** 217,227 ****
  			goto exec_fail_dealloc;
  		if (imgp->interpreted) {
! 			/* free old bp/image_header */
! 			if (bp != NULL) {
! 				brelse(bp);
! 				bp = NULL;
! 			} else
! 				free((void *)imgp->image_header, M_TEMP);
! 			imgp->image_header = NULL;
  			/* free old vnode and name buffer */
  			vrele(ndp->ni_vp);
--- 194,198 ----
  			goto exec_fail_dealloc;
  		if (imgp->interpreted) {
! 			exec_unmap_first_page(imgp);
  			/* free old vnode and name buffer */
  			vrele(ndp->ni_vp);
***************
*** 352,375 ****
  	setregs(p, imgp->entry_addr, (u_long)stack_base);
  
  	/*
  	 * free various allocated resources
  	 */
! 	kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase, ARG_MAX);
! 	if (bp != NULL)
! 		brelse(bp);
! 	else if (imgp->image_header != NULL)
! 		free((void *)imgp->image_header, M_TEMP);
! 	vrele(ndp->ni_vp);
! 	zfree(namei_zone, ndp->ni_cnd.cn_pnbuf);
  
- 	return (0);
- 
- exec_fail_dealloc:
  	if (imgp->stringbase != NULL)
! 		kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase, ARG_MAX);
! 	if (bp != NULL)
! 		brelse(bp);
! 	else if (imgp->image_header != NULL)
! 		free((void *)imgp->image_header, M_TEMP);
  	if (ndp->ni_vp) {
  		vrele(ndp->ni_vp);
--- 323,338 ----
  	setregs(p, imgp->entry_addr, (u_long)stack_base);
  
+ exec_fail_dealloc:
+ 
  	/*
  	 * free various allocated resources
  	 */
! 	if (imgp->firstpage)
! 		exec_unmap_first_page(imgp);
  
  	if (imgp->stringbase != NULL)
! 		kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase,
! 			ARG_MAX + PAGE_SIZE);
! 
  	if (ndp->ni_vp) {
  		vrele(ndp->ni_vp);
***************
*** 377,380 ****
--- 340,346 ----
  	}
  
+ 	if (error == 0)
+ 		return (0);
+ 
  exec_fail:
  	if (imgp->vmspace_destroyed) {
***************
*** 388,391 ****
--- 354,422 ----
  }
  
+ int
+ exec_map_first_page(imgp)
+ 	struct image_params *imgp;
+ {
+ 	int s;
+ 	vm_page_t m;
+ 	vm_object_t object;
+ 
+ 
+ 	if (imgp->firstpage) {
+ 		exec_unmap_first_page(imgp);
+ 	}
+ 
+ 	object = imgp->vp->v_object;
+ 	s = splvm();
+ 
+ retry:
+ 	m = vm_page_lookup(object, 0);
+ 	if (m == NULL) {
+ 		m = vm_page_alloc(object, 0, VM_ALLOC_NORMAL);
+ 		if (m == NULL) {
+ 			VM_WAIT;
+ 			goto retry;
+ 		}
+ 	} else if ((m->flags & PG_BUSY) || m->busy) {
+ 		m->flags |= PG_WANTED;
+ 		tsleep(m, PVM, "execpw", 0);
+ 		goto retry;
+ 	}
+ 
+ 	m->flags |= PG_BUSY;
+ 
+ 	if ((m->valid & VM_PAGE_BITS_ALL) != VM_PAGE_BITS_ALL) {
+ 		int rv;
+ 		rv = vm_pager_get_pages(object, &m, 1, 0);
+ 		if (rv != VM_PAGER_OK) {
+ 			vm_page_protect(m, VM_PROT_NONE);
+ 			vm_page_deactivate(m);
+ 			PAGE_WAKEUP(m);
+ 			splx(s);
+ 			return EIO;
+ 		}
+ 	}
+ 
+ 	vm_page_wire(m);
+ 	PAGE_WAKEUP(m);
+ 	splx(s);
+ 
+ 	pmap_kenter((vm_offset_t) imgp->image_header, VM_PAGE_TO_PHYS(m));
+ 	imgp->firstpage = m;
+ 
+ 	return 0;
+ }
+ 
+ void
+ exec_unmap_first_page(imgp)
+ 	struct image_params *imgp;
+ {
+ 	if (imgp->firstpage) {
+ 		pmap_kremove((vm_offset_t) imgp->image_header);
+ 		vm_page_unwire(imgp->firstpage);
+ 		imgp->firstpage = NULL;
+ 	}
+ }
+ 
  /*
   * Destroy old address space, and allocate a new stack
***************
*** 421,428 ****
  
  	/* Allocate a new stack */
! 	error = vm_map_find(map, NULL, 0, (vm_offset_t *)&stack_addr,
! 	    SGROWSIZ, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0);
  	if (error)
! 		return(error);
  
  	vmspace->vm_ssize = SGROWSIZ >> PAGE_SHIFT;
--- 452,460 ----
  
  	/* Allocate a new stack */
! 	error = vm_map_insert(&vmspace->vm_map, NULL, 0,
! 		(vm_offset_t) stack_addr, (vm_offset_t) USRSTACK,
! 		VM_PROT_ALL, VM_PROT_ALL, 0);
  	if (error)
! 		return (error);
  
  	vmspace->vm_ssize = SGROWSIZ >> PAGE_SHIFT;
Index: kern/vfs_subr.c
===================================================================
RCS file: /local/home/ncvs/src/sys/kern/vfs_subr.c,v
retrieving revision 1.121
diff -C2 -r1.121 vfs_subr.c
*** vfs_subr.c	1998/01/07 09:26:29	1.121
--- vfs_subr.c	1998/01/11 04:48:53
***************
*** 108,112 ****
  SYSCTL_INT(_debug, OID_AUTO, freevnodes, CTLFLAG_RD, &freevnodes, 0, "");
  
! int vfs_ioopt = 0;
  SYSCTL_INT(_vfs, OID_AUTO, ioopt, CTLFLAG_RW, &vfs_ioopt, 0, "");
  
--- 108,112 ----
  SYSCTL_INT(_debug, OID_AUTO, freevnodes, CTLFLAG_RD, &freevnodes, 0, "");
  
! int vfs_ioopt = 2;
  SYSCTL_INT(_vfs, OID_AUTO, ioopt, CTLFLAG_RW, &vfs_ioopt, 0, "");
  
***************
*** 351,356 ****
  	struct vnode **vpp;
  {
  	struct proc *p = curproc;	/* XXX */
! 	struct vnode *vp, *tvp;
  	vm_object_t object;
  	TAILQ_HEAD(freelst, vnode) vnode_tmp_list;
--- 351,357 ----
  	struct vnode **vpp;
  {
+ 	int s;
  	struct proc *p = curproc;	/* XXX */
! 	struct vnode *vp, *tvp, *nvp;
  	vm_object_t object;
  	TAILQ_HEAD(freelst, vnode) vnode_tmp_list;
***************
*** 363,366 ****
--- 364,368 ----
  	 */
  
+ 	s = splbio();
  	simple_lock(&vnode_free_list_slock);
  	TAILQ_INIT(&vnode_tmp_list);
***************
*** 374,378 ****
  		vp = NULL;
  	} else {
! 		TAILQ_FOREACH(vp, &vnode_free_list, v_freelist) {
  			if (!simple_lock_try(&vp->v_interlock)) 
  				continue;
--- 376,383 ----
  		vp = NULL;
  	} else {
! 		for (vp = TAILQ_FIRST(&vnode_free_list); vp; vp = nvp) {
! 
! 			nvp = TAILQ_NEXT(vp, v_freelist);
! 
  			if (!simple_lock_try(&vp->v_interlock)) 
  				continue;
***************
*** 396,400 ****
  	}
  
! 	TAILQ_FOREACH(tvp, &vnode_tmp_list, v_freelist) {
  		TAILQ_REMOVE(&vnode_tmp_list, tvp, v_freelist);
  		TAILQ_INSERT_TAIL(&vnode_free_list, tvp, v_freelist);
--- 401,406 ----
  	}
  
! 	for (tvp = TAILQ_FIRST(&vnode_tmp_list); tvp; tvp = nvp) {
! 		nvp = TAILQ_NEXT(tvp, v_freelist);
  		TAILQ_REMOVE(&vnode_tmp_list, tvp, v_freelist);
  		TAILQ_INSERT_TAIL(&vnode_free_list, tvp, v_freelist);
***************
*** 455,458 ****
--- 461,465 ----
  	vp->v_usecount = 1;
  	vp->v_data = 0;
+ 	splx(s);
  	return (0);
  }
***************
*** 1417,1421 ****
  	if (vp->v_usecount == 0 && !(vp->v_flag & VDOOMED)) {
  		simple_lock(&vnode_free_list_slock);
! 		TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
  		TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_freelist);
  		simple_unlock(&vnode_free_list_slock);
--- 1424,1430 ----
  	if (vp->v_usecount == 0 && !(vp->v_flag & VDOOMED)) {
  		simple_lock(&vnode_free_list_slock);
! 		if (vp->v_flag & VFREE) {
! 			TAILQ_REMOVE(&vnode_free_list, vp, v_freelist);
! 		}
  		TAILQ_INSERT_HEAD(&vnode_free_list, vp, v_freelist);
  		simple_unlock(&vnode_free_list_slock);
Index: kern/vfs_vnops.c
===================================================================
RCS file: /local/home/ncvs/src/sys/kern/vfs_vnops.c,v
retrieving revision 1.46
diff -C2 -r1.46 vfs_vnops.c
*** vfs_vnops.c	1998/01/06 05:16:32	1.46
--- vfs_vnops.c	1998/01/11 06:26:07
***************
*** 512,518 ****
  			vp->v_flag |= VXWANT;
  			simple_unlock(&vp->v_interlock);
! 			if (tsleep((caddr_t)vp, PINOD, "vn_lock", 120*hz)) {
! 				vprint("vn_lock: timeout:", vp);
! 			}
  			error = ENOENT;
  		} else {
--- 512,516 ----
  			vp->v_flag |= VXWANT;
  			simple_unlock(&vp->v_interlock);
! 			tsleep((caddr_t)vp, PINOD, "vn_lock", 0);
  			error = ENOENT;
  		} else {
Index: sys/imgact.h
===================================================================
RCS file: /local/home/ncvs/src/sys/sys/imgact.h,v
retrieving revision 1.15
diff -C2 -r1.15 imgact.h
*** imgact.h	1997/04/23 22:02:37	1.15
--- imgact.h	1998/01/07 07:41:39
***************
*** 53,56 ****
--- 53,57 ----
  	char interpreter_name[64]; /* name of the interpreter */
  	void *auxargs;		/* ELF Auxinfo structure pointer */
+ 	struct vm_page *firstpage;	/* first page that we mapped */
  };
  
Index: sys/vnode.h
===================================================================
RCS file: /local/home/ncvs/src/sys/sys/vnode.h,v
retrieving revision 1.63
diff -C2 -r1.63 vnode.h
*** vnode.h	1998/01/06 05:23:04	1.63
--- vnode.h	1998/01/07 05:55:19
***************
*** 274,285 ****
  extern void	(*lease_updatetime) __P((int deltat));
  
  #define VSHOULDFREE(vp)	\
  	(!((vp)->v_flag & (VFREE|VDOOMED)) && \
  	 !(vp)->v_holdcnt && !(vp)->v_usecount)
  
  #define VSHOULDBUSY(vp)	\
  	(((vp)->v_flag & VFREE) && \
  	 ((vp)->v_holdcnt || (vp)->v_usecount))
- 
  
  #endif /* KERNEL */
--- 274,292 ----
  extern void	(*lease_updatetime) __P((int deltat));
  
+ #if 1
+ #define VSHOULDFREE(vp)	\
+ 	(!((vp)->v_flag & (VFREE|VDOOMED)) && \
+ 	 !(vp)->v_holdcnt && !(vp)->v_usecount && \
+ 	 (!(vp)->v_object || \
+ 	  !((vp)->v_object->ref_count || (vp)->v_object->resident_page_count)))
+ #else
  #define VSHOULDFREE(vp)	\
  	(!((vp)->v_flag & (VFREE|VDOOMED)) && \
  	 !(vp)->v_holdcnt && !(vp)->v_usecount)
+ #endif
  
  #define VSHOULDBUSY(vp)	\
  	(((vp)->v_flag & VFREE) && \
  	 ((vp)->v_holdcnt || (vp)->v_usecount))
  
  #endif /* KERNEL */
Index: vm/vm_fault.c
===================================================================
RCS file: /local/home/ncvs/src/sys/vm/vm_fault.c,v
retrieving revision 1.73
diff -C2 -r1.73 vm_fault.c
*** vm_fault.c	1998/01/06 05:25:54	1.73
--- vm_fault.c	1998/01/06 08:05:58
***************
*** 524,529 ****
--- 524,531 ----
  	}
  
+ #if defined(DIAGNOSTIC)
  	if ((m->flags & PG_BUSY) == 0)
  		panic("vm_fault: not busy after main loop");
+ #endif
  
  	/*
Index: vm/vm_map.c
===================================================================
RCS file: /local/home/ncvs/src/sys/vm/vm_map.c,v
retrieving revision 1.104
diff -C2 -r1.104 vm_map.c
*** vm_map.c	1998/01/06 05:25:58	1.104
--- vm_map.c	1998/01/11 04:43:10
***************
*** 2406,2410 ****
  	}
  
! 	if (entry->object.vm_object != NULL)
  		default_pager_convert_to_swapq(entry->object.vm_object);
  	/*
--- 2406,2410 ----
  	}
  
! 	if (entry->object.vm_object->type == OBJT_DEFAULT)
  		default_pager_convert_to_swapq(entry->object.vm_object);
  	/*
***************
*** 2480,2493 ****
  	vm_pindex_t first_pindex, osize, oindex;
  	off_t ooffset;
  
  	if (npages)
  		*npages = 0;
  
  	while (cnt > 0) {
  		map = mapa;
  		uaddr = uaddra;
  
  		if ((vm_map_lookup(&map, uaddr,
! 			VM_PROT_READ|VM_PROT_WRITE, &first_entry, &first_object,
  			&first_pindex, &prot, &wired, &su)) != KERN_SUCCESS) {
  			return EFAULT;
--- 2480,2497 ----
  	vm_pindex_t first_pindex, osize, oindex;
  	off_t ooffset;
+ 	int skipinit, allremoved;
  
  	if (npages)
  		*npages = 0;
  
+ 	allremoved = 0;
+ 
  	while (cnt > 0) {
  		map = mapa;
  		uaddr = uaddra;
+ 		skipinit = 0;
  
  		if ((vm_map_lookup(&map, uaddr,
! 			VM_PROT_READ, &first_entry, &first_object,
  			&first_pindex, &prot, &wired, &su)) != KERN_SUCCESS) {
  			return EFAULT;
***************
*** 2507,2521 ****
  		osize = atop(tcnt);
  
  		if (npages) {
! 			vm_pindex_t src_index, idx;
! 			src_index = OFF_TO_IDX(cp);
  			for (idx = 0; idx < osize; idx++) {
  				vm_page_t m;
! 				if ((m = vm_page_lookup(srcobject, src_index + idx)) == NULL) {
  					vm_map_lookup_done(map, first_entry);
  					return 0;
  				}
! 				if ((m->flags & PG_BUSY) || m->busy ||
! 					m->hold_count || m->wire_count ||
  					((m->valid & VM_PAGE_BITS_ALL) != VM_PAGE_BITS_ALL)) {
  					vm_map_lookup_done(map, first_entry);
--- 2511,2524 ----
  		osize = atop(tcnt);
  
+ 		oindex = OFF_TO_IDX(cp);
  		if (npages) {
! 			vm_pindex_t idx;
  			for (idx = 0; idx < osize; idx++) {
  				vm_page_t m;
! 				if ((m = vm_page_lookup(srcobject, oindex + idx)) == NULL) {
  					vm_map_lookup_done(map, first_entry);
  					return 0;
  				}
! 				if ((m->flags & PG_BUSY) ||
  					((m->valid & VM_PAGE_BITS_ALL) != VM_PAGE_BITS_ALL)) {
  					vm_map_lookup_done(map, first_entry);
***************
*** 2525,2554 ****
  		}
  
- 		oindex = OFF_TO_IDX(first_entry->offset);
- 
  /*
   * If we are changing an existing map entry, just redirect
   * the object, and change mappings.
   */
! 		if ((first_object->ref_count == 1) &&
! 			(first_object->backing_object == srcobject) &&
  			(first_object->size == osize) &&
  			(first_object->resident_page_count == 0)) {
  
! 			/*
! 			 * Remove old window into the file
! 			 */
! 			pmap_remove (map->pmap, start, end);
! 
! 			/*
! 			 * Force copy on write for mmaped regions
! 			 */
! 			vm_object_pmap_copy_1 (first_object,
! 				oindex, oindex + osize);
  
! 			/*
! 			 * Point the object appropriately
! 			 */
! 			first_object->backing_object_offset = cp;
  /*
   * Otherwise, we have to do a logical mmap.
--- 2528,2625 ----
  		}
  
  /*
   * If we are changing an existing map entry, just redirect
   * the object, and change mappings.
   */
! 		if (first_object->type == OBJT_VNODE) {
! 
! 			if (first_object != srcobject) {
! 
! 				vm_object_deallocate(first_object);
! 				srcobject->flags |= OBJ_OPT;
! 				vm_object_reference(srcobject);
! 
! 				first_entry->object.vm_object = srcobject;
! 				first_entry->offset = cp;
! 
! 			} else if (first_entry->offset != cp) {
! 
! 				first_entry->offset = cp;
! 
! 			} else {
! 
! 				skipinit = 1;
! 
! 			}
! 
! 			if (skipinit == 0) {
! 				/*
!    				* Remove old window into the file
!    				*/
! 				if (!allremoved) {
! 					pmap_remove (map->pmap, uaddra, uaddra + cnt);
! 					allremoved = 1;
! 				}
! 
! 				/*
!    				* Force copy on write for mmaped regions
!    				*/
! 				vm_object_pmap_copy_1 (srcobject,
! 					oindex, oindex + osize);
! 			}
! 			
! 		} else if ((first_object->ref_count == 1) &&
  			(first_object->size == osize) &&
  			(first_object->resident_page_count == 0)) {
+ 			vm_object_t oldobject;
  
! 			oldobject = first_object->backing_object;
! 
! 			if ((first_object->backing_object_offset != cp) ||
! 				(oldobject != srcobject)) {
! 				/*
!    				* Remove old window into the file
!    				*/
! 				if (!allremoved) {
! 					pmap_remove (map->pmap, uaddra, uaddra + cnt);
! 					allremoved = 1;
! 				}
! 
! 				/*
!    				* Force copy on write for mmaped regions
!    				*/
! 				vm_object_pmap_copy_1 (srcobject,
! 					oindex, oindex + osize);
! 
! 				/*
!    				* Point the object appropriately
!    				*/
! 				if (oldobject != srcobject) {
! 				/*
!    				* Set the object optimization hint flag
!    				*/
! 					srcobject->flags |= OBJ_OPT;
! 					vm_object_reference(srcobject);
! 
! 					if (oldobject) {
! 						TAILQ_REMOVE(&oldobject->shadow_head,
! 							first_object, shadow_list);
! 						oldobject->shadow_count--;
! 						if (oldobject->shadow_count == 0)
! 							oldobject->flags &= ~OBJ_OPT;
! 						vm_object_deallocate(oldobject);
! 					}
! 
! 					TAILQ_INSERT_TAIL(&srcobject->shadow_head,
! 						first_object, shadow_list);
! 					srcobject->shadow_count++;
! 
! 					first_object->backing_object = srcobject;
! 				}
  
! 				first_object->backing_object_offset = cp;
! 			} else {
! 				skipinit = 1;
! 			}
  /*
   * Otherwise, we have to do a logical mmap.
***************
*** 2556,2568 ****
  		} else {
  
! 			object = srcobject;
! 			object->flags |= OBJ_OPT;
! 			vm_object_reference(object);
! 			ooffset = cp;
! 
! 			vm_object_shadow(&object, &ooffset, osize);
  
! 			pmap_remove (map->pmap, start, end);
! 			vm_object_pmap_copy_1 (first_object,
  				oindex, oindex + osize);
  			vm_map_lookup_done(map, first_entry);
--- 2627,2638 ----
  		} else {
  
! 			srcobject->flags |= OBJ_OPT;
! 			vm_object_reference(srcobject);
  
! 			if (!allremoved) {
! 				pmap_remove (map->pmap, uaddra, uaddra + cnt);
! 				allremoved = 1;
! 			}
! 			vm_object_pmap_copy_1 (srcobject,
  				oindex, oindex + osize);
  			vm_map_lookup_done(map, first_entry);
***************
*** 2579,2584 ****
  			vm_map_entry_delete(map, first_entry);
  
! 			rv = vm_map_insert(map, object, 0, start, end,
! 				VM_PROT_ALL, VM_PROT_ALL, MAP_COPY_ON_WRITE);
  
  			if (rv != KERN_SUCCESS)
--- 2649,2654 ----
  			vm_map_entry_delete(map, first_entry);
  
! 			rv = vm_map_insert(map, srcobject, cp, start, end,
! 				VM_PROT_ALL, VM_PROT_ALL, MAP_COPY_ON_WRITE | MAP_COPY_NEEDED);
  
  			if (rv != KERN_SUCCESS)
***************
*** 2589,2594 ****
   * Map the window directly, if it is already in memory
   */
! 		pmap_object_init_pt(map->pmap, start,
! 			srcobject, (vm_pindex_t) OFF_TO_IDX(cp), end - start, 1);
  
  		vm_map_unlock(map);
--- 2659,2665 ----
   * Map the window directly, if it is already in memory
   */
! 		if (!skipinit)
! 			pmap_object_init_pt(map->pmap, start,
! 				srcobject, (vm_pindex_t) OFF_TO_IDX(cp), end - start, 0);
  
  		vm_map_unlock(map);
***************
*** 2664,2671 ****
--- 2735,2746 ----
  
  		vm_object_reference(robject);
+ 
+ 		s = splvm();
  		while (robject->paging_in_progress) {
  			robject->flags |= OBJ_PIPWNT;
  			tsleep(robject, PVM, "objfrz", 0);
  		}
+ 		splx(s);
+ 
  		if (robject->ref_count == 1) {
  			vm_object_deallocate(robject);
***************
*** 2691,2695 ****
  
  			if( m_in->flags & PG_BUSY) {
! 				s = splhigh();
  				while (m_in && (m_in->flags & PG_BUSY)) {
  					m_in->flags |= PG_WANTED;
--- 2766,2770 ----
  
  			if( m_in->flags & PG_BUSY) {
! 				s = splvm();
  				while (m_in && (m_in->flags & PG_BUSY)) {
  					m_in->flags |= PG_WANTED;
***************
*** 2706,2710 ****
  			m_out = vm_page_lookup(robject, dstpindex);
  			if( m_out && (m_out->flags & PG_BUSY)) {
! 				s = splhigh();
  				while (m_out && (m_out->flags & PG_BUSY)) {
  					m_out->flags |= PG_WANTED;
--- 2781,2785 ----
  			m_out = vm_page_lookup(robject, dstpindex);
  			if( m_out && (m_out->flags & PG_BUSY)) {
! 				s = splvm();
  				while (m_out && (m_out->flags & PG_BUSY)) {
  					m_out->flags |= PG_WANTED;
***************
*** 2734,2737 ****
--- 2809,2813 ----
  
  		if (((from - bo_pindex) == 0) && ((to - bo_pindex) == robject->size)) {
+ 
  			object->shadow_count--;
  
Index: vm/vm_object.c
===================================================================
RCS file: /local/home/ncvs/src/sys/vm/vm_object.c,v
retrieving revision 1.105
diff -C2 -r1.105 vm_object.c
*** vm_object.c	1998/01/07 03:12:19	1.105
--- vm_object.c	1998/01/11 07:56:56
***************
*** 333,336 ****
--- 333,337 ----
  						robject->flags |= OBJ_PIPWNT;
  						tsleep(robject, PVM, "objde1", 0);
+ 						splx(s);
  						goto retry;
  					}
***************
*** 339,342 ****
--- 340,344 ----
  						object->flags |= OBJ_PIPWNT;
  						tsleep(object, PVM, "objde2", 0);
+ 						splx(s);
  						goto retry;
  					}
Index: vm/vm_page.c
===================================================================
RCS file: /local/home/ncvs/src/sys/vm/vm_page.c,v
retrieving revision 1.84
diff -C2 -r1.84 vm_page.c
*** vm_page.c	1997/12/29 00:24:58	1.84
--- vm_page.c	1998/01/11 07:59:09
***************
*** 754,757 ****
--- 754,758 ----
  	register vm_page_t m;
  	struct vpgqueues *pq;
+ 	vm_object_t oldobject;
  	int queue, qtype;
  	int s;
***************
*** 862,868 ****
--- 863,871 ----
  	--(*pq->cnt);
  	--(*pq->lcnt);
+ 	oldobject = NULL;
  	if (qtype == PQ_ZERO) {
  		m->flags = PG_ZERO|PG_BUSY;
  	} else if (qtype == PQ_CACHE) {
+ 		oldobject = m->object;
  		vm_page_remove(m);
  		m->flags = PG_BUSY;
***************
*** 892,895 ****
--- 895,911 ----
  		pagedaemon_wakeup();
  
+ 	if (((page_req == VM_ALLOC_NORMAL) || (page_req == VM_ALLOC_ZERO)) &&
+ 		oldobject &&
+ 		((oldobject->type == OBJT_VNODE) &&
+ 		 (oldobject->ref_count == 0) &&
+ 		 (oldobject->resident_page_count == 0))) {
+ 		struct vnode *vp;
+ 		vp = (struct vnode *) oldobject->handle;
+ 		if (VSHOULDFREE(vp)) {
+ 			vm_object_reference(oldobject);
+ 			vm_object_vndeallocate(oldobject);
+ 		}
+ 	}
+ 
  	return (m);
  }
***************
*** 955,958 ****
--- 971,975 ----
  	vm_page_t m;
  {
+ #if !defined(MAX_PERF)
  	if (m->busy ||
  		(m->flags & PG_BUSY) ||
***************
*** 967,970 ****
--- 984,988 ----
  			panic("vm_page_free: freeing busy page");
  	}
+ #endif
  
  	vm_page_remove(m);
Index: vm/vm_pageout.c
===================================================================
RCS file: /local/home/ncvs/src/sys/vm/vm_pageout.c,v
retrieving revision 1.106
diff -C2 -r1.106 vm_pageout.c
*** vm_pageout.c	1998/01/06 05:26:11	1.106
--- vm_pageout.c	1998/01/07 02:36:12
***************
*** 593,596 ****
--- 593,614 ----
  #endif
  
+ void
+ vm_pageout_page_free(vm_page_t m) {
+ 	vm_object_t objref = NULL;
+ 
+ 	m->flags |= PG_BUSY;
+ 	if (m->object->type == OBJT_VNODE) {
+ 		objref = m->object;
+ 		vm_object_reference(objref);
+ 	}
+ 	vm_page_protect(m, VM_PROT_NONE);
+ 	PAGE_WAKEUP(m);
+ 	vm_page_free(m);
+ 	cnt.v_dfree++;
+ 	if (objref) {
+ 		vm_object_vndeallocate(objref);
+ 	}
+ }
+ 
  /*
   *	vm_pageout_scan does the dirty work for the pageout daemon.
***************
*** 717,723 ****
  		 */
  		if (m->valid == 0) {
! 			vm_page_protect(m, VM_PROT_NONE);
! 			vm_page_free(m);
! 			cnt.v_dfree++;
  			++pages_freed;
  
--- 735,739 ----
  		 */
  		if (m->valid == 0) {
! 			vm_pageout_page_free(m);
  			++pages_freed;
  
***************
*** 954,959 ****
  			break;
  		cache_rover = (cache_rover + PQ_PRIME2) & PQ_L2_MASK;
! 		vm_page_free(m);
! 		cnt.v_dfree++;
  	}
  	splx(s);
--- 970,974 ----
  			break;
  		cache_rover = (cache_rover + PQ_PRIME2) & PQ_L2_MASK;
! 		vm_pageout_page_free(m);
  	}
  	splx(s);
Index: vm/vm_pageout.h
===================================================================
RCS file: /local/home/ncvs/src/sys/vm/vm_pageout.h,v
retrieving revision 1.21
diff -C2 -r1.21 vm_pageout.h
*** vm_pageout.h	1997/12/06 02:23:36	1.21
--- vm_pageout.h	1998/01/06 20:46:59
***************
*** 106,109 ****
--- 106,110 ----
  void vm_pageout_cluster __P((vm_page_t, vm_object_t));
  int vm_pageout_flush __P((vm_page_t *, int, int));
+ void vm_pageout_page_free __P((vm_page_t));
  
  #endif



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199801111819.NAA01653>