Diff for /src/sys/vm/vm_page.c between versions 1.20 and 1.21

version 1.20, 2004/05/10 11:05:13 version 1.21, 2004/05/13 17:40:19
Line 374  vm_page_unhold(vm_page_t mem) Line 374  vm_page_unhold(vm_page_t mem)
  *      enter the page into the kernel's pmap.  We are not allowed to block   *      enter the page into the kernel's pmap.  We are not allowed to block
  *      here so we *can't* do this anyway.   *      here so we *can't* do this anyway.
  *   *
  *      The object and page must be locked, and must be splhigh.  
  *      This routine may not block.   *      This routine may not block.
    *      This routine must be called at splvm().
  */   */
   
 void  void
 vm_page_insert(vm_page_t m, vm_object_t object, vm_pindex_t pindex)  vm_page_insert(vm_page_t m, vm_object_t object, vm_pindex_t pindex)
 {  {
Line 389  vm_page_insert(vm_page_t m, vm_object_t Line 388  vm_page_insert(vm_page_t m, vm_object_t
         /*          /*
          * Record the object/offset pair in this page           * Record the object/offset pair in this page
          */           */
   
         m->object = object;          m->object = object;
         m->pindex = pindex;          m->pindex = pindex;
   
         /*          /*
          * Insert it into the object_object/offset hash table           * Insert it into the object_object/offset hash table
          */           */
   
         bucket = &vm_page_buckets[vm_page_hash(object, pindex)];          bucket = &vm_page_buckets[vm_page_hash(object, pindex)];
         m->hnext = *bucket;          m->hnext = *bucket;
         *bucket = m;          *bucket = m;
Line 431  vm_page_insert(vm_page_t m, vm_object_t Line 428  vm_page_insert(vm_page_t m, vm_object_t
  *      table and the object page list, but do not invalidate/terminate   *      table and the object page list, but do not invalidate/terminate
  *      the backing store.   *      the backing store.
  *   *
 *      The object and page must be locked, and at splhigh. *      This routine must be called at splvm()
  *      The underlying pmap entry (if any) is NOT removed here.   *      The underlying pmap entry (if any) is NOT removed here.
  *      This routine may not block.   *      This routine may not block.
  */   */
   
 void  void
 vm_page_remove(vm_page_t m)  vm_page_remove(vm_page_t m)
 {  {
Line 463  vm_page_remove(vm_page_t m) Line 459  vm_page_remove(vm_page_t m)
          * Note: we must NULL-out m->hnext to prevent loops in detached           * Note: we must NULL-out m->hnext to prevent loops in detached
          * buffers with vm_page_lookup().           * buffers with vm_page_lookup().
          */           */
   
         {          {
                 struct vm_page **bucket;                  struct vm_page **bucket;
   
Line 481  vm_page_remove(vm_page_t m) Line 476  vm_page_remove(vm_page_t m)
         /*          /*
          * Now remove from the object's list of backed pages.           * Now remove from the object's list of backed pages.
          */           */
   
         TAILQ_REMOVE(&object->memq, m, listq);          TAILQ_REMOVE(&object->memq, m, listq);
   
         /*          /*
          * And show that the object has one fewer resident page.           * And show that the object has one fewer resident page.
          */           */
   
         object->resident_page_count--;          object->resident_page_count--;
         object->generation++;          object->generation++;
   
Line 497  vm_page_remove(vm_page_t m) Line 490  vm_page_remove(vm_page_t m)
 /*  /*
  *      vm_page_lookup:   *      vm_page_lookup:
  *   *
 *      Returns the page associated with the object/offset *      Locate and return the page at (object, pindex), or NULL if the
 *      pair specified; if none is found, NULL is returned. *       page could not be found.
 * 
 *      NOTE: the code below does not lock.  It will operate properly if 
 *      an interrupt makes a change, but the generation algorithm will not  
 *      operate properly in an SMP environment where both cpu's are able to run 
 *      kernel code simultaneously. 
  *   *
 *      The object must be locked.  No side effects. *      This routine will operate properly without spl protection, but
 *      This routine may not block. *      the returned page could be in flux if it is busy.  Because an
 *      This is a critical path routine *      interrupt can race a caller's busy check (unbusying and freeing the
  *      page we return before the caller is able to check the busy bit),
  *      the caller should generally call this routine at splvm().
  *
  *      Callers may call this routine without spl protection if they know
  *      'for sure' that the page will not be ripped out from under them
  *      by an interrupt.
  */   */
   
 vm_page_t  vm_page_t
Line 1433  vm_page_dontneed(vm_page_t m) Line 1427  vm_page_dontneed(vm_page_t m)
 }  }
   
 /*  /*
 * Grab a page, waiting until we are waken up due to the page * Grab a page, blocking if it is busy and allocating a page if necessary.
 * changing state.  We keep on waiting, if the page continues * A busy page is returned or NULL.
 * to be in the object.  If the page doesn't exist, allocate it. 
  *   *
  * If VM_ALLOC_RETRY is specified VM_ALLOC_NORMAL must also be specified.   * If VM_ALLOC_RETRY is specified VM_ALLOC_NORMAL must also be specified.
    * If VM_ALLOC_RETRY is not specified
  *   *
 * This routine may block. * This routine may block, but if VM_ALLOC_RETRY is not set then NULL is
  * always returned if we had blocked.  
  * This routine will never return NULL if VM_ALLOC_RETRY is set.
  * This routine may not be called from an interrupt.
  * The returned page may not be entirely valid.
  *
  * This routine may be called from mainline code without spl protection and
  * be guarenteed a busied page associated with the object at the specified
  * index.
  */   */
 vm_page_t  vm_page_t
 vm_page_grab(vm_object_t object, vm_pindex_t pindex, int allocflags)  vm_page_grab(vm_object_t object, vm_pindex_t pindex, int allocflags)
Line 1449  vm_page_grab(vm_object_t object, vm_pind Line 1451  vm_page_grab(vm_object_t object, vm_pind
   
         KKASSERT(allocflags &          KKASSERT(allocflags &
                 (VM_ALLOC_NORMAL|VM_ALLOC_INTERRUPT|VM_ALLOC_SYSTEM));                  (VM_ALLOC_NORMAL|VM_ALLOC_INTERRUPT|VM_ALLOC_SYSTEM));
           s = splvm();
 retrylookup:  retrylookup:
         if ((m = vm_page_lookup(object, pindex)) != NULL) {          if ((m = vm_page_lookup(object, pindex)) != NULL) {
                 if (m->busy || (m->flags & PG_BUSY)) {                  if (m->busy || (m->flags & PG_BUSY)) {
                         generation = object->generation;                          generation = object->generation;
   
                         s = splvm();  
                         while ((object->generation == generation) &&                          while ((object->generation == generation) &&
                                         (m->busy || (m->flags & PG_BUSY))) {                                          (m->busy || (m->flags & PG_BUSY))) {
                                 vm_page_flag_set(m, PG_WANTED | PG_REFERENCED);                                  vm_page_flag_set(m, PG_WANTED | PG_REFERENCED);
                                 tsleep(m, 0, "pgrbwt", 0);                                  tsleep(m, 0, "pgrbwt", 0);
                                 if ((allocflags & VM_ALLOC_RETRY) == 0) {                                  if ((allocflags & VM_ALLOC_RETRY) == 0) {
                                        splx(s);                                        m = NULL;
                                        return NULL;                                        goto done;
                                 }                                  }
                         }                          }
                         splx(s);  
                         goto retrylookup;                          goto retrylookup;
                 } else {                  } else {
                         vm_page_busy(m);                          vm_page_busy(m);
                        return m;                        goto done;
                 }                  }
         }          }
   
         m = vm_page_alloc(object, pindex, allocflags & ~VM_ALLOC_RETRY);          m = vm_page_alloc(object, pindex, allocflags & ~VM_ALLOC_RETRY);
         if (m == NULL) {          if (m == NULL) {
                 VM_WAIT;                  VM_WAIT;
                 if ((allocflags & VM_ALLOC_RETRY) == 0)                  if ((allocflags & VM_ALLOC_RETRY) == 0)
                        return NULL;                        goto done;
                 goto retrylookup;                  goto retrylookup;
         }          }
done:
        return m;        splx(s);
         return(m);
 }  }
   
 /*  /*

Removed from v.1.20  
changed lines
  Added in v.1.21