memory_object_data_return says, in KCOPY, whether the kernel keeps the
pages it returns (a clean, as for a sync) or evicts them. The
callbacks did not get it. A kept page can already be newer than the
copy being written, which the kernel took when it was asked for it;
a pager that keeps its own copy of what it is given needs to know.
---
libpager/data-return.c | 11 +++++++++++
libpager/pager.h | 7 +++++++
2 files changed, 18 insertions(+)
diff --git a/libpager/data-return.c b/libpager/data-return.c
index 1416ae410..61de126f9 100644
--- a/libpager/data-return.c
+++ b/libpager/data-return.c
@@ -21,6 +21,15 @@
#include <string.h>
#include <assert-backtrace.h>
+/* Whether the write this thread is doing leaves the pages resident. */
+static __thread int write_keeps_page;
+
+int
+pager_write_keeps_page (void)
+{
+ return write_keeps_page;
+}
+
/* Worker function used by _pager_S_memory_object_data_return
and _pager_S_memory_object_data_initialize. All args are
as for _pager_S_memory_object_data_return; the additional
@@ -158,6 +167,7 @@ _pager_do_write_request (struct pager *p,
/* Let someone else in. */
pthread_mutex_unlock (&p->interlock);
+ write_keeps_page = kcopy;
int i_page = 0;
while (i_page < npages)
{
@@ -204,6 +214,7 @@ _pager_do_write_request (struct pager *p,
i_page = j_page;
}
+ write_keeps_page = 0;
/* Acquire the right to meddle with the pagemap */
diff --git a/libpager/pager.h b/libpager/pager.h
index 8c43ad0ee..3f09f2c4b 100644
--- a/libpager/pager.h
+++ b/libpager/pager.h
@@ -213,6 +213,13 @@ error_t pager_write_pages(struct user_pager_info *upi,
vm_size_t length,
vm_size_t *written);
+/* Called from pager_write_page or pager_write_pages: nonzero if the
+ kernel keeps the pages being written resident, because it only cleans
+ them (a sync), and zero if it evicts them. A kept page can be newer
+ than the copy being written, which the kernel took when the write was
+ requested. */
+int pager_write_keeps_page (void);
+
/* The user must define this function. A page should be made writable. */
error_t
pager_unlock_page (struct user_pager_info *pager,
--
2.56.0