[BACK]Return to uvm_vnode.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / uvm

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/uvm/uvm_vnode.c between version 1.97 and 1.97.2.2

version 1.97, 2011/09/06 16:41:55 version 1.97.2.2, 2011/11/26 15:19:06
Line 64  __KERNEL_RCSID(0, "$NetBSD$");
Line 64  __KERNEL_RCSID(0, "$NetBSD$");
   
 #include <uvm/uvm.h>  #include <uvm/uvm.h>
 #include <uvm/uvm_readahead.h>  #include <uvm/uvm_readahead.h>
   #include <uvm/uvm_page_array.h>
   
 /*  /*
  * functions   * functions
Line 76  static int uvn_put(struct uvm_object *, 
Line 77  static int uvn_put(struct uvm_object *, 
 static void     uvn_reference(struct uvm_object *);  static void     uvn_reference(struct uvm_object *);
   
 static int      uvn_findpage(struct uvm_object *, voff_t, struct vm_page **,  static int      uvn_findpage(struct uvm_object *, voff_t, struct vm_page **,
                              int);                               int, struct uvm_page_array *a, unsigned int);
   
 /*  /*
  * master pager structure   * master pager structure
Line 130  uvn_detach(struct uvm_object *uobj)
Line 131  uvn_detach(struct uvm_object *uobj)
  *   *
  * => object must be locked on entry!   VOP_PUTPAGES must unlock it.   * => object must be locked on entry!   VOP_PUTPAGES must unlock it.
  * => flags: PGO_SYNCIO -- use sync. I/O   * => flags: PGO_SYNCIO -- use sync. I/O
  * => note: caller must set PG_CLEAN and pmap_clear_modify (if needed)  
  */   */
   
 static int  static int
Line 197  uvn_findpages(struct uvm_object *uobj, v
Line 197  uvn_findpages(struct uvm_object *uobj, v
     struct vm_page **pgs, int flags)      struct vm_page **pgs, int flags)
 {  {
         int i, count, found, npages, rv;          int i, count, found, npages, rv;
           struct uvm_page_array a;
   
           uvm_page_array_init(&a);
         count = found = 0;          count = found = 0;
         npages = *npagesp;          npages = *npagesp;
         if (flags & UFP_BACKWARD) {          if (flags & UFP_BACKWARD) {
                 for (i = npages - 1; i >= 0; i--, offset -= PAGE_SIZE) {                  for (i = npages - 1; i >= 0; i--, offset -= PAGE_SIZE) {
                         rv = uvn_findpage(uobj, offset, &pgs[i], flags);                          rv = uvn_findpage(uobj, offset, &pgs[i], flags, &a,
                               npages - i);
                         if (rv == 0) {                          if (rv == 0) {
                                 if (flags & UFP_DIRTYONLY)                                  if (flags & UFP_DIRTYONLY)
                                         break;                                          break;
Line 212  uvn_findpages(struct uvm_object *uobj, v
Line 215  uvn_findpages(struct uvm_object *uobj, v
                 }                  }
         } else {          } else {
                 for (i = 0; i < npages; i++, offset += PAGE_SIZE) {                  for (i = 0; i < npages; i++, offset += PAGE_SIZE) {
                         rv = uvn_findpage(uobj, offset, &pgs[i], flags);                          rv = uvn_findpage(uobj, offset, &pgs[i], flags, &a,
                               npages - i);
                         if (rv == 0) {                          if (rv == 0) {
                                 if (flags & UFP_DIRTYONLY)                                  if (flags & UFP_DIRTYONLY)
                                         break;                                          break;
Line 221  uvn_findpages(struct uvm_object *uobj, v
Line 225  uvn_findpages(struct uvm_object *uobj, v
                         count++;                          count++;
                 }                  }
         }          }
           uvm_page_array_fini(&a);
         *npagesp = count;          *npagesp = count;
         return (found);          return (found);
 }  }
   
 static int  static int
 uvn_findpage(struct uvm_object *uobj, voff_t offset, struct vm_page **pgp,  uvn_findpage(struct uvm_object *uobj, voff_t offset, struct vm_page **pgp,
     int flags)      int flags, struct uvm_page_array *a, unsigned int nleft)
 {  {
         struct vm_page *pg;          struct vm_page *pg;
         bool dirty;          bool dirty;
           const unsigned int fillflags =
               ((flags & UFP_BACKWARD) ? UVM_PAGE_ARRAY_FILL_BACKWARD : 0) ||
               ((flags & UFP_DIRTYONLY) ?
               (UVM_PAGE_ARRAY_FILL_DIRTYONLY|UVM_PAGE_ARRAY_FILL_DENSE) : 0);
         UVMHIST_FUNC("uvn_findpage"); UVMHIST_CALLED(ubchist);          UVMHIST_FUNC("uvn_findpage"); UVMHIST_CALLED(ubchist);
         UVMHIST_LOG(ubchist, "vp %p off 0x%lx", uobj, offset,0,0);          UVMHIST_LOG(ubchist, "vp %p off 0x%lx", uobj, offset,0,0);
   
Line 238  uvn_findpage(struct uvm_object *uobj, vo
Line 247  uvn_findpage(struct uvm_object *uobj, vo
   
         if (*pgp != NULL) {          if (*pgp != NULL) {
                 UVMHIST_LOG(ubchist, "dontcare", 0,0,0,0);                  UVMHIST_LOG(ubchist, "dontcare", 0,0,0,0);
                 return 0;                  goto skip;
         }          }
         for (;;) {          for (;;) {
                 /* look for an existing page */                  /* look for an existing page */
                 pg = uvm_pagelookup(uobj, offset);                  pg = uvm_page_array_fill_and_peek(a, uobj, offset, nleft,
                       fillflags);
                   if (pg != NULL && pg->offset != offset) {
                           KASSERT((fillflags & UVM_PAGE_ARRAY_FILL_DENSE) == 0);
                           KASSERT(
                               ((fillflags & UVM_PAGE_ARRAY_FILL_BACKWARD) != 0)
                               == (pg->offset < offset));
                           pg = NULL;
                   }
   
                 /* nope?  allocate one now */                  /* nope?  allocate one now */
                 if (pg == NULL) {                  if (pg == NULL) {
Line 259  uvn_findpage(struct uvm_object *uobj, vo
Line 276  uvn_findpage(struct uvm_object *uobj, vo
                                 }                                  }
                                 mutex_exit(uobj->vmobjlock);                                  mutex_exit(uobj->vmobjlock);
                                 uvm_wait("uvn_fp1");                                  uvm_wait("uvn_fp1");
                                   uvm_page_array_clear(a);
                                 mutex_enter(uobj->vmobjlock);                                  mutex_enter(uobj->vmobjlock);
                                 continue;                                  continue;
                         }                          }
Line 267  uvn_findpage(struct uvm_object *uobj, vo
Line 285  uvn_findpage(struct uvm_object *uobj, vo
                         break;                          break;
                 } else if (flags & UFP_NOCACHE) {                  } else if (flags & UFP_NOCACHE) {
                         UVMHIST_LOG(ubchist, "nocache",0,0,0,0);                          UVMHIST_LOG(ubchist, "nocache",0,0,0,0);
                         return 0;                          goto skip;
                 }                  }
   
                 /* page is there, see if we need to wait on it */                  /* page is there, see if we need to wait on it */
                 if ((pg->flags & PG_BUSY) != 0) {                  if ((pg->flags & PG_BUSY) != 0) {
                         if (flags & UFP_NOWAIT) {                          if (flags & UFP_NOWAIT) {
                                 UVMHIST_LOG(ubchist, "nowait",0,0,0,0);                                  UVMHIST_LOG(ubchist, "nowait",0,0,0,0);
                                 return 0;                                  goto skip;
                         }                          }
                         pg->flags |= PG_WANTED;                          pg->flags |= PG_WANTED;
                         UVMHIST_LOG(ubchist, "wait %p (color %u)", pg,                          UVMHIST_LOG(ubchist, "wait %p (color %u)", pg,
                             VM_PGCOLOR_BUCKET(pg), 0,0);                              VM_PGCOLOR_BUCKET(pg), 0,0);
                         UVM_UNLOCK_AND_WAIT(pg, uobj->vmobjlock, 0,                          UVM_UNLOCK_AND_WAIT(pg, uobj->vmobjlock, 0,
                                             "uvn_fp2", 0);                                              "uvn_fp2", 0);
                           uvm_page_array_clear(a);
                         mutex_enter(uobj->vmobjlock);                          mutex_enter(uobj->vmobjlock);
                         continue;                          continue;
                 }                  }
   
                 /* skip PG_RDONLY pages if requested */                  /* skip PG_RDONLY and PG_HOLE pages if requested */
                 if ((flags & UFP_NORDONLY) && (pg->flags & PG_RDONLY)) {                  if ((flags & UFP_NORDONLY) &&
                       (pg->flags & (PG_RDONLY|PG_HOLE))) {
                         UVMHIST_LOG(ubchist, "nordonly",0,0,0,0);                          UVMHIST_LOG(ubchist, "nordonly",0,0,0,0);
                         return 0;                          goto skip;
                 }                  }
   
                 /* stop on clean pages if requested */                  /* stop on clean pages if requested */
                 if (flags & UFP_DIRTYONLY) {                  if (flags & UFP_DIRTYONLY) {
                         dirty = pmap_clear_modify(pg) ||                          dirty = uvm_pagecheckdirty(pg, false);
                                 (pg->flags & PG_CLEAN) == 0;  
                         pg->flags |= PG_CLEAN;  
                         if (!dirty) {                          if (!dirty) {
                                 UVMHIST_LOG(ubchist, "dirtonly", 0,0,0,0);                                  UVMHIST_LOG(ubchist, "dirtonly", 0,0,0,0);
                                 return 0;                                  return 0;
Line 307  uvn_findpage(struct uvm_object *uobj, vo
Line 325  uvn_findpage(struct uvm_object *uobj, vo
                 UVM_PAGE_OWN(pg, "uvn_findpage");                  UVM_PAGE_OWN(pg, "uvn_findpage");
                 UVMHIST_LOG(ubchist, "found %p (color %u)",                  UVMHIST_LOG(ubchist, "found %p (color %u)",
                     pg, VM_PGCOLOR_BUCKET(pg), 0,0);                      pg, VM_PGCOLOR_BUCKET(pg), 0,0);
                   uvm_page_array_advance(a);
                 break;                  break;
         }          }
         *pgp = pg;          *pgp = pg;
         return 1;          return 1;
   
   skip:
           pg = uvm_page_array_peek(a);
           if (pg != NULL) {
                   if (pg->offset == offset) {
                           uvm_page_array_advance(a);
                   } else {
                           KASSERT((fillflags & UVM_PAGE_ARRAY_FILL_DENSE) == 0);
                   }
           }
           return 0;
 }  }
   
 /*  /*

Legend:
Removed from v.1.97  
changed lines
  Added in v.1.97.2.2

CVSweb <webmaster@jp.NetBSD.org>