[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.354.4.1 and 1.354.4.2

version 1.354.4.1, 2019/06/10 22:09:58 version 1.354.4.2, 2020/04/13 08:05:21
Line 141  UVMMAP_EVCNT_DEFINE(knomerge)
Line 141  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_tree)
 UVMMAP_EVCNT_DEFINE(mlk_treeloop)  UVMMAP_EVCNT_DEFINE(mlk_treeloop)
 UVMMAP_EVCNT_DEFINE(mlk_listloop)  
   
 const char vmmapbsy[] = "vmmapbsy";  const char vmmapbsy[] = "vmmapbsy";
   
Line 187  int user_va0_disable = __USER_VA0_DISABL
Line 185  int user_va0_disable = __USER_VA0_DISABL
  */   */
   
 /*  /*
    * uvm_map_align_va: round down or up virtual address
    */
   static __inline void
   uvm_map_align_va(vaddr_t *vap, vsize_t align, int topdown)
   {
   
           KASSERT(powerof2(align));
   
           if (align != 0 && (*vap & (align - 1)) != 0) {
                   if (topdown)
                           *vap = rounddown2(*vap, align);
                   else
                           *vap = roundup2(*vap, align);
           }
   }
   
   /*
  * UVM_ET_ISCOMPATIBLE: check some requirements for map entry merging   * UVM_ET_ISCOMPATIBLE: check some requirements for map entry merging
  */   */
 extern struct vm_map *pager_map;  extern struct vm_map *pager_map;
Line 806  static inline void
Line 821  static inline void
 uvm_mapent_copy(struct vm_map_entry *src, struct vm_map_entry *dst)  uvm_mapent_copy(struct vm_map_entry *src, struct vm_map_entry *dst)
 {  {
   
         memcpy(dst, src, ((char *)&src->uvm_map_entry_stop_copy) -          memcpy(dst, src, sizeof(*dst));
             ((char *)src));          dst->flags = 0;
 }  }
   
 #if defined(DEBUG)  #if defined(DEBUG)
Line 923  uvm_map_init_caches(void)
Line 938  uvm_map_init_caches(void)
          */           */
   
         pool_cache_bootstrap(&uvm_map_entry_cache, sizeof(struct vm_map_entry),          pool_cache_bootstrap(&uvm_map_entry_cache, sizeof(struct vm_map_entry),
             0, 0, 0, "vmmpepl", NULL, IPL_NONE, NULL, NULL, NULL);              coherency_unit, 0, PR_LARGECACHE, "vmmpepl", NULL, IPL_NONE, NULL,
               NULL, NULL);
         pool_cache_bootstrap(&uvm_vmspace_cache, sizeof(struct vmspace),          pool_cache_bootstrap(&uvm_vmspace_cache, sizeof(struct vmspace),
             0, 0, 0, "vmsppl", NULL, IPL_NONE, NULL, NULL, NULL);              0, 0, 0, "vmsppl", NULL, IPL_NONE, NULL, NULL, NULL);
 }  }
Line 1063  uvm_map(struct vm_map *map, vaddr_t *sta
Line 1079  uvm_map(struct vm_map *map, vaddr_t *sta
         int error;          int error;
   
         KASSERT((size & PAGE_MASK) == 0);          KASSERT((size & PAGE_MASK) == 0);
           KASSERT((flags & UVM_FLAG_FIXED) == 0 || align == 0);
   
         /*          /*
          * for pager_map, allocate the new entry first to avoid sleeping           * for pager_map, allocate the new entry first to avoid sleeping
Line 1661  uvm_map_lookup_entry(struct vm_map *map,
Line 1678  uvm_map_lookup_entry(struct vm_map *map,
     struct vm_map_entry **entry /* OUT */)      struct vm_map_entry **entry /* OUT */)
 {  {
         struct vm_map_entry *cur;          struct vm_map_entry *cur;
         bool use_tree = false;  
         UVMHIST_FUNC("uvm_map_lookup_entry");          UVMHIST_FUNC("uvm_map_lookup_entry");
         UVMHIST_CALLED(maphist);          UVMHIST_CALLED(maphist);
   
Line 1669  uvm_map_lookup_entry(struct vm_map *map,
Line 1685  uvm_map_lookup_entry(struct vm_map *map,
             (uintptr_t)map, address, (uintptr_t)entry, 0);              (uintptr_t)map, address, (uintptr_t)entry, 0);
   
         /*          /*
          * start looking either from the head of the           * make a quick check to see if we are already looking at
          * list, or from the hint.           * the entry we want (which is usually the case).  note also
            * that we don't need to save the hint here...  it is the
            * same hint (unless we are at the header, in which case the
            * hint didn't buy us anything anyway).
          */           */
   
         cur = map->hint;          cur = map->hint;
   
         if (cur == &map->header)  
                 cur = cur->next;  
   
         UVMMAP_EVCNT_INCR(mlk_call);          UVMMAP_EVCNT_INCR(mlk_call);
         if (address >= cur->start) {          if (cur != &map->header &&
               address >= cur->start && cur->end > address) {
                 /*                  UVMMAP_EVCNT_INCR(mlk_hint);
                  * go from hint to end of list.                  *entry = cur;
                  *                  UVMHIST_LOG(maphist,"<- got it via hint (%#jx)",
                  * but first, make a quick check to see if                      (uintptr_t)cur, 0, 0, 0);
                  * we are already looking at the entry we                  uvm_mapent_check(*entry);
                  * want (which is usually the case).                  return (true);
                  * note also that we don't need to save the hint  
                  * here... it is the same hint (unless we are  
                  * at the header, in which case the hint didn't  
                  * buy us anything anyway).  
                  */  
   
                 if (cur != &map->header && cur->end > address) {  
                         UVMMAP_EVCNT_INCR(mlk_hint);  
                         *entry = cur;  
                         UVMHIST_LOG(maphist,"<- got it via hint (%#jx)",  
                             (uintptr_t)cur, 0, 0, 0);  
                         uvm_mapent_check(*entry);  
                         return (true);  
                 }  
   
                 if (map->nentries > 15)  
                         use_tree = true;  
         } else {  
   
                 /*  
                  * invalid hint.  use tree.  
                  */  
                 use_tree = true;  
         }          }
   
         uvm_map_check(map, __func__);          uvm_map_check(map, __func__);
   
         if (use_tree) {  
                 /*  
                  * Simple lookup in the tree.  Happens when the hint is  
                  * invalid, or nentries reach a threshold.  
                  */  
                 UVMMAP_EVCNT_INCR(mlk_tree);  
                 if (uvm_map_lookup_entry_bytree(map, address, entry)) {  
                         goto got;  
                 } else {  
                         goto failed;  
                 }  
         }  
   
         /*          /*
          * search linearly           * lookup in the tree.
          */           */
   
         UVMMAP_EVCNT_INCR(mlk_list);          UVMMAP_EVCNT_INCR(mlk_tree);
         while (cur != &map->header) {          if (__predict_true(uvm_map_lookup_entry_bytree(map, address, entry))) {
                 UVMMAP_EVCNT_INCR(mlk_listloop);                  SAVE_HINT(map, map->hint, *entry);
                 if (cur->end > address) {                  UVMHIST_LOG(maphist,"<- search got it (%#jx)",
                         if (address >= cur->start) {                      (uintptr_t)cur, 0, 0, 0);
                                 /*                  KDASSERT((*entry)->start <= address);
                                  * save this lookup for future                  KDASSERT(address < (*entry)->end);
                                  * hints, and return                  uvm_mapent_check(*entry);
                                  */                  return (true);
   
                                 *entry = cur;  
 got:  
                                 SAVE_HINT(map, map->hint, *entry);  
                                 UVMHIST_LOG(maphist,"<- search got it (%#jx)",  
                                         (uintptr_t)cur, 0, 0, 0);  
                                 KDASSERT((*entry)->start <= address);  
                                 KDASSERT(address < (*entry)->end);  
                                 uvm_mapent_check(*entry);  
                                 return (true);  
                         }  
                         break;  
                 }  
                 cur = cur->next;  
         }          }
         *entry = cur->prev;  
 failed:  
         SAVE_HINT(map, map->hint, *entry);          SAVE_HINT(map, map->hint, *entry);
         UVMHIST_LOG(maphist,"<- failed!",0,0,0,0);          UVMHIST_LOG(maphist,"<- failed!",0,0,0,0);
         KDASSERT((*entry) == &map->header || (*entry)->end <= address);          KDASSERT((*entry) == &map->header || (*entry)->end <= address);
Line 1805  uvm_map_space_avail(vaddr_t *start, vsiz
Line 1768  uvm_map_space_avail(vaddr_t *start, vsiz
                                 *start = ptoa(hint + align); /* adjust to color */                                  *start = ptoa(hint + align); /* adjust to color */
                         }                          }
                 }                  }
         } else if (align != 0) {          } else {
                 if ((*start & (align - 1)) != 0) {                  KASSERT(powerof2(align));
                         if (topdown)                  uvm_map_align_va(start, align, topdown);
                                 *start &= ~(align - 1);  
                         else  
                                 *start = roundup(*start, align);  
                 }  
                 /*                  /*
                  * XXX Should we PMAP_PREFER() here again?                   * XXX Should we PMAP_PREFER() here again?
                  * eh...i think we're okay                   * eh...i think we're okay
Line 1861  uvm_map_findspace(struct vm_map *map, va
Line 1820  uvm_map_findspace(struct vm_map *map, va
   
         UVMHIST_LOG(maphist, "(map=%#jx, hint=%#jx, len=%ju, flags=%#jx)",          UVMHIST_LOG(maphist, "(map=%#jx, hint=%#jx, len=%ju, flags=%#jx)",
             (uintptr_t)map, hint, length, flags);              (uintptr_t)map, hint, length, flags);
         KASSERT((flags & UVM_FLAG_COLORMATCH) != 0 || (align & (align - 1)) == 0);          KASSERT((flags & UVM_FLAG_COLORMATCH) != 0 || powerof2(align));
         KASSERT((flags & UVM_FLAG_COLORMATCH) == 0 || align < uvmexp.ncolors);          KASSERT((flags & UVM_FLAG_COLORMATCH) == 0 || align < uvmexp.ncolors);
         KASSERT((flags & UVM_FLAG_FIXED) == 0 || align == 0);          KASSERT((flags & UVM_FLAG_FIXED) == 0 || align == 0);
   
Line 1888  uvm_map_findspace(struct vm_map *map, va
Line 1847  uvm_map_findspace(struct vm_map *map, va
         }          }
   
         /*          /*
            * hint may not be aligned properly; we need round up or down it
            * before proceeding further.
            */
           if ((flags & UVM_FLAG_COLORMATCH) == 0)
                   uvm_map_align_va(&hint, align, topdown);
   
           /*
          * Look for the first possible address; if there's already           * Look for the first possible address; if there's already
          * something at this address, we have to start after it.           * something at this address, we have to start after it.
          */           */
Line 2219  uvm_unmap_remove(struct vm_map *map, vad
Line 2185  uvm_unmap_remove(struct vm_map *map, vad
         }          }
   
         /*          /*
          * Save the free space hint           * save the free space hint
          */           */
   
         if (map->first_free != &map->header && map->first_free->start >= start)          if (map->first_free != &map->header && map->first_free->start >= start)
Line 2291  uvm_unmap_remove(struct vm_map *map, vad
Line 2257  uvm_unmap_remove(struct vm_map *map, vad
                          * change while in pmap_remove().                           * change while in pmap_remove().
                          */                           */
   
                         uvm_map_lock_entry(entry);  #ifdef __HAVE_UNLOCKED_PMAP /* XXX temporary */
                           uvm_map_lock_entry(entry, RW_WRITER);
   #else
                           uvm_map_lock_entry(entry, RW_READER);
   #endif
                         pmap_remove(map->pmap, entry->start, entry->end);                          pmap_remove(map->pmap, entry->start, entry->end);
   
                           /*
                            * note: if map is dying, leave pmap_update() for
                            * later.  if the map is to be reused (exec) then
                            * pmap_update() will be called.  if the map is
                            * being disposed of (exit) then pmap_destroy()
                            * will be called.
                            */
   
                           if ((map->flags & VM_MAP_DYING) == 0) {
                                   pmap_update(vm_map_pmap(map));
                           } else {
                                   KASSERT(vm_map_pmap(map) != pmap_kernel());
                           }
   
                         uvm_map_unlock_entry(entry);                          uvm_map_unlock_entry(entry);
                 }                  }
   
Line 2337  uvm_unmap_remove(struct vm_map *map, vad
Line 2322  uvm_unmap_remove(struct vm_map *map, vad
                 entry = next;                  entry = next;
         }          }
   
         /*  
          * Note: if map is dying, leave pmap_update() for pmap_destroy(),  
          * which will be called later.  
          */  
         if ((map->flags & VM_MAP_DYING) == 0) {  
                 pmap_update(vm_map_pmap(map));  
         } else {  
                 KASSERT(vm_map_pmap(map) != pmap_kernel());  
         }  
   
         uvm_map_check(map, "unmap_remove leave");          uvm_map_check(map, "unmap_remove leave");
   
         /*          /*
Line 2864  uvm_map_extract(struct vm_map *srcmap, v
Line 2839  uvm_map_extract(struct vm_map *srcmap, v
   
                         /* we advance "entry" in the following if statement */                          /* we advance "entry" in the following if statement */
                         if (flags & UVM_EXTRACT_REMOVE) {                          if (flags & UVM_EXTRACT_REMOVE) {
                                 uvm_map_lock_entry(entry);  #ifdef __HAVE_UNLOCKED_PMAP /* XXX temporary */
                                   uvm_map_lock_entry(entry, RW_WRITER);
   #else
                                   uvm_map_lock_entry(entry, RW_READER);
   #endif
                                 pmap_remove(srcmap->pmap, entry->start,                                  pmap_remove(srcmap->pmap, entry->start,
                                                 entry->end);                                                  entry->end);
                                 uvm_map_unlock_entry(entry);                                  uvm_map_unlock_entry(entry);
Line 3096  uvm_map_protect(struct vm_map *map, vadd
Line 3075  uvm_map_protect(struct vm_map *map, vadd
   
                 if (current->protection != old_prot) {                  if (current->protection != old_prot) {
                         /* update pmap! */                          /* update pmap! */
                         uvm_map_lock_entry(current);  #ifdef __HAVE_UNLOCKED_PMAP /* XXX temporary */
                           uvm_map_lock_entry(current, RW_WRITER);
   #else
                           uvm_map_lock_entry(current, RW_READER);
   #endif
                         pmap_protect(map->pmap, current->start, current->end,                          pmap_protect(map->pmap, current->start, current->end,
                             current->protection & MASK(current));                              current->protection & MASK(current));
                         uvm_map_unlock_entry(current);                          uvm_map_unlock_entry(current);
Line 3829  uvm_map_clean(struct vm_map *map, vaddr_
Line 3812  uvm_map_clean(struct vm_map *map, vaddr_
         struct vm_map_entry *current, *entry;          struct vm_map_entry *current, *entry;
         struct uvm_object *uobj;          struct uvm_object *uobj;
         struct vm_amap *amap;          struct vm_amap *amap;
         struct vm_anon *anon, *anon_tofree;          struct vm_anon *anon;
         struct vm_page *pg;          struct vm_page *pg;
         vaddr_t offset;          vaddr_t offset;
         vsize_t size;          vsize_t size;
Line 3890  uvm_map_clean(struct vm_map *map, vaddr_
Line 3873  uvm_map_clean(struct vm_map *map, vaddr_
   
                 offset = start - current->start;                  offset = start - current->start;
                 size = MIN(end, current->end) - start;                  size = MIN(end, current->end) - start;
                 anon_tofree = NULL;  
   
                 amap_lock(amap);                  amap_lock(amap, RW_WRITER);
                 for ( ; size != 0; size -= PAGE_SIZE, offset += PAGE_SIZE) {                  for ( ; size != 0; size -= PAGE_SIZE, offset += PAGE_SIZE) {
                         anon = amap_lookup(&current->aref, offset);                          anon = amap_lookup(&current->aref, offset);
                         if (anon == NULL)                          if (anon == NULL)
Line 3923  uvm_map_clean(struct vm_map *map, vaddr_
Line 3905  uvm_map_clean(struct vm_map *map, vaddr_
                                  * at all in these cases.                                   * at all in these cases.
                                  */                                   */
   
                                 mutex_enter(&uvm_pageqlock);  
                                 if (pg->loan_count != 0 ||                                  if (pg->loan_count != 0 ||
                                     pg->wire_count != 0) {                                      pg->wire_count != 0) {
                                         mutex_exit(&uvm_pageqlock);  
                                         continue;                                          continue;
                                 }                                  }
                                 KASSERT(pg->uanon == anon);                                  KASSERT(pg->uanon == anon);
                                   uvm_pagelock(pg);
                                 uvm_pagedeactivate(pg);                                  uvm_pagedeactivate(pg);
                                 mutex_exit(&uvm_pageqlock);                                  uvm_pageunlock(pg);
                                 continue;                                  continue;
   
                         case PGO_FREE:                          case PGO_FREE:
Line 3951  uvm_map_clean(struct vm_map *map, vaddr_
Line 3932  uvm_map_clean(struct vm_map *map, vaddr_
                                 amap_unadd(&current->aref, offset);                                  amap_unadd(&current->aref, offset);
                                 refs = --anon->an_ref;                                  refs = --anon->an_ref;
                                 if (refs == 0) {                                  if (refs == 0) {
                                         anon->an_link = anon_tofree;                                          uvm_anfree(anon);
                                         anon_tofree = anon;  
                                 }                                  }
                                 continue;                                  continue;
                         }                          }
                 }                  }
                 uvm_anon_freelst(amap, anon_tofree);                  amap_unlock(amap);
   
  flush_object:   flush_object:
                 /*                  /*
Line 3970  uvm_map_clean(struct vm_map *map, vaddr_
Line 3950  uvm_map_clean(struct vm_map *map, vaddr_
                 uoff = current->offset + (start - current->start);                  uoff = current->offset + (start - current->start);
                 size = MIN(end, current->end) - start;                  size = MIN(end, current->end) - start;
                 if (uobj != NULL) {                  if (uobj != NULL) {
                         mutex_enter(uobj->vmobjlock);                          rw_enter(uobj->vmobjlock, RW_WRITER);
                         if (uobj->pgops->pgo_put != NULL)                          if (uobj->pgops->pgo_put != NULL)
                                 error = (uobj->pgops->pgo_put)(uobj, uoff,                                  error = (uobj->pgops->pgo_put)(uobj, uoff,
                                     uoff + size, flags | PGO_CLEANIT);                                      uoff + size, flags | PGO_CLEANIT);
Line 4154  uvmspace_exec(struct lwp *l, vaddr_t sta
Line 4134  uvmspace_exec(struct lwp *l, vaddr_t sta
         struct proc *p = l->l_proc;          struct proc *p = l->l_proc;
         struct vmspace *nvm, *ovm = p->p_vmspace;          struct vmspace *nvm, *ovm = p->p_vmspace;
         struct vm_map *map;          struct vm_map *map;
           int flags;
   
         KASSERT(ovm != NULL);          KASSERT(ovm != NULL);
 #ifdef __HAVE_CPU_VMSPACE_EXEC  #ifdef __HAVE_CPU_VMSPACE_EXEC
Line 4189  uvmspace_exec(struct lwp *l, vaddr_t sta
Line 4170  uvmspace_exec(struct lwp *l, vaddr_t sta
                 map->flags &= ~VM_MAP_WIREFUTURE;                  map->flags &= ~VM_MAP_WIREFUTURE;
   
                 /*                  /*
                  * now unmap the old program                   * now unmap the old program.
                  */                   *
                    * XXX set VM_MAP_DYING for the duration, so pmap_update()
                 pmap_remove_all(map->pmap);                   * is not called until the pmap has been totally cleared out
                 uvm_unmap(map, vm_map_min(map), vm_map_max(map));                   * after pmap_remove_all(), or it can confuse some pmap
                    * implementations.  it would be nice to handle this by
                    * deferring the pmap_update() while it is known the address
                    * space is not visible to any user LWP other than curlwp,
                    * but there isn't an elegant way of inferring that right
                    * now.
                    */
   
                   flags = pmap_remove_all(map->pmap) ? UVM_FLAG_VAONLY : 0;
                   map->flags |= VM_MAP_DYING;
                   uvm_unmap1(map, vm_map_min(map), vm_map_max(map), flags);
                   map->flags &= ~VM_MAP_DYING;
                   pmap_update(map->pmap);
                 KASSERT(map->header.prev == &map->header);                  KASSERT(map->header.prev == &map->header);
                 KASSERT(map->nentries == 0);                  KASSERT(map->nentries == 0);
   
Line 4228  uvmspace_exec(struct lwp *l, vaddr_t sta
Line 4221  uvmspace_exec(struct lwp *l, vaddr_t sta
 }  }
   
 /*  /*
  * uvmspace_addref: add a referece to a vmspace.   * uvmspace_addref: add a reference to a vmspace.
  */   */
   
 void  void
 uvmspace_addref(struct vmspace *vm)  uvmspace_addref(struct vmspace *vm)
 {  {
         struct vm_map *map = &vm->vm_map;  
   
         KASSERT((map->flags & VM_MAP_DYING) == 0);  
   
         mutex_enter(&map->misc_lock);          KASSERT((vm->vm_map.flags & VM_MAP_DYING) == 0);
         KASSERT(vm->vm_refcnt > 0);          KASSERT(vm->vm_refcnt > 0);
         vm->vm_refcnt++;          atomic_inc_uint(&vm->vm_refcnt);
         mutex_exit(&map->misc_lock);  
 }  }
   
 /*  /*
Line 4253  uvmspace_free(struct vmspace *vm)
Line 4242  uvmspace_free(struct vmspace *vm)
 {  {
         struct vm_map_entry *dead_entries;          struct vm_map_entry *dead_entries;
         struct vm_map *map = &vm->vm_map;          struct vm_map *map = &vm->vm_map;
         int n;          int flags;
   
         UVMHIST_FUNC("uvmspace_free"); UVMHIST_CALLED(maphist);          UVMHIST_FUNC("uvmspace_free"); UVMHIST_CALLED(maphist);
   
         UVMHIST_LOG(maphist,"(vm=%#jx) ref=%jd", (uintptr_t)vm, vm->vm_refcnt,          UVMHIST_LOG(maphist,"(vm=%#jx) ref=%jd", (uintptr_t)vm, vm->vm_refcnt,
             0, 0);              0, 0);
         mutex_enter(&map->misc_lock);          if (atomic_dec_uint_nv(&vm->vm_refcnt) > 0)
         n = --vm->vm_refcnt;  
         mutex_exit(&map->misc_lock);  
         if (n > 0)  
                 return;                  return;
   
         /*          /*
Line 4271  uvmspace_free(struct vmspace *vm)
Line 4257  uvmspace_free(struct vmspace *vm)
          */           */
   
         map->flags |= VM_MAP_DYING;          map->flags |= VM_MAP_DYING;
         pmap_remove_all(map->pmap);          flags = pmap_remove_all(map->pmap) ? UVM_FLAG_VAONLY : 0;
   
         /* Get rid of any SYSV shared memory segments. */          /* Get rid of any SYSV shared memory segments. */
         if (uvm_shmexit && vm->vm_shm != NULL)          if (uvm_shmexit && vm->vm_shm != NULL)
Line 4279  uvmspace_free(struct vmspace *vm)
Line 4265  uvmspace_free(struct vmspace *vm)
   
         if (map->nentries) {          if (map->nentries) {
                 uvm_unmap_remove(map, vm_map_min(map), vm_map_max(map),                  uvm_unmap_remove(map, vm_map_min(map), vm_map_max(map),
                     &dead_entries, 0);                      &dead_entries, flags);
                 if (dead_entries != NULL)                  if (dead_entries != NULL)
                         uvm_unmap_detach(dead_entries, 0);                          uvm_unmap_detach(dead_entries, 0);
         }          }
Line 4446  uvm_mapent_forkcopy(struct vm_map *new_m
Line 4432  uvm_mapent_forkcopy(struct vm_map *new_m
                 if (old_entry->aref.ar_amap &&                  if (old_entry->aref.ar_amap &&
                     !UVM_ET_ISNEEDSCOPY(old_entry)) {                      !UVM_ET_ISNEEDSCOPY(old_entry)) {
                         if (old_entry->max_protection & VM_PROT_WRITE) {                          if (old_entry->max_protection & VM_PROT_WRITE) {
   #ifdef __HAVE_UNLOCKED_PMAP /* XXX temporary */
                                   uvm_map_lock_entry(old_entry, RW_WRITER);
   #else
                                   uvm_map_lock_entry(old_entry, RW_READER);
   #endif
                                 pmap_protect(old_map->pmap,                                  pmap_protect(old_map->pmap,
                                     old_entry->start, old_entry->end,                                      old_entry->start, old_entry->end,
                                     old_entry->protection & ~VM_PROT_WRITE);                                      old_entry->protection & ~VM_PROT_WRITE);
                                   uvm_map_unlock_entry(old_entry);
                         }                          }
                         old_entry->etype |= UVM_ET_NEEDSCOPY;                          old_entry->etype |= UVM_ET_NEEDSCOPY;
                 }                  }
Line 4728  uvm_unmap1(struct vm_map *map, vaddr_t s
Line 4720  uvm_unmap1(struct vm_map *map, vaddr_t s
         struct vm_map_entry *dead_entries;          struct vm_map_entry *dead_entries;
         UVMHIST_FUNC("uvm_unmap"); UVMHIST_CALLED(maphist);          UVMHIST_FUNC("uvm_unmap"); UVMHIST_CALLED(maphist);
   
         KASSERT(start < end);          KASSERTMSG(start < end,
               "%s: map %p: start %#jx < end %#jx", __func__, map,
               (uintmax_t)start, (uintmax_t)end);
         UVMHIST_LOG(maphist, "  (map=%#jx, start=%#jx, end=%#jx)",          UVMHIST_LOG(maphist, "  (map=%#jx, start=%#jx, end=%#jx)",
             (uintptr_t)map, start, end, 0);              (uintptr_t)map, start, end, 0);
         if (map == kernel_map) {          if (map == kernel_map) {
Line 4753  uvm_unmap1(struct vm_map *map, vaddr_t s
Line 4747  uvm_unmap1(struct vm_map *map, vaddr_t s
 /*  /*
  * uvm_map_reference: add reference to a map   * uvm_map_reference: add reference to a map
  *   *
  * => map need not be locked (we use misc_lock).   * => map need not be locked
  */   */
   
 void  void
 uvm_map_reference(struct vm_map *map)  uvm_map_reference(struct vm_map *map)
 {  {
         mutex_enter(&map->misc_lock);  
         map->ref_count++;  
         mutex_exit(&map->misc_lock);  
 }  
   
 bool          atomic_inc_uint(&map->ref_count);
 vm_map_starved_p(struct vm_map *map)  
 {  
   
         if ((map->flags & VM_MAP_WANTVA) != 0) {  
                 return true;  
         }  
         /* XXX */  
         if ((vm_map_max(map) - vm_map_min(map)) / 16 * 15 < map->size) {  
                 return true;  
         }  
         return false;  
 }  }
   
 void  void
 uvm_map_lock_entry(struct vm_map_entry *entry)  uvm_map_lock_entry(struct vm_map_entry *entry, krw_t op)
 {  {
   
         if (entry->aref.ar_amap != NULL) {          if (entry->aref.ar_amap != NULL) {
                 amap_lock(entry->aref.ar_amap);                  amap_lock(entry->aref.ar_amap, op);
         }          }
         if (UVM_ET_ISOBJ(entry)) {          if (UVM_ET_ISOBJ(entry)) {
                 mutex_enter(entry->object.uvm_obj->vmobjlock);                  rw_enter(entry->object.uvm_obj->vmobjlock, op);
         }          }
 }  }
   
Line 4795  uvm_map_unlock_entry(struct vm_map_entry
Line 4774  uvm_map_unlock_entry(struct vm_map_entry
 {  {
   
         if (UVM_ET_ISOBJ(entry)) {          if (UVM_ET_ISOBJ(entry)) {
                 mutex_exit(entry->object.uvm_obj->vmobjlock);                  rw_exit(entry->object.uvm_obj->vmobjlock);
         }          }
         if (entry->aref.ar_amap != NULL) {          if (entry->aref.ar_amap != NULL) {
                 amap_unlock(entry->aref.ar_amap);                  amap_unlock(entry->aref.ar_amap);
Line 4946  fill_vmentry(struct lwp *l, struct proc 
Line 4925  fill_vmentry(struct lwp *l, struct proc 
         kve->kve_offset = e->offset;          kve->kve_offset = e->offset;
         kve->kve_wired_count = e->wired_count;          kve->kve_wired_count = e->wired_count;
         kve->kve_inheritance = e->inheritance;          kve->kve_inheritance = e->inheritance;
         kve->kve_attributes = e->map_attrib;          kve->kve_attributes = 0; /* unused */
         kve->kve_advice = e->advice;          kve->kve_advice = e->advice;
 #define PROT(p) (((p) & VM_PROT_READ) ? KVME_PROT_READ : 0) | \  #define PROT(p) (((p) & VM_PROT_READ) ? KVME_PROT_READ : 0) | \
         (((p) & VM_PROT_WRITE) ? KVME_PROT_WRITE : 0) | \          (((p) & VM_PROT_WRITE) ? KVME_PROT_WRITE : 0) | \

Legend:
Removed from v.1.354.4.1  
changed lines
  Added in v.1.354.4.2

CVSweb <webmaster@jp.NetBSD.org>