Diff for /src/sys/vm/vm_fault.c between versions 1.13 and 1.14

version 1.13, 2004/03/29 17:30:23 version 1.14, 2004/05/13 17:40:19
Line 193  vm_fault(vm_map_t map, vm_offset_t vaddr Line 193  vm_fault(vm_map_t map, vm_offset_t vaddr
         vm_page_t marray[VM_FAULT_READ];          vm_page_t marray[VM_FAULT_READ];
         int hardfault;          int hardfault;
         int faultcount;          int faultcount;
           int s;
         struct faultstate fs;          struct faultstate fs;
   
         mycpu->gd_cnt.v_vm_faults++;          mycpu->gd_cnt.v_vm_faults++;
         hardfault = 0;          hardfault = 0;
   
RetryFault:;RetryFault:
 
         /*          /*
          * Find the backing store object and offset into it to begin the           * Find the backing store object and offset into it to begin the
          * search.           * search.
Line 288  RetryFault:; Line 288  RetryFault:;
                 }                  }
   
                 /*                  /*
                 * See if page is resident                 * See if page is resident.  spl protection is required
                  * to avoid an interrupt unbusy/free race against our
                  * lookup.  We must hold the protection through a page
                  * allocation or busy.
                  */                   */
                                        s = splvm();
                 fs.m = vm_page_lookup(fs.object, fs.pindex);                  fs.m = vm_page_lookup(fs.object, fs.pindex);
                 if (fs.m != NULL) {                  if (fs.m != NULL) {
                        int queue, s;                        int queue;
                         /*                          /*
                          * Wait/Retry if the page is busy.  We have to do this                           * Wait/Retry if the page is busy.  We have to do this
                          * if the page is busy via either PG_BUSY or                            * if the page is busy via either PG_BUSY or 
Line 312  RetryFault:; Line 315  RetryFault:;
                          */                           */
                         if ((fs.m->flags & PG_BUSY) || fs.m->busy) {                          if ((fs.m->flags & PG_BUSY) || fs.m->busy) {
                                 unlock_things(&fs);                                  unlock_things(&fs);
                                (void)vm_page_sleep_busy(fs.m, TRUE, "vmpfw");                                vm_page_sleep_busy(fs.m, TRUE, "vmpfw");
                                 mycpu->gd_cnt.v_intrans++;                                  mycpu->gd_cnt.v_intrans++;
                                 vm_object_deallocate(fs.first_object);                                  vm_object_deallocate(fs.first_object);
                                   splx(s);
                                 goto RetryFault;                                  goto RetryFault;
                         }                          }
   
                         queue = fs.m->queue;                          queue = fs.m->queue;
                         s = splvm();  
                         vm_page_unqueue_nowakeup(fs.m);                          vm_page_unqueue_nowakeup(fs.m);
                         splx(s);  
   
                         if ((queue - fs.m->pc) == PQ_CACHE && vm_page_count_severe()) {                          if ((queue - fs.m->pc) == PQ_CACHE && vm_page_count_severe()) {
                                 vm_page_activate(fs.m);                                  vm_page_activate(fs.m);
                                 unlock_and_deallocate(&fs);                                  unlock_and_deallocate(&fs);
                                 VM_WAITPFAULT;                                  VM_WAITPFAULT;
                                   splx(s);
                                 goto RetryFault;                                  goto RetryFault;
                         }                          }
   
Line 335  RetryFault:; Line 338  RetryFault:;
                          * pagedaemon.  If it still isn't completely valid                           * pagedaemon.  If it still isn't completely valid
                          * (readable), jump to readrest, else break-out ( we                           * (readable), jump to readrest, else break-out ( we
                          * found the page ).                           * found the page ).
                            *
                            * We can release the spl once we have marked the
                            * page busy.
                          */                           */
   
                         vm_page_busy(fs.m);                          vm_page_busy(fs.m);
                           splx(s);
   
                         if (((fs.m->valid & VM_PAGE_BITS_ALL) != VM_PAGE_BITS_ALL) &&                          if (((fs.m->valid & VM_PAGE_BITS_ALL) != VM_PAGE_BITS_ALL) &&
                                 fs.m->object != kernel_object && fs.m->object != kmem_object) {                                  fs.m->object != kernel_object && fs.m->object != kmem_object) {
                                 goto readrest;                                  goto readrest;
Line 349  RetryFault:; Line 357  RetryFault:;
                 /*                  /*
                  * Page is not resident, If this is the search termination                   * Page is not resident, If this is the search termination
                  * or the pager might contain the page, allocate a new page.                   * or the pager might contain the page, allocate a new page.
                    *
                    * note: we are still in splvm().
                  */                   */
   
                 if (TRYPAGER || fs.object == fs.first_object) {                  if (TRYPAGER || fs.object == fs.first_object) {
                         if (fs.pindex >= fs.object->size) {                          if (fs.pindex >= fs.object->size) {
                                   splx(s);
                                 unlock_and_deallocate(&fs);                                  unlock_and_deallocate(&fs);
                                 return (KERN_PROTECTION_FAILURE);                                  return (KERN_PROTECTION_FAILURE);
                         }                          }
Line 366  RetryFault:; Line 377  RetryFault:;
                                     (fs.vp || fs.object->backing_object)? VM_ALLOC_NORMAL: VM_ALLOC_NORMAL | VM_ALLOC_ZERO);                                      (fs.vp || fs.object->backing_object)? VM_ALLOC_NORMAL: VM_ALLOC_NORMAL | VM_ALLOC_ZERO);
                         }                          }
                         if (fs.m == NULL) {                          if (fs.m == NULL) {
                                   splx(s);
                                 unlock_and_deallocate(&fs);                                  unlock_and_deallocate(&fs);
                                 VM_WAITPFAULT;                                  VM_WAITPFAULT;
                                 goto RetryFault;                                  goto RetryFault;
                         }                          }
                 }                  }
                   splx(s);
   
 readrest:  readrest:
                 /*                  /*
Line 381  readrest: Line 394  readrest:
                  * Attempt to fault-in the page if there is a chance that the                   * Attempt to fault-in the page if there is a chance that the
                  * pager has it, and potentially fault in additional pages                   * pager has it, and potentially fault in additional pages
                  * at the same time.                   * at the same time.
                    *
                    * We are NOT in splvm here and if TRYPAGER is true then
                    * fs.m will be non-NULL and will be PG_BUSY for us.
                  */                   */
   
                 if (TRYPAGER) {                  if (TRYPAGER) {
Line 419  readrest: Line 435  readrest:
                                  * note: partially valid pages cannot be                                    * note: partially valid pages cannot be 
                                  * included in the lookahead - NFS piecemeal                                   * included in the lookahead - NFS piecemeal
                                  * writes will barf on it badly.                                   * writes will barf on it badly.
                                 */                                 *
                                 * spl protection is required to avoid races
                                for(tmppindex = fs.first_pindex - 1;                                 * between the lookup and an interrupt
                                        tmppindex >= firstpindex;                                 * unbusy/free sequence occuring prior to
                                        --tmppindex) {                                 * our busy check.
                                  */
                                 s = splvm();
                                 for (tmppindex = fs.first_pindex - 1;
                                     tmppindex >= firstpindex;
                                     --tmppindex
                                 ) {
                                         vm_page_t mt;                                          vm_page_t mt;
                                         mt = vm_page_lookup( fs.first_object, tmppindex);                                          mt = vm_page_lookup( fs.first_object, tmppindex);
                                         if (mt == NULL || (mt->valid != VM_PAGE_BITS_ALL))                                          if (mt == NULL || (mt->valid != VM_PAGE_BITS_ALL))
Line 442  readrest: Line 464  readrest:
                                                 vm_page_cache(mt);                                                  vm_page_cache(mt);
                                         }                                          }
                                 }                                  }
                                   splx(s);
   
                                 ahead += behind;                                  ahead += behind;
                                 behind = 0;                                  behind = 0;
Line 491  readrest: Line 514  readrest:
                                  * Relookup in case pager changed page. Pager                                   * Relookup in case pager changed page. Pager
                                  * is responsible for disposition of old page                                   * is responsible for disposition of old page
                                  * if moved.                                   * if moved.
                                    *
                                    * XXX other code segments do relookups too.
                                    * It's a bad abstraction that needs to be
                                    * fixed/removed.
                                  */                                   */
                                 fs.m = vm_page_lookup(fs.object, fs.pindex);                                  fs.m = vm_page_lookup(fs.object, fs.pindex);
                                if(!fs.m) {                                if (fs.m == NULL) {
                                         unlock_and_deallocate(&fs);                                          unlock_and_deallocate(&fs);
                                         goto RetryFault;                                          goto RetryFault;
                                 }                                  }
Line 1179  vm_fault_additional_pages(vm_page_t m, i Line 1206  vm_fault_additional_pages(vm_page_t m, i
   
         /*          /*
          * scan backward for the read behind pages -- in memory            * scan backward for the read behind pages -- in memory 
            *
            * Assume that if the page is not found an interrupt will not
            * create it.  Theoretically interrupts can only remove (busy)
            * pages, not create new associations.
          */           */
         if (pindex > 0) {          if (pindex > 0) {
                 if (rbehind > pindex) {                  if (rbehind > pindex) {

Removed from v.1.13  
changed lines
  Added in v.1.14