[pypy-commit] stmgc c8-reshare-pages: do a direct NOACCES->ACCESSIBLE if the SIGSEGV is a write operation

Raemi pypy.commits at gmail.com
Mon Feb 27 11:40:13 EST 2017


Author: Remi Meier <remi.meier at gmail.com>
Branch: c8-reshare-pages
Changeset: r2017:5911d9fa238e
Date: 2017-02-27 17:38 +0100
http://bitbucket.org/pypy/stmgc/changeset/5911d9fa238e/

Log:	do a direct NOACCES->ACCESSIBLE if the SIGSEGV is a write operation

	Apparently the kernel can tell us if the SIGSEGV is caused by a
	write. Then we can avoid the NOACCESS->RO->RW dance, saving ~10% of
	SIGSEGV on test_random.

	> strace ~/pypy_dir/pytest.py test_zrandom.py -vx -k 10 2>&1 |egrep
	"SIGSEGV"|wc -l

diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -817,7 +817,7 @@
         if (get_page_status_in(my_segnum, page) != PAGE_ACCESSIBLE) {
             release_privatization_lock(STM_SEGMENT->segment_num);
             /* emulate pagefault -> PAGE_ACCESSIBLE/READONLY: */
-            handle_segfault_in_page(page);
+            handle_segfault_in_page(page, false);
             volatile char *dummy = REAL_ADDRESS(STM_SEGMENT->segment_base, page * 4096UL);
             *dummy = *dummy;            /* force segfault (incl. writing) */
             acquire_privatization_lock(STM_SEGMENT->segment_num);
diff --git a/c8/stm/signal_handler.c b/c8/stm/signal_handler.c
--- a/c8/stm/signal_handler.c
+++ b/c8/stm/signal_handler.c
@@ -61,8 +61,26 @@
 }
 
 
+static void readonly_to_accessible(int my_segnum, uintptr_t pagenum)
+{
+    /* make our page write-ready */
+    page_mark_accessible(my_segnum, pagenum);
+
+    /* our READONLY copy *has* to have the current data, no
+       copy necessary */
+    /* make READONLY pages in other segments NO_ACCESS */
+    for (int i = 1; i < NB_SEGMENTS; i++) {
+        if (i == my_segnum)
+            continue;
+
+        if (get_page_status_in(i, pagenum) == PAGE_READONLY)
+            page_mark_inaccessible(i, pagenum);
+    }
+
+}
+
 long ro_to_acc = 0;
-static void handle_segfault_in_page(uintptr_t pagenum)
+static void handle_segfault_in_page(uintptr_t pagenum, bool is_write)
 {
     /* assumes page 'pagenum' is ACCESS_NONE, privatizes it,
        and validates to newest revision */
@@ -78,22 +96,13 @@
     assert(page_status == PAGE_NO_ACCESS
            || page_status == PAGE_READONLY);
 
+
+    //is_write=false;
+    if (page_status == PAGE_READONLY || is_write) {
+        dprintf(("SHORTCUT\n"));
+        readonly_to_accessible(my_segnum, pagenum);
+    }
     if (page_status == PAGE_READONLY) {
-        /* make our page write-ready */
-        page_mark_accessible(my_segnum, pagenum);
-
-        dprintf((" > found READONLY, make others NO_ACCESS\n"));
-        /* our READONLY copy *has* to have the current data, no
-           copy necessary */
-        /* make READONLY pages in other segments NO_ACCESS */
-        for (i = 1; i < NB_SEGMENTS; i++) {
-            if (i == my_segnum)
-                continue;
-
-            if (get_page_status_in(i, pagenum) == PAGE_READONLY)
-                page_mark_inaccessible(i, pagenum);
-        }
-
         ro_to_acc++;
 
         release_all_privatization_locks();
@@ -155,7 +164,8 @@
     }
 
     /* make our page write-ready */
-    page_mark_accessible(my_segnum, pagenum);
+    if (!is_write) // is_write -> already marked accessible above
+        page_mark_accessible(my_segnum, pagenum);
 
     /* account for this page now: XXX */
     /* increment_total_allocated(4096); */
@@ -230,8 +240,11 @@
         abort();
     }
 
+    // http://stackoverflow.com/questions/17671869/how-to-identify-read-or-write-operations-of-page-fault-when-using-sigaction-hand
+    bool is_write = ((ucontext_t*)context)->uc_mcontext.gregs[REG_ERR] & 0x2;
+
     DEBUG_EXPECT_SEGFAULT(false);
-    handle_segfault_in_page(pagenum);
+    handle_segfault_in_page(pagenum, is_write);
     DEBUG_EXPECT_SEGFAULT(true);
 
     errno = saved_errno;
diff --git a/c8/stm/signal_handler.h b/c8/stm/signal_handler.h
--- a/c8/stm/signal_handler.h
+++ b/c8/stm/signal_handler.h
@@ -2,7 +2,7 @@
 static void copy_bk_objs_in_page_from(int from_segnum, uintptr_t pagenum,
                                       bool only_if_not_modified);
 
-static void handle_segfault_in_page(uintptr_t pagenum);
+static void handle_segfault_in_page(uintptr_t pagenum, bool is_write);
 
 
 static void setup_signal_handler(void);


More information about the pypy-commit mailing list