summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_object.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/vm/vm_object.c')
-rw-r--r--sys/vm/vm_object.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 1df9faf..6da6c9b 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -478,8 +478,10 @@ vm_object_terminate(object)
/*
* vm_object_page_clean
*
- * Clean all dirty pages in the specified range of object.
- * Leaves page on whatever queue it is currently on.
+ * Clean all dirty pages in the specified range of object. Leaves page
+ * on whatever queue it is currently on. If NOSYNC is set then do not
+ * write out pages with PG_NOSYNC set (originally comes from MAP_NOSYNC),
+ * leaving the object dirty.
*
* Odd semantics: if start == end, we clean everything.
*
@@ -503,6 +505,7 @@ vm_object_page_clean(object, start, end, flags)
int chkb;
int maxb;
int i;
+ int clearobjflags;
int pagerflags;
vm_page_t maf[vm_pageout_page_count];
vm_page_t mab[vm_pageout_page_count];
@@ -527,12 +530,26 @@ vm_object_page_clean(object, start, end, flags)
tend = end;
}
+ /*
+ * Generally set CLEANCHK interlock and make the page read-only so
+ * we can then clear the object flags.
+ *
+ * However, if this is a nosync mmap then the object is likely to
+ * stay dirty so do not mess with the page and do not clear the
+ * object flags.
+ */
+
+ clearobjflags = 1;
+
for(p = TAILQ_FIRST(&object->memq); p; p = TAILQ_NEXT(p, listq)) {
vm_page_flag_set(p, PG_CLEANCHK);
- vm_page_protect(p, VM_PROT_READ);
+ if ((flags & OBJPC_NOSYNC) && (p->flags & PG_NOSYNC))
+ clearobjflags = 0;
+ else
+ vm_page_protect(p, VM_PROT_READ);
}
- if ((tstart == 0) && (tend == object->size)) {
+ if (clearobjflags && (tstart == 0) && (tend == object->size)) {
vm_object_clear_flag(object, OBJ_WRITEABLE|OBJ_MIGHTBEDIRTY);
}
@@ -557,6 +574,16 @@ rescan:
continue;
}
+ /*
+ * If we have been asked to skip nosync pages and this is a
+ * nosync page, skip it. Note that the object flags were
+ * not cleared in this case so we do not have to set them.
+ */
+ if ((flags & OBJPC_NOSYNC) && (p->flags & PG_NOSYNC)) {
+ vm_page_flag_clear(p, PG_CLEANCHK);
+ continue;
+ }
+
s = splvm();
while (vm_page_sleep_busy(p, TRUE, "vpcwai")) {
if (object->generation != curgeneration) {
OpenPOWER on IntegriCloud