From owner-freebsd-bugs Sat Jan 6 15:17:52 1996 Return-Path: owner-bugs Received: (from root@localhost) by freefall.freebsd.org (8.7.3/8.7.3) id PAA27434 for bugs-outgoing; Sat, 6 Jan 1996 15:17:52 -0800 (PST) Received: from Root.COM (implode.Root.COM [198.145.90.17]) by freefall.freebsd.org (8.7.3/8.7.3) with SMTP id PAA27424 for ; Sat, 6 Jan 1996 15:17:46 -0800 (PST) Received: from corbin.Root.COM (corbin [198.145.90.50]) by Root.COM (8.6.12/8.6.5) with ESMTP id PAA09337; Sat, 6 Jan 1996 15:17:45 -0800 Received: from localhost (localhost [127.0.0.1]) by corbin.Root.COM (8.7.3/8.6.5) with SMTP id PAA13971; Sat, 6 Jan 1996 15:17:45 -0800 (PST) Message-Id: <199601062317.PAA13971@corbin.Root.COM> To: Poul-Henning Kamp cc: aagero@aage.aage.priv.no, freebsd-bugs@freefall.freebsd.org Subject: Re: kern/901: busy pages get free'd by vm_page_free From: David Greenman Reply-To: davidg@Root.COM Date: Sat, 06 Jan 1996 15:17:45 -0800 Sender: owner-bugs@FreeBSD.ORG Precedence: bulk I just looked at my own changes and they are considerably different from Poul-Henning's. The correct solution for this problem I believe is what I've attached to this message. Basically, if "from" is already page-aligned and is the base address of the buffer, and if the bp->b_data contains an offset (as it sometimes does), then the subtraction will be negative and the machine will panic. The solution is to page truncate bp->b_data first before subtracting. -DG David Greenman Core Team/Principal Architect, The FreeBSD Project Index: vfs_bio.c =================================================================== RCS file: /home/ncvs/src/sys/kern/vfs_bio.c,v retrieving revision 1.81 diff -c -r1.81 vfs_bio.c *** vfs_bio.c 1996/01/05 20:12:33 1.81 --- vfs_bio.c 1996/01/06 22:25:10 *************** *** 1605,1618 **** * not associated with a file object. */ void ! vm_hold_load_pages(struct buf * bp, vm_offset_t froma, vm_offset_t toa) { vm_offset_t pg; vm_page_t p; - vm_offset_t from = round_page(froma); - vm_offset_t to = round_page(toa); ! for (pg = from; pg < to; pg += PAGE_SIZE) { tryagain: --- 1605,1618 ---- * not associated with a file object. */ void ! vm_hold_load_pages(struct buf * bp, vm_offset_t from, vm_offset_t to) { vm_offset_t pg; vm_page_t p; ! to = round_page(to); ! ! for (pg = round_page(from); pg < to; pg += PAGE_SIZE) { tryagain: *************** *** 1624,1645 **** } vm_page_wire(p); pmap_kenter(pg, VM_PAGE_TO_PHYS(p)); ! bp->b_pages[((caddr_t) pg - bp->b_data) >> PAGE_SHIFT] = p; PAGE_WAKEUP(p); bp->b_npages++; } } void ! vm_hold_free_pages(struct buf * bp, vm_offset_t froma, vm_offset_t toa) { vm_offset_t pg; vm_page_t p; ! vm_offset_t from = round_page(froma); ! vm_offset_t to = round_page(toa); ! for (pg = from; pg < to; pg += PAGE_SIZE) { ! int index = ((caddr_t) pg - bp->b_data) >> PAGE_SHIFT; p = bp->b_pages[index]; bp->b_pages[index] = 0; pmap_kremove(pg); --- 1624,1647 ---- } vm_page_wire(p); pmap_kenter(pg, VM_PAGE_TO_PHYS(p)); ! bp->b_pages[(pg - trunc_page(bp->b_data)) >> PAGE_SHIFT] = p; PAGE_WAKEUP(p); bp->b_npages++; } } void ! vm_hold_free_pages(struct buf * bp, vm_offset_t from, vm_offset_t to) { vm_offset_t pg; vm_page_t p; ! int index; ! ! from = round_page(from); ! to = round_page(to); ! index = (from - trunc_page(bp->b_data)) >> PAGE_SHIFT; ! for (pg = from; pg < to; pg += PAGE_SIZE, index++) { p = bp->b_pages[index]; bp->b_pages[index] = 0; pmap_kremove(pg);