[BACK]Return to uvm_map.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_map.c between version 1.254.4.1 and 1.254.4.2

version 1.254.4.1, 2008/06/23 04:32:06 version 1.254.4.2, 2008/09/18 04:37:06
Line 95  __KERNEL_RCSID(0, "$NetBSD$");
Line 95  __KERNEL_RCSID(0, "$NetBSD$");
 #endif  #endif
   
 #include <uvm/uvm.h>  #include <uvm/uvm.h>
 #undef RB_AUGMENT  
 #define RB_AUGMENT(x)   uvm_rb_augment(x)  
   
 #ifdef DDB  #ifdef DDB
 #include <uvm/uvm_ddb.h>  #include <uvm/uvm_ddb.h>
Line 131  UVMMAP_EVCNT_DEFINE(knomerge)
Line 129  UVMMAP_EVCNT_DEFINE(knomerge)
 UVMMAP_EVCNT_DEFINE(map_call)  UVMMAP_EVCNT_DEFINE(map_call)
 UVMMAP_EVCNT_DEFINE(mlk_call)  UVMMAP_EVCNT_DEFINE(mlk_call)
 UVMMAP_EVCNT_DEFINE(mlk_hint)  UVMMAP_EVCNT_DEFINE(mlk_hint)
   UVMMAP_EVCNT_DEFINE(mlk_list)
   UVMMAP_EVCNT_DEFINE(mlk_tree)
   UVMMAP_EVCNT_DEFINE(mlk_treeloop)
   UVMMAP_EVCNT_DEFINE(mlk_listloop)
   
 UVMMAP_EVCNT_DEFINE(uke_alloc)  UVMMAP_EVCNT_DEFINE(uke_alloc)
 UVMMAP_EVCNT_DEFINE(uke_free)  UVMMAP_EVCNT_DEFINE(uke_free)
Line 297  static void uvm_map_unreference_amap(str
Line 299  static void uvm_map_unreference_amap(str
   
 int _uvm_map_sanity(struct vm_map *);  int _uvm_map_sanity(struct vm_map *);
 int _uvm_tree_sanity(struct vm_map *);  int _uvm_tree_sanity(struct vm_map *);
 static vsize_t uvm_rb_subtree_space(const struct vm_map_entry *);  static vsize_t uvm_rb_maxgap(const struct vm_map_entry *);
   
 static inline int  CTASSERT(offsetof(struct vm_map_entry, rb_node) == 0);
 uvm_compare(const struct vm_map_entry *a, const struct vm_map_entry *b)  #define ROOT_ENTRY(map)         ((struct vm_map_entry *)(map)->rb_tree.rbt_root)
   #define LEFT_ENTRY(entry)       ((struct vm_map_entry *)(entry)->rb_node.rb_left)
   #define RIGHT_ENTRY(entry)      ((struct vm_map_entry *)(entry)->rb_node.rb_right)
   #define PARENT_ENTRY(map, entry) \
           (ROOT_ENTRY(map) == (entry) \
               ? NULL \
               : (struct vm_map_entry *)RB_FATHER(&(entry)->rb_node))
   
   static int
   uvm_map_compare_nodes(const struct rb_node *nparent,
           const struct rb_node *nkey)
 {  {
           const struct vm_map_entry *eparent = (const void *) nparent;
           const struct vm_map_entry *ekey = (const void *) nkey;
   
         if (a->start < b->start)          KASSERT(eparent->start < ekey->start || eparent->start >= ekey->end);
                 return (-1);          KASSERT(ekey->start < eparent->start || ekey->start >= eparent->end);
         else if (a->start > b->start)  
                 return (1);  
   
         return (0);          if (ekey->start < eparent->start)
                   return -1;
           if (ekey->start >= eparent->end)
                   return 1;
           return 0;
 }  }
   
 static inline void  static int
 uvm_rb_augment(struct vm_map_entry *entry)  uvm_map_compare_key(const struct rb_node *nparent, const void *vkey)
 {  {
           const struct vm_map_entry *eparent = (const void *) nparent;
           const vaddr_t va = *(const vaddr_t *) vkey;
   
         entry->space = uvm_rb_subtree_space(entry);          if (va < eparent->start)
                   return -1;
           if (va >= eparent->end)
                   return 1;
           return 0;
 }  }
   
 RB_PROTOTYPE(uvm_tree, vm_map_entry, rb_entry, uvm_compare);  static const struct rb_tree_ops uvm_map_tree_ops = {
           .rbto_compare_nodes = uvm_map_compare_nodes,
 RB_GENERATE(uvm_tree, vm_map_entry, rb_entry, uvm_compare);          .rbto_compare_key = uvm_map_compare_key,
   };
   
 static inline vsize_t  static inline vsize_t
 uvm_rb_space(const struct vm_map *map, const struct vm_map_entry *entry)  uvm_rb_gap(const struct vm_map_entry *entry)
 {  {
         /* XXX map is not used */  
   
         KASSERT(entry->next != NULL);          KASSERT(entry->next != NULL);
         return entry->next->start - entry->end;          return entry->next->start - entry->end;
 }  }
   
 static vsize_t  static vsize_t
 uvm_rb_subtree_space(const struct vm_map_entry *entry)  uvm_rb_maxgap(const struct vm_map_entry *entry)
 {  {
         vaddr_t space, tmp;          struct vm_map_entry *child;
           vsize_t maxgap = entry->gap;
   
         space = entry->ownspace;          /*
         if (RB_LEFT(entry, rb_entry)) {           * We need maxgap to be the largest gap of us or any of our
                 tmp = RB_LEFT(entry, rb_entry)->space;           * descendents.  Since each of our children's maxgap is the
                 if (tmp > space)           * cached value of their largest gap of themselves or their
                         space = tmp;           * descendents, we can just use that value and avoid recursing
         }           * down the tree to calculate it.
            */
           if ((child = LEFT_ENTRY(entry)) != NULL && maxgap < child->maxgap)
                   maxgap = child->maxgap;
   
         if (RB_RIGHT(entry, rb_entry)) {          if ((child = RIGHT_ENTRY(entry)) != NULL && maxgap < child->maxgap)
                 tmp = RB_RIGHT(entry, rb_entry)->space;                  maxgap = child->maxgap;
                 if (tmp > space)  
                         space = tmp;  
         }  
   
         return (space);          return maxgap;
 }  }
   
 static inline void  static void
 uvm_rb_fixup(struct vm_map *map, struct vm_map_entry *entry)  uvm_rb_fixup(struct vm_map *map, struct vm_map_entry *entry)
 {  {
         /* We need to traverse to the very top */          struct vm_map_entry *parent;
         do {  
                 entry->ownspace = uvm_rb_space(map, entry);          KASSERT(entry->gap == uvm_rb_gap(entry));
                 entry->space = uvm_rb_subtree_space(entry);          entry->maxgap = uvm_rb_maxgap(entry);
         } while ((entry = RB_PARENT(entry, rb_entry)) != NULL);  
           while ((parent = PARENT_ENTRY(map, entry)) != NULL) {
                   struct vm_map_entry *brother;
                   vsize_t maxgap = parent->gap;
   
                   KDASSERT(parent->gap == uvm_rb_gap(parent));
                   if (maxgap < entry->maxgap)
                           maxgap = entry->maxgap;
                   /*
                    * Since we work our towards the root, we know entry's maxgap
                    * value is ok but its brothers may now be out-of-date due
                    * rebalancing.  So refresh it.
                    */
                   brother = (struct vm_map_entry *)parent->rb_node.rb_nodes[RB_POSITION(&entry->rb_node) ^ RB_DIR_OTHER];
                   if (brother != NULL) {
                           KDASSERT(brother->gap == uvm_rb_gap(brother));
                           brother->maxgap = uvm_rb_maxgap(brother);
                           if (maxgap < brother->maxgap)
                                   maxgap = brother->maxgap;
                   }
   
                   parent->maxgap = maxgap;
                   entry = parent;
           }
 }  }
   
 static void  static void
 uvm_rb_insert(struct vm_map *map, struct vm_map_entry *entry)  uvm_rb_insert(struct vm_map *map, struct vm_map_entry *entry)
 {  {
         vaddr_t space = uvm_rb_space(map, entry);          entry->gap = entry->maxgap = uvm_rb_gap(entry);
         struct vm_map_entry *tmp;  
   
         entry->ownspace = entry->space = space;  
         tmp = RB_INSERT(uvm_tree, &(map)->rbhead, entry);  
 #ifdef DIAGNOSTIC  
         if (tmp != NULL)  
                 panic("uvm_rb_insert: duplicate entry?");  
 #endif  
         uvm_rb_fixup(map, entry);  
         if (entry->prev != &map->header)          if (entry->prev != &map->header)
                 uvm_rb_fixup(map, entry->prev);                  entry->prev->gap = uvm_rb_gap(entry->prev);
   
           if (!rb_tree_insert_node(&map->rb_tree, &entry->rb_node))
                   panic("uvm_rb_insert: map %p: duplicate entry?", map);
   
           /*
            * If the previous entry is not our immediate left child, then it's an
            * ancestor and will be fixed up on the way to the root.  We don't
            * have to check entry->prev against &map->header since &map->header
            * will never be in the tree.
            */
           uvm_rb_fixup(map,
               LEFT_ENTRY(entry) == entry->prev ? entry->prev : entry);
 }  }
   
 static void  static void
 uvm_rb_remove(struct vm_map *map, struct vm_map_entry *entry)  uvm_rb_remove(struct vm_map *map, struct vm_map_entry *entry)
 {  {
         struct vm_map_entry *parent;          struct vm_map_entry *prev_parent = NULL, *next_parent = NULL;
   
         parent = RB_PARENT(entry, rb_entry);          /*
         RB_REMOVE(uvm_tree, &(map)->rbhead, entry);           * If we are removing an interior node, then an adjacent node will
            * be used to replace its position in the tree.  Therefore we will
            * need to fixup the tree starting at the parent of the replacement
            * node.  So record their parents for later use.
            */
         if (entry->prev != &map->header)          if (entry->prev != &map->header)
                   prev_parent = PARENT_ENTRY(map, entry->prev);
           if (entry->next != &map->header)
                   next_parent = PARENT_ENTRY(map, entry->next);
   
           rb_tree_remove_node(&map->rb_tree, &entry->rb_node);
   
           /*
            * If the previous node has a new parent, fixup the tree starting
            * at the previous node's old parent.
            */
           if (entry->prev != &map->header) {
                   /*
                    * Update the previous entry's gap due to our absence.
                    */
                   entry->prev->gap = uvm_rb_gap(entry->prev);
                 uvm_rb_fixup(map, entry->prev);                  uvm_rb_fixup(map, entry->prev);
         if (parent)                  if (prev_parent != NULL
                 uvm_rb_fixup(map, parent);                      && prev_parent != entry
                       && prev_parent != PARENT_ENTRY(map, entry->prev))
                           uvm_rb_fixup(map, prev_parent);
           }
   
           /*
            * If the next node has a new parent, fixup the tree starting
            * at the next node's old parent.
            */
           if (entry->next != &map->header) {
                   uvm_rb_fixup(map, entry->next);
                   if (next_parent != NULL
                       && next_parent != entry
                       && next_parent != PARENT_ENTRY(map, entry->next))
                           uvm_rb_fixup(map, next_parent);
           }
 }  }
   
 #if defined(DEBUG)  #if defined(DEBUG)
Line 455  _uvm_tree_sanity(struct vm_map *map)
Line 537  _uvm_tree_sanity(struct vm_map *map)
         struct vm_map_entry *tmp, *trtmp;          struct vm_map_entry *tmp, *trtmp;
         int n = 0, i = 1;          int n = 0, i = 1;
   
         RB_FOREACH(tmp, uvm_tree, &map->rbhead) {          for (tmp = map->header.next; tmp != &map->header; tmp = tmp->next) {
                 if (tmp->ownspace != uvm_rb_space(map, tmp)) {                  if (tmp->gap != uvm_rb_gap(tmp)) {
                         printf("%d/%d ownspace %lx != %lx %s\n",                          printf("%d/%d gap %lx != %lx %s\n",
                             n + 1, map->nentries,                              n + 1, map->nentries,
                             (ulong)tmp->ownspace, (ulong)uvm_rb_space(map, tmp),                              (ulong)tmp->gap, (ulong)uvm_rb_gap(tmp),
                             tmp->next == &map->header ? "(last)" : "");                              tmp->next == &map->header ? "(last)" : "");
                         goto error;                          goto error;
                 }                  }
                   /*
                    * If any entries are out of order, tmp->gap will be unsigned
                    * and will likely exceed the size of the map.
                    */
                   KASSERT(tmp->gap < map->size);
                   n++;
           }
   
           if (n != map->nentries) {
                   printf("nentries: %d vs %d\n", n, map->nentries);
                   goto error;
         }          }
   
         trtmp = NULL;          trtmp = NULL;
         RB_FOREACH(tmp, uvm_tree, &map->rbhead) {          for (tmp = map->header.next; tmp != &map->header; tmp = tmp->next) {
                 if (tmp->space != uvm_rb_subtree_space(tmp)) {                  if (tmp->maxgap != uvm_rb_maxgap(tmp)) {
                         printf("space %lx != %lx\n",                          printf("maxgap %lx != %lx\n",
                             (ulong)tmp->space,                              (ulong)tmp->maxgap,
                             (ulong)uvm_rb_subtree_space(tmp));                              (ulong)uvm_rb_maxgap(tmp));
                         goto error;                          goto error;
                 }                  }
                 if (trtmp != NULL && trtmp->start >= tmp->start) {                  if (trtmp != NULL && trtmp->start >= tmp->start) {
Line 477  _uvm_tree_sanity(struct vm_map *map)
Line 571  _uvm_tree_sanity(struct vm_map *map)
                             trtmp->start, tmp->start);                              trtmp->start, tmp->start);
                         goto error;                          goto error;
                 }                  }
                 n++;  
   
                 trtmp = tmp;                  trtmp = tmp;
         }          }
   
         if (n != map->nentries) {          for (tmp = map->header.next; tmp != &map->header;
                 printf("nentries: %d vs %d\n", n, map->nentries);  
                 goto error;  
         }  
   
         for (tmp = map->header.next; tmp && tmp != &map->header;  
             tmp = tmp->next, i++) {              tmp = tmp->next, i++) {
                 trtmp = RB_FIND(uvm_tree, &map->rbhead, tmp);                  trtmp = (void *) rb_tree_iterate(&map->rb_tree, &tmp->rb_node,
                       RB_DIR_LEFT);
                   if (trtmp == NULL)
                           trtmp = &map->header;
                   if (tmp->prev != trtmp) {
                           printf("lookup: %d: %p->prev=%p: %p\n",
                               i, tmp, tmp->prev, trtmp);
                           goto error;
                   }
                   trtmp = (void *) rb_tree_iterate(&map->rb_tree, &tmp->rb_node,
                       RB_DIR_RIGHT);
                   if (trtmp == NULL)
                           trtmp = &map->header;
                   if (tmp->next != trtmp) {
                           printf("lookup: %d: %p->next=%p: %p\n",
                               i, tmp, tmp->next, trtmp);
                           goto error;
                   }
                   trtmp = (void *)rb_tree_find_node(&map->rb_tree, &tmp->start);
                 if (trtmp != tmp) {                  if (trtmp != tmp) {
                         printf("lookup: %d: %p - %p: %p\n", i, tmp, trtmp,                          printf("lookup: %d: %p - %p: %p\n", i, tmp, trtmp,
                             RB_PARENT(tmp, rb_entry));                              PARENT_ENTRY(map, tmp));
                         goto error;                          goto error;
                 }                  }
         }          }
Line 1064  uvm_map(struct vm_map *map, vaddr_t *sta
Line 1170  uvm_map(struct vm_map *map, vaddr_t *sta
          * for pager_map, allocate the new entry first to avoid sleeping           * for pager_map, allocate the new entry first to avoid sleeping
          * for memory while we have the map locked.           * for memory while we have the map locked.
          *           *
          * besides, because we allocates entries for in-kernel maps           * Also, because we allocate entries for in-kernel maps
          * a bit differently (cf. uvm_kmapent_alloc/free), we need to           * a bit differently (cf. uvm_kmapent_alloc/free), we need to
          * allocate them before locking the map.           * allocate them before locking the map.
          */           */
Line 1338  uvm_map_enter(struct vm_map *map, const 
Line 1444  uvm_map_enter(struct vm_map *map, const 
                 if (uobj && uobj->pgops->pgo_detach)                  if (uobj && uobj->pgops->pgo_detach)
                         uobj->pgops->pgo_detach(uobj);                          uobj->pgops->pgo_detach(uobj);
   
                   /*
                    * Now that we've merged the entries, note that we've grown
                    * and our gap has shrunk.  Then fix the tree.
                    */
                 prev_entry->end += size;                  prev_entry->end += size;
                   prev_entry->gap -= size;
                 uvm_rb_fixup(map, prev_entry);                  uvm_rb_fixup(map, prev_entry);
   
                 uvm_map_check(map, "map backmerged");                  uvm_map_check(map, "map backmerged");
Line 1465  forwardmerge:
Line 1576  forwardmerge:
                         }                          }
                 } else {                  } else {
                         prev_entry->next->start -= size;                          prev_entry->next->start -= size;
                         if (prev_entry != &map->header)                          if (prev_entry != &map->header) {
                                   prev_entry->gap -= size;
                                   KASSERT(prev_entry->gap == uvm_rb_gap(prev_entry));
                                 uvm_rb_fixup(map, prev_entry);                                  uvm_rb_fixup(map, prev_entry);
                           }
                         if (uobj)                          if (uobj)
                                 prev_entry->next->offset = uoffset;                                  prev_entry->next->offset = uoffset;
                 }                  }
Line 1582  done:
Line 1696  done:
  * uvm_map_lookup_entry_bytree: lookup an entry in tree   * uvm_map_lookup_entry_bytree: lookup an entry in tree
  */   */
   
 static bool  static inline bool
 uvm_map_lookup_entry_bytree(struct vm_map *map, vaddr_t address,  uvm_map_lookup_entry_bytree(struct vm_map *map, vaddr_t address,
     struct vm_map_entry **entry /* OUT */)      struct vm_map_entry **entry /* OUT */)
 {  {
         struct vm_map_entry *prev = &map->header;          struct vm_map_entry *prev = &map->header;
         struct vm_map_entry *cur = RB_ROOT(&map->rbhead);          struct vm_map_entry *cur = ROOT_ENTRY(map);
   
         while (cur) {          while (cur) {
                   UVMMAP_EVCNT_INCR(mlk_treeloop);
                 if (address >= cur->start) {                  if (address >= cur->start) {
                         if (address < cur->end) {                          if (address < cur->end) {
                                 *entry = cur;                                  *entry = cur;
                                 return true;                                  return true;
                         }                          }
                         prev = cur;                          prev = cur;
                         cur = RB_RIGHT(cur, rb_entry);                          cur = RIGHT_ENTRY(cur);
                 } else                  } else
                         cur = RB_LEFT(cur, rb_entry);                          cur = LEFT_ENTRY(cur);
         }          }
         *entry = prev;          *entry = prev;
         return false;          return false;
Line 1658  uvm_map_lookup_entry(struct vm_map *map,
Line 1773  uvm_map_lookup_entry(struct vm_map *map,
                         return (true);                          return (true);
                 }                  }
   
                 if (map->nentries > 30)                  if (map->nentries > 15)
                         use_tree = true;                          use_tree = true;
         } else {          } else {
   
Line 1675  uvm_map_lookup_entry(struct vm_map *map,
Line 1790  uvm_map_lookup_entry(struct vm_map *map,
                  * Simple lookup in the tree.  Happens when the hint is                   * Simple lookup in the tree.  Happens when the hint is
                  * invalid, or nentries reach a threshold.                   * invalid, or nentries reach a threshold.
                  */                   */
                   UVMMAP_EVCNT_INCR(mlk_tree);
                 if (uvm_map_lookup_entry_bytree(map, address, entry)) {                  if (uvm_map_lookup_entry_bytree(map, address, entry)) {
                         goto got;                          goto got;
                 } else {                  } else {
Line 1686  uvm_map_lookup_entry(struct vm_map *map,
Line 1802  uvm_map_lookup_entry(struct vm_map *map,
          * search linearly           * search linearly
          */           */
   
           UVMMAP_EVCNT_INCR(mlk_list);
         while (cur != &map->header) {          while (cur != &map->header) {
                   UVMMAP_EVCNT_INCR(mlk_listloop);
                 if (cur->end > address) {                  if (cur->end > address) {
                         if (address >= cur->start) {                          if (address >= cur->start) {
                                 /*                                  /*
Line 1914  uvm_map_findspace(struct vm_map *map, va
Line 2032  uvm_map_findspace(struct vm_map *map, va
 nextgap:  nextgap:
         KDASSERT((flags & UVM_FLAG_FIXED) == 0);          KDASSERT((flags & UVM_FLAG_FIXED) == 0);
         /* If there is not enough space in the whole tree, we fail */          /* If there is not enough space in the whole tree, we fail */
         tmp = RB_ROOT(&map->rbhead);          tmp = ROOT_ENTRY(map);
         if (tmp == NULL || tmp->space < length)          if (tmp == NULL || tmp->maxgap < length)
                 goto notfound;                  goto notfound;
   
         prev = NULL; /* previous candidate */          prev = NULL; /* previous candidate */
   
         /* Find an entry close to hint that has enough space */          /* Find an entry close to hint that has enough space */
         for (; tmp;) {          for (; tmp;) {
                 KASSERT(tmp->next->start == tmp->end + tmp->ownspace);                  KASSERT(tmp->next->start == tmp->end + tmp->gap);
                 if (topdown) {                  if (topdown) {
                         if (tmp->next->start < hint + length &&                          if (tmp->next->start < hint + length &&
                             (prev == NULL || tmp->end > prev->end)) {                              (prev == NULL || tmp->end > prev->end)) {
                                 if (tmp->ownspace >= length)                                  if (tmp->gap >= length)
                                         prev = tmp;                                          prev = tmp;
                                 else if ((child = RB_LEFT(tmp, rb_entry))                                  else if ((child = LEFT_ENTRY(tmp)) != NULL
                                     != NULL && child->space >= length)                                      && child->maxgap >= length)
                                         prev = tmp;                                          prev = tmp;
                         }                          }
                 } else {                  } else {
                         if (tmp->end >= hint &&                          if (tmp->end >= hint &&
                             (prev == NULL || tmp->end < prev->end)) {                              (prev == NULL || tmp->end < prev->end)) {
                                 if (tmp->ownspace >= length)                                  if (tmp->gap >= length)
                                         prev = tmp;                                          prev = tmp;
                                 else if ((child = RB_RIGHT(tmp, rb_entry))                                  else if ((child = RIGHT_ENTRY(tmp)) != NULL
                                     != NULL && child->space >= length)                                      && child->maxgap >= length)
                                         prev = tmp;                                          prev = tmp;
                         }                          }
                 }                  }
                 if (tmp->next->start < hint + length)                  if (tmp->next->start < hint + length)
                         child = RB_RIGHT(tmp, rb_entry);                          child = RIGHT_ENTRY(tmp);
                 else if (tmp->end > hint)                  else if (tmp->end > hint)
                         child = RB_LEFT(tmp, rb_entry);                          child = LEFT_ENTRY(tmp);
                 else {                  else {
                         if (tmp->ownspace >= length)                          if (tmp->gap >= length)
                                 break;                                  break;
                         if (topdown)                          if (topdown)
                                 child = RB_LEFT(tmp, rb_entry);                                  child = LEFT_ENTRY(tmp);
                         else                          else
                                 child = RB_RIGHT(tmp, rb_entry);                                  child = RIGHT_ENTRY(tmp);
                 }                  }
                 if (child == NULL || child->space < length)                  if (child == NULL || child->maxgap < length)
                         break;                          break;
                 tmp = child;                  tmp = child;
         }          }
Line 1979  nextgap:
Line 2097  nextgap:
                 case -1:                  case -1:
                         goto wraparound;                          goto wraparound;
                 }                  }
                 if (tmp->ownspace >= length)                  if (tmp->gap >= length)
                         goto listsearch;                          goto listsearch;
         }          }
         if (prev == NULL)          if (prev == NULL)
Line 2001  nextgap:
Line 2119  nextgap:
         case -1:          case -1:
                 goto wraparound;                  goto wraparound;
         }          }
         if (prev->ownspace >= length)          if (prev->gap >= length)
                 goto listsearch;                  goto listsearch;
   
         if (topdown)          if (topdown)
                 tmp = RB_LEFT(prev, rb_entry);                  tmp = LEFT_ENTRY(prev);
         else          else
                 tmp = RB_RIGHT(prev, rb_entry);                  tmp = RIGHT_ENTRY(prev);
         for (;;) {          for (;;) {
                 KASSERT(tmp && tmp->space >= length);                  KASSERT(tmp && tmp->maxgap >= length);
                 if (topdown)                  if (topdown)
                         child = RB_RIGHT(tmp, rb_entry);                          child = RIGHT_ENTRY(tmp);
                 else                  else
                         child = RB_LEFT(tmp, rb_entry);                          child = LEFT_ENTRY(tmp);
                 if (child && child->space >= length) {                  if (child && child->maxgap >= length) {
                         tmp = child;                          tmp = child;
                         continue;                          continue;
                 }                  }
                 if (tmp->ownspace >= length)                  if (tmp->gap >= length)
                         break;                          break;
                 if (topdown)                  if (topdown)
                         tmp = RB_LEFT(tmp, rb_entry);                          tmp = LEFT_ENTRY(tmp);
                 else                  else
                         tmp = RB_RIGHT(tmp, rb_entry);                          tmp = RIGHT_ENTRY(tmp);
         }          }
   
         if (topdown) {          if (topdown) {
Line 4516  again:
Line 4634  again:
   
         va = args.uma_start;          va = args.uma_start;
   
         pmap_kenter_pa(va, VM_PAGE_TO_PHYS(pg), VM_PROT_READ|VM_PROT_WRITE);          pmap_kenter_pa(va, VM_PAGE_TO_PHYS(pg),
               VM_PROT_READ|VM_PROT_WRITE|PMAP_KMPAGE);
         pmap_update(vm_map_pmap(map));          pmap_update(vm_map_pmap(map));
   
         ukh = (void *)va;          ukh = (void *)va;
Line 5032  uvm_map_setup(struct vm_map *map, vaddr_
Line 5151  uvm_map_setup(struct vm_map *map, vaddr_
 {  {
         int ipl;          int ipl;
   
         RB_INIT(&map->rbhead);          rb_tree_init(&map->rb_tree, &uvm_map_tree_ops);
         map->header.next = map->header.prev = &map->header;          map->header.next = map->header.prev = &map->header;
         map->nentries = 0;          map->nentries = 0;
         map->size = 0;          map->size = 0;

Legend:
Removed from v.1.254.4.1  
changed lines
  Added in v.1.254.4.2

CVSweb <webmaster@jp.NetBSD.org>