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


Reply via email to