Module Name: src Committed By: chs Date: Tue Aug 18 10:40:20 UTC 2020
Modified Files: src/sys/uvm: uvm_amap.c Log Message: fix amap_extend() to handle amaps where we previously failed to allocate the ppref memory. To generate a diff of this commit: cvs rdiff -u -r1.122 -r1.123 src/sys/uvm/uvm_amap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/uvm/uvm_amap.c diff -u src/sys/uvm/uvm_amap.c:1.122 src/sys/uvm/uvm_amap.c:1.123 --- src/sys/uvm/uvm_amap.c:1.122 Thu Jul 9 05:57:15 2020 +++ src/sys/uvm/uvm_amap.c Tue Aug 18 10:40:20 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_amap.c,v 1.122 2020/07/09 05:57:15 skrll Exp $ */ +/* $NetBSD: uvm_amap.c,v 1.123 2020/08/18 10:40:20 chs Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvm_amap.c,v 1.122 2020/07/09 05:57:15 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_amap.c,v 1.123 2020/08/18 10:40:20 chs Exp $"); #include "opt_uvmhist.h" @@ -353,7 +353,7 @@ amap_extend(struct vm_map_entry *entry, struct vm_amap *amap = entry->aref.ar_amap; int slotoff = entry->aref.ar_pageoff; int slotmapped, slotadd, slotneed, slotadded, slotalloc; - int slotadj, slotarea; + int slotadj, slotarea, slotendoff; int oldnslots; #ifdef UVM_AMAP_PPREF int *newppref, *oldppref; @@ -388,6 +388,36 @@ amap_extend(struct vm_map_entry *entry, } /* + * Because this amap only has 1 ref, we know that there is + * only one vm_map_entry pointing to it, and the one entry is + * using slots between slotoff and slotoff + slotmapped. If + * we have been using ppref then we know that only slots in + * the one map entry's range can have anons, since ppref + * allowed us to free any anons outside that range as other map + * entries which used this amap were removed. But without ppref, + * we couldn't know which slots were still needed by other map + * entries, so we couldn't free any anons as we removed map + * entries, and so any slot from 0 to am_nslot can have an + * anon. But now that we know there is only one map entry + * left and we know its range, we can free up any anons + * outside that range. This is necessary because the rest of + * this function assumes that there are no anons in the amap + * outside of the one map entry's range. + */ + + slotendoff = slotoff + slotmapped; + if (amap->am_ppref == PPREF_NONE) { + amap_wiperange(amap, 0, slotoff); + amap_wiperange(amap, slotendoff, amap->am_nslot - slotendoff); + } + for (i = 0; i < slotoff; i++) { + KASSERT(amap->am_anon[i] == NULL); + } + for (i = slotendoff; i < amap->am_nslot - slotendoff; i++) { + KASSERT(amap->am_anon[i] == NULL); + } + + /* * 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.