Date: Sat, 06 Jan 1996 15:17:45 -0800 From: David Greenman <davidg@Root.COM> To: Poul-Henning Kamp <phk@critter.tfs.com> Cc: aagero@aage.aage.priv.no, freebsd-bugs@freefall.freebsd.org Subject: Re: kern/901: busy pages get free'd by vm_page_free Message-ID: <199601062317.PAA13971@corbin.Root.COM>
next in thread | raw e-mail | index | archive | help
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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199601062317.PAA13971>
