Skip site navigation (1)Skip section navigation (2)
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>