aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2019-09-04 20:28:16 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2019-09-04 20:28:16 +0000
commitbf5661f4a1af6931ec4b6b866c964ff19aaccb12 (patch)
tree3b09d549db177bb4492f9b0616662ac14ca91458
parentf93b7f954e96d5162007561ea3ddc1443468d912 (diff)
downloadsrc-bf5661f4a1af6931ec4b6b866c964ff19aaccb12.tar.gz
src-bf5661f4a1af6931ec4b6b866c964ff19aaccb12.zip
madvise(MADV_FREE): Quick fix to time rewind.
Don't free pages in a shadowing object. While this degrades MADV_FREE to a no-op (and we could, instead, choose to fall back to MADV_DONTNEED, at the cost of changing pmap_madvise), this is presently considered a temporary fix. We may prefer to risk a little fragmentation of the map by creating a zero/OBJT_DEFAULT entry over top of the existing object and, simultaneously, revert to the existing marking any pages in the former shadowing object in the advised region as reclaimable. At least one consumer of MADV_FREE (snmalloc) may use mmap() to construct zeroed pages "eventually" here anyway, so the fragmentation may be coming anyway. Submitted by: Nathaniel Filardo <nwf20@cl.cam.ac.uk> PR: 240061 Reviewed by: markj MFC after: 1 week Differential revision: https://reviews.freebsd.org/D21517
Notes
Notes: svn path=/head/; revision=351830
-rw-r--r--sys/vm/vm_map.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index 50289e5a34cd..29105726a8de 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -2736,6 +2736,18 @@ vm_map_madvise(
if (current->eflags & MAP_ENTRY_IS_SUB_MAP)
continue;
+ /*
+ * MADV_FREE would otherwise rewind time to
+ * the creation of the shadow object. Because
+ * we hold the VM map read-locked, neither the
+ * entry's object nor the presence of a
+ * backing object can change.
+ */
+ if (behav == MADV_FREE &&
+ current->object.vm_object != NULL &&
+ current->object.vm_object->backing_object != NULL)
+ continue;
+
pstart = OFF_TO_IDX(current->offset);
pend = pstart + atop(current->end - current->start);
useStart = current->start;