summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/uvm/uvm_amap.c170
-rw-r--r--sys/uvm/uvm_amap.h4
-rw-r--r--sys/uvm/uvm_map.c12
3 files changed, 8 insertions, 178 deletions
diff --git a/sys/uvm/uvm_amap.c b/sys/uvm/uvm_amap.c
index dc1506e74d3..6472c0f4bee 100644
--- a/sys/uvm/uvm_amap.c
+++ b/sys/uvm/uvm_amap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_amap.c,v 1.62 2016/03/16 16:53:43 stefan Exp $ */
+/* $OpenBSD: uvm_amap.c,v 1.63 2016/03/27 09:51:37 stefan Exp $ */
/* $NetBSD: uvm_amap.c,v 1.27 2000/11/25 06:27:59 chs Exp $ */
/*
@@ -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
diff --git a/sys/uvm/uvm_amap.h b/sys/uvm/uvm_amap.h
index 333aa49eb35..a98b44073ad 100644
--- a/sys/uvm/uvm_amap.h
+++ b/sys/uvm/uvm_amap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_amap.h,v 1.21 2016/03/06 14:47:07 stefan Exp $ */
+/* $OpenBSD: uvm_amap.h,v 1.22 2016/03/27 09:51:37 stefan Exp $ */
/* $NetBSD: uvm_amap.h,v 1.14 2001/02/18 21:19:08 chs Exp $ */
/*
@@ -72,8 +72,6 @@ void amap_copy(vm_map_t, vm_map_entry_t, int, boolean_t, vaddr_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 */
diff --git a/sys/uvm/uvm_map.c b/sys/uvm/uvm_map.c
index f6569d64b14..ff7c5e407c6 100644
--- a/sys/uvm/uvm_map.c
+++ b/sys/uvm/uvm_map.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_map.c,v 1.209 2016/03/15 20:50:23 krw Exp $ */
+/* $OpenBSD: uvm_map.c,v 1.210 2016/03/27 09:51:37 stefan Exp $ */
/* $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */
/*
@@ -1448,14 +1448,14 @@ uvm_mapent_merge(struct vm_map *map, struct vm_map_entry *e1,
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;
- }
+ KASSERT(e1->aref.ar_amap == NULL);
/*
* Don't drop obj reference: