Subject: [merged] 
tools-vm-page-typesc-catch-sigbus-if-raced-with-truncate.patch removed from -mm 
tree
To: 
[email protected],[email protected],[email protected],[email protected]
From: [email protected]
Date: Thu, 05 Jun 2014 12:41:51 -0700


The patch titled
     Subject: tools/vm/page-types.c: catch sigbus if raced with truncate
has been removed from the -mm tree.  Its filename was
     tools-vm-page-typesc-catch-sigbus-if-raced-with-truncate.patch

This patch was dropped because it was merged into mainline or a subsystem tree

------------------------------------------------------
From: Konstantin Khlebnikov <[email protected]>
Subject: tools/vm/page-types.c: catch sigbus if raced with truncate

Recently added page-cache dumping is known to be a little bit racy.
But after race with truncate it just dies due to unhandled SIGBUS
when it tries to poke pages beyond the new end of file.
This patch adds handler for SIGBUS which skips the rest of the file.

Signed-off-by: Konstantin Khlebnikov <[email protected]>
Cc: Naoya Horiguchi <[email protected]>
Cc: <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
---

 tools/vm/page-types.c |   35 ++++++++++++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 3 deletions(-)

diff -puN 
tools/vm/page-types.c~tools-vm-page-typesc-catch-sigbus-if-raced-with-truncate 
tools/vm/page-types.c
--- 
a/tools/vm/page-types.c~tools-vm-page-typesc-catch-sigbus-if-raced-with-truncate
+++ a/tools/vm/page-types.c
@@ -32,6 +32,8 @@
 #include <assert.h>
 #include <ftw.h>
 #include <time.h>
+#include <setjmp.h>
+#include <signal.h>
 #include <sys/types.h>
 #include <sys/errno.h>
 #include <sys/fcntl.h>
@@ -824,21 +826,38 @@ static void show_file(const char *name,
                        atime, now - st->st_atime);
 }
 
+static sigjmp_buf sigbus_jmp;
+
+static void * volatile sigbus_addr;
+
+static void sigbus_handler(int sig, siginfo_t *info, void *ucontex)
+{
+       (void)sig;
+       (void)ucontex;
+       sigbus_addr = info ? info->si_addr : NULL;
+       siglongjmp(sigbus_jmp, 1);
+}
+
+static struct sigaction sigbus_action = {
+       .sa_sigaction = sigbus_handler,
+       .sa_flags = SA_SIGINFO,
+};
+
 static void walk_file(const char *name, const struct stat *st)
 {
        uint8_t vec[PAGEMAP_BATCH];
        uint64_t buf[PAGEMAP_BATCH], flags;
        unsigned long nr_pages, pfn, i;
+       off_t off, end = st->st_size;
        int fd;
-       off_t off;
        ssize_t len;
        void *ptr;
        int first = 1;
 
        fd = checked_open(name, O_RDONLY|O_NOATIME|O_NOFOLLOW);
 
-       for (off = 0; off < st->st_size; off += len) {
-               nr_pages = (st->st_size - off + page_size - 1) / page_size;
+       for (off = 0; off < end; off += len) {
+               nr_pages = (end - off + page_size - 1) / page_size;
                if (nr_pages > PAGEMAP_BATCH)
                        nr_pages = PAGEMAP_BATCH;
                len = nr_pages * page_size;
@@ -855,11 +874,19 @@ static void walk_file(const char *name,
                if (madvise(ptr, len, MADV_RANDOM))
                        fatal("madvice failed: %s", name);
 
+               if (sigsetjmp(sigbus_jmp, 1)) {
+                       end = off + sigbus_addr ? sigbus_addr - ptr : 0;
+                       fprintf(stderr, "got sigbus at offset %lld: %s\n",
+                                       (long long)end, name);
+                       goto got_sigbus;
+               }
+
                /* populate ptes */
                for (i = 0; i < nr_pages ; i++) {
                        if (vec[i] & 1)
                                (void)*(volatile int *)(ptr + i * page_size);
                }
+got_sigbus:
 
                /* turn off harvesting reference bits */
                if (madvise(ptr, len, MADV_SEQUENTIAL))
@@ -910,6 +937,7 @@ static void walk_page_cache(void)
 
        kpageflags_fd = checked_open(PROC_KPAGEFLAGS, O_RDONLY);
        pagemap_fd = checked_open("/proc/self/pagemap", O_RDONLY);
+       sigaction(SIGBUS, &sigbus_action, NULL);
 
        if (stat(opt_file, &st))
                fatal("stat failed: %s\n", opt_file);
@@ -925,6 +953,7 @@ static void walk_page_cache(void)
 
        close(kpageflags_fd);
        close(pagemap_fd);
+       signal(SIGBUS, SIG_DFL);
 }
 
 static void parse_file(const char *name)
_

Patches currently in -mm which might be from [email protected] are

origin.patch
linux-next.patch

--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to