amap_extend is called when merging two adjacent areas of virtual address
space. However, merging is done only for kernel
virtual address space. It's not done for user space:

uvm/uvm_map.c:1359
        /*
         * Try to merge entry.
         *
         * Userland allocations are kept separated most of the time.
         * Forego the effort of merging what most of the time can't be merged
         * and only try the merge if it concerns a kernel entry.
         */
        if ((flags & UVM_FLAG_NOMERGE) == 0 &&
            (map->flags & VM_MAP_ISVMSPACE) == 0)
                uvm_mapent_tryjoin(map, entry, &dead);


As far as I can tell, kernel vm_map_entries do not use amaps. So
amap_extend should never be called. Can we remove it?

Index: uvm/uvm_amap.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_amap.c,v
retrieving revision 1.62
diff -u -p -r1.62 uvm_amap.c
--- uvm/uvm_amap.c      16 Mar 2016 16:53:43 -0000      1.62
+++ uvm/uvm_amap.c      23 Mar 2016 17:03:53 -0000
@@ -279,174 +279,6 @@ amap_free(struct vm_amap *amap)
 }
 
 /*
- * amap_extend: extend the size of an amap (if needed)
- *
- * => called from uvm_map when we want to extend an amap to cover
- *    a new mapping (rather than allocate a new one)
- * => to safely extend an amap it should have a reference count of
- *    one (thus it can't be shared)
- * => XXXCDC: support padding at this level?
- */
-int
-amap_extend(struct vm_map_entry *entry, vsize_t addsize)
-{
-       struct vm_amap *amap = entry->aref.ar_amap;
-       int slotoff = entry->aref.ar_pageoff;
-       int slotmapped, slotadd, slotneed, slotalloc;
-#ifdef UVM_AMAP_PPREF
-       int *newppref, *oldppref;
-#endif
-       u_int *newsl, *newbck, *oldsl, *oldbck;
-       struct vm_anon **newover, **oldover;
-       int slotadded;
-
-       /*
-        * first, determine how many slots we need in the amap.  don't
-        * forget that ar_pageoff could be non-zero: this means that
-        * there are some unused slots before us in the amap.
-        */
-       AMAP_B2SLOT(slotmapped, entry->end - entry->start); /* slots mapped */
-       AMAP_B2SLOT(slotadd, addsize);                  /* slots to add */
-       slotneed = slotoff + slotmapped + slotadd;
-
-       /*
-        * case 1: we already have enough slots in the map and thus
-        * only need to bump the reference counts on the slots we are
-        * adding.
-        */
-       if (amap->am_nslot >= slotneed) {
-#ifdef UVM_AMAP_PPREF
-               if (amap->am_ppref && amap->am_ppref != PPREF_NONE) {
-                       amap_pp_adjref(amap, slotoff + slotmapped, slotadd, 1);
-               }
-#endif
-               return (0);
-       }
-
-       /*
-        * case 2: we pre-allocated slots for use and we just need to
-        * bump nslot up to take account for these slots.
-        */
-       if (amap->am_maxslot >= slotneed) {
-#ifdef UVM_AMAP_PPREF
-               if (amap->am_ppref && amap->am_ppref != PPREF_NONE) {
-                       if ((slotoff + slotmapped) < amap->am_nslot)
-                               amap_pp_adjref(amap, slotoff + slotmapped, 
-                                   (amap->am_nslot - (slotoff + slotmapped)),
-                                   1);
-                       pp_setreflen(amap->am_ppref, amap->am_nslot, 1, 
-                          slotneed - amap->am_nslot);
-               }
-#endif
-               amap->am_nslot = slotneed;
-               /*
-                * no need to zero am_anon since that was done at
-                * alloc time and we never shrink an allocation.
-                */
-               return (0);
-       }
-
-       /*
-        * case 3: we need to malloc a new amap and copy all the amap
-        * data over from old amap to the new one.
-        *
-        * XXXCDC: could we take advantage of a kernel realloc()?  
-        */
-       if (slotneed >= UVM_AMAP_LARGE)
-               return E2BIG;
-
-       if (slotneed > UVM_AMAP_CHUNK)
-               slotalloc = malloc_roundup(slotneed * MALLOC_SLOT_UNIT) /
-                   MALLOC_SLOT_UNIT;
-       else
-               slotalloc = slotneed;
-
-#ifdef UVM_AMAP_PPREF
-       newppref = NULL;
-       if (amap->am_ppref && amap->am_ppref != PPREF_NONE) {
-               newppref = mallocarray(slotalloc, sizeof(int), M_UVMAMAP,
-                   M_WAITOK | M_CANFAIL);
-               if (newppref == NULL) {
-                       /* give up if malloc fails */
-                       free(amap->am_ppref, M_UVMAMAP, 0);
-                       amap->am_ppref = PPREF_NONE;
-               }
-       }
-#endif
-       if (slotneed > UVM_AMAP_CHUNK)
-               newsl = malloc(slotalloc * MALLOC_SLOT_UNIT, M_UVMAMAP,
-                   M_WAITOK | M_CANFAIL);
-       else
-               newsl = pool_get(&uvm_amap_slot_pools[slotalloc - 1],
-                   PR_WAITOK | PR_LIMITFAIL);
-       if (newsl == NULL) {
-#ifdef UVM_AMAP_PPREF
-               if (newppref != NULL) {
-                       free(newppref, M_UVMAMAP, 0);
-               }
-#endif
-               return (ENOMEM);
-       }
-       newbck = (int *)(((char *)newsl) + slotalloc * sizeof(int));
-       newover = (struct vm_anon **)(((char *)newbck) + slotalloc *
-           sizeof(int));
-       KASSERT(amap->am_maxslot < slotneed);
-
-       /* now copy everything over to new malloc'd areas... */
-       slotadded = slotalloc - amap->am_nslot;
-
-       /* do am_slots */
-       oldsl = amap->am_slots;
-       memcpy(newsl, oldsl, sizeof(int) * amap->am_nused);
-       amap->am_slots = newsl;
-
-       /* do am_anon */
-       oldover = amap->am_anon;
-       memcpy(newover, oldover, sizeof(struct vm_anon *) * amap->am_nslot);
-       memset(newover + amap->am_nslot, 0, sizeof(struct vm_anon *) *
-           slotadded);
-       amap->am_anon = newover;
-
-       /* do am_bckptr */
-       oldbck = amap->am_bckptr;
-       memcpy(newbck, oldbck, sizeof(int) * amap->am_nslot);
-       memset(newbck + amap->am_nslot, 0, sizeof(int) * slotadded); /* XXX: 
needed? */
-       amap->am_bckptr = newbck;
-
-#ifdef UVM_AMAP_PPREF
-       /* do ppref */
-       oldppref = amap->am_ppref;
-       if (newppref) {
-               memcpy(newppref, oldppref, sizeof(int) * amap->am_nslot);
-               memset(newppref + amap->am_nslot, 0, sizeof(int) * slotadded);
-               amap->am_ppref = newppref;
-               if ((slotoff + slotmapped) < amap->am_nslot)
-                       amap_pp_adjref(amap, slotoff + slotmapped, 
-                           (amap->am_nslot - (slotoff + slotmapped)), 1);
-               pp_setreflen(newppref, amap->am_nslot, 1,
-                   slotneed - amap->am_nslot);
-       }
-#endif
-
-       /* free */
-       if (amap->am_maxslot > UVM_AMAP_CHUNK)
-               free(oldsl, M_UVMAMAP, 0);
-       else
-               pool_put(&uvm_amap_slot_pools[amap->am_maxslot - 1],
-                   oldsl);
-
-       /* and update master values */
-       amap->am_nslot = slotneed;
-       amap->am_maxslot = slotalloc;
-
-#ifdef UVM_AMAP_PPREF
-       if (oldppref && oldppref != PPREF_NONE)
-               free(oldppref, M_UVMAMAP, 0);
-#endif
-       return (0);
-}
-
-/*
  * amap_wipeout: wipeout all anon's in an amap; then free the amap!
  *
  * => called from amap_unref when the final reference to an amap is
Index: uvm/uvm_amap.h
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_amap.h,v
retrieving revision 1.21
diff -u -p -r1.21 uvm_amap.h
--- uvm/uvm_amap.h      6 Mar 2016 14:47:07 -0000       1.21
+++ uvm/uvm_amap.h      23 Mar 2016 17:03:53 -0000
@@ -72,8 +72,6 @@ void          amap_copy(vm_map_t, vm_map_entry_t
                    vaddr_t);
                                        /* resolve all COW faults now */
 void           amap_cow_now(vm_map_t, vm_map_entry_t);
-                                       /* make amap larger */
-int            amap_extend(vm_map_entry_t, vsize_t);
                                        /* get amap's flags */
 int            amap_flags(struct vm_amap *);
                                        /* free amap */
Index: uvm/uvm_map.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_map.c,v
retrieving revision 1.209
diff -u -p -r1.209 uvm_map.c
--- uvm/uvm_map.c       15 Mar 2016 20:50:23 -0000      1.209
+++ uvm/uvm_map.c       23 Mar 2016 17:03:54 -0000
@@ -1448,14 +1448,15 @@ uvm_mapent_merge(struct vm_map *map, str
        struct uvm_addr_state *free;
 
        /*
-        * Amap of e1 must be extended to include e2.
+        * Merging is not supported for map entries that
+        * contain an amap in e1. This should never happen
+        * anyway, because only kernel entries are merged.
+        * These do not contain amaps.
         * e2 contains no real information in its amap,
         * so it can be erased immediately.
         */
-       if (e1->aref.ar_amap) {
-               if (amap_extend(e1, e2->end - e2->start))
-                       return NULL;
-       }
+       if (e1->aref.ar_amap)
+               return NULL;
 
        /*
         * Don't drop obj reference:

Reply via email to