From 4f699173cb6857c91138afda709896a50200f434 Mon Sep 17 00:00:00 2001 From: David Greenman Date: Wed, 18 Nov 1998 09:00:47 +0000 Subject: [PATCH] Closed a very narrow and rare race condition that involved net interrupts, bio interrupts, and a truncated file that along with the precise alignment of the planets could result in a page being freed multiple times or a just-freed page being put onto the inactive queue. --- sys/kern/uipc_syscalls.c | 5 ++++- sys/kern/vfs_bio.c | 6 ++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index a35931e38863..a857710b20ee 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94 - * $Id: uipc_syscalls.c,v 1.44 1998/11/14 23:36:17 dg Exp $ + * $Id: uipc_syscalls.c,v 1.45 1998/11/15 16:55:09 dg Exp $ */ #include "opt_compat.h" @@ -1366,6 +1366,7 @@ sf_buf_free(caddr_t addr, u_int size) { struct sf_buf *sf; struct vm_page *m; + int s; sf = dtosf(addr); if (sf->refcnt == 0) @@ -1374,6 +1375,7 @@ sf_buf_free(caddr_t addr, u_int size) if (sf->refcnt == 0) { pmap_qremove((vm_offset_t)addr, 1); m = sf->m; + s = splvm(); vm_page_unwire(m, 0); /* * Check for the object going away on us. This can @@ -1382,6 +1384,7 @@ sf_buf_free(caddr_t addr, u_int size) */ if (m->wire_count == 0 && m->object == NULL) vm_page_free(m); + splx(s); sf->m = NULL; SLIST_INSERT_HEAD(&sf_freelist, sf, free_list); if (sf_buf_alloc_want) { diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 0b5487cbe37d..570455862a8f 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -11,7 +11,7 @@ * 2. Absolutely no warranty of function or purpose is made by the author * John S. Dyson. * - * $Id: vfs_bio.c,v 1.183 1998/10/30 14:53:54 dg Exp $ + * $Id: vfs_bio.c,v 1.184 1998/10/31 15:31:22 peter Exp $ */ /* @@ -788,9 +788,10 @@ static void vfs_vmio_release(bp) struct buf *bp; { - int i; + int i, s; vm_page_t m; + s = splvm(); for (i = 0; i < bp->b_npages; i++) { m = bp->b_pages[i]; bp->b_pages[i] = NULL; @@ -820,6 +821,7 @@ vfs_vmio_release(bp) } } } + splx(s); bufspace -= bp->b_bufsize; vmiospace -= bp->b_bufsize; pmap_qremove(trunc_page((vm_offset_t) bp->b_data), bp->b_npages);