<div dir="ltr"><div><div>Hi,<br><br></div>sorry, ping~<br><br>since the basal patches(build libhugetlb.a & check_hugetlb) have been merged, now we could consider this one.<br><br>926c65d hugetlb: checking if hugepage is supported on target system<br>676746e hugetlb: rename lib/ipcshm.* to lib/hugetlb.*<br><br></div><div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Nov 27, 2015 at 6:00 PM, Li Wang <span dir="ltr"><<a href="mailto:liwang@redhat.com" target="_blank">liwang@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class=""><div class="h5">Description of Problem:<br>
        There is a race condition if we map a same file on different processes.<br>
        Region tracking is protected by mmap_sem and hugetlb_instantiation_mutex.<br>
        When we do mmap, we don't grab a hugetlb_instantiation_mutex, but only<br>
        mmap_sem (exclusively).  This doesn't prevent other tasks from modifying<br>
        the region structure, so it can be modified by two processes concurrently.<br>
<br>
        Testcase hugemmap06.c is the trigger to cause system crash:<br>
        crash> bt -s<br>
        PID: 4492   TASK: ffff88033e437520  CPU: 2   COMMAND: "hugemmap06"<br>
         #0 [ffff88033dbb3960] machine_kexec+395 at ffffffff8103d1ab<br>
         #1 [ffff88033dbb39c0] crash_kexec+114 at ffffffff810cc4f2<br>
         #2 [ffff88033dbb3a90] oops_end+192 at ffffffff8153c840<br>
         #3 [ffff88033dbb3ac0] die+91 at ffffffff81010f5b<br>
         #4 [ffff88033dbb3af0] do_general_protection+338 at ffffffff8153c332<br>
         #5 [ffff88033dbb3b20] general_protection+37 at ffffffff8153bb05<br>
            [exception RIP: list_del+40]<br>
            RIP: ffffffff812a3598  RSP: ffff88033dbb3bd8  RFLAGS: 00010292<br>
            RAX: dead000000100100  RBX: ffff88013cf37340  RCX: 0000000000002dc2<br>
            RDX: dead000000200200  RSI: 0000000000000046  RDI: 0000000000000009<br>
            RBP: ffff88033dbb3be8   R8: 0000000000015598   R9: 0000000000000000<br>
            R10: 000000000000000f  R11: 0000000000000009  R12: 000000000000000a<br>
            R13: ffff88033d64b9e8  R14: ffff88033e5b9720  R15: ffff88013cf37340<br>
            ORIG_RAX: ffffffffffffffff  CS: 0010  SS: 0000<br>
         #6 [ffff88033dbb3bf0] region_add+154 at ffffffff811698da<br>
         #7 [ffff88033dbb3c40] alloc_huge_page+669 at ffffffff8116a61d<br>
         #8 [ffff88033dbb3ce0] hugetlb_fault+1083 at ffffffff8116b9bb<br>
         #9 [ffff88033dbb3d90] handle_mm_fault+917 at ffffffff81153295<br>
        #10 [ffff88033dbb3e00] __do_page_fault+326 at ffffffff8104f156<br>
        #11 [ffff88033dbb3f20] do_page_fault+62 at ffffffff8153e78e<br>
        #12 [ffff88033dbb3f50] page_fault+37 at ffffffff8153bb35<br>
            RIP: 00000000004027c6  RSP: 00007f7cadef9e80  RFLAGS: 00010297<br>
            RAX: 000000005a49238f  RBX: 00007ffcb2d19320  RCX: 000000357498e084<br>
            RDX: 000000357498e0b0  RSI: 00007f7cadef9e5c  RDI: 000000357498e4e0<br>
            RBP: 0000000000000008   R8: 000000357498e0a0   R9: 000000357498e100<br>
            R10: 00007f7cadefa9d0  R11: 0000000000000206  R12: 0000000000000007<br>
            R13: 0000000000000002  R14: 0000000000000003  R15: 00002aaaac000000<br>
            ORIG_RAX: ffffffffffffffff  CS: 0033  SS: 002b<br>
<br>
</div></div><span class="">The fix are all these below commits:<br>
</span>       f522c3ac00(mm, hugetlb: change variable name reservations to resv)<br>
       9119a41e90(mm, hugetlb: unify region structure handling)<br>
       7b24d8616b(mm, hugetlb: fix race in region tracking)<br>
       1406ec9ba6(mm, hugetlb: improve, cleanup resv_map parameters)<br>
<span class=""><br>
Signed-off-by: Li Wang <<a href="mailto:liwang@redhat.com">liwang@redhat.com</a>><br>
---<br>
<br>
</span>Notes:<br>
    v2 --> v3<br>
    a. include hugetlb.h<br>
    b. listing commits in a short way<br>
    c. update the license to GPLv3<br>
    d. make tid[ARSZ] and for(...) simple<br>
    e. keep &tid[i] the same style in one function<br>
<span class=""><br>
 runtest/hugetlb                                    |   1 +<br>
 testcases/kernel/mem/.gitignore                    |   1 +<br>
 testcases/kernel/mem/hugetlb/hugemmap/Makefile     |   2 +<br>
</span> testcases/kernel/mem/hugetlb/hugemmap/hugemmap06.c | 180 +++++++++++++++++++++<br>
 4 files changed, 184 insertions(+)<br>
<div><div class="h5"> create mode 100644 testcases/kernel/mem/hugetlb/hugemmap/hugemmap06.c<br>
<br>
diff --git a/runtest/hugetlb b/runtest/hugetlb<br>
index 2e9f215..ac24513 100644<br>
--- a/runtest/hugetlb<br>
+++ b/runtest/hugetlb<br>
@@ -2,6 +2,7 @@ hugemmap01 hugemmap01<br>
 hugemmap02 hugemmap02<br>
 hugemmap04 hugemmap04<br>
 hugemmap05 hugemmap05<br>
+hugemmap06 hugemmap06<br>
 hugemmap05_1 hugemmap05 -m<br>
 hugemmap05_2 hugemmap05 -s<br>
 hugemmap05_3 hugemmap05 -s -m<br>
diff --git a/testcases/kernel/mem/.gitignore b/testcases/kernel/mem/.gitignore<br>
index 4702377..ac8e6d8 100644<br>
--- a/testcases/kernel/mem/.gitignore<br>
+++ b/testcases/kernel/mem/.gitignore<br>
@@ -3,6 +3,7 @@<br>
 /hugetlb/hugemmap/hugemmap02<br>
 /hugetlb/hugemmap/hugemmap04<br>
 /hugetlb/hugemmap/hugemmap05<br>
+/hugetlb/hugemmap/hugemmap06<br>
 /hugetlb/hugeshmat/hugeshmat01<br>
 /hugetlb/hugeshmat/hugeshmat02<br>
 /hugetlb/hugeshmat/hugeshmat03<br>
diff --git a/testcases/kernel/mem/hugetlb/hugemmap/Makefile b/testcases/kernel/mem/hugetlb/hugemmap/Makefile<br>
</div></div>index f51f6b9..2473aca 100644<br>
<span class="">--- a/testcases/kernel/mem/hugetlb/hugemmap/Makefile<br>
+++ b/testcases/kernel/mem/hugetlb/hugemmap/Makefile<br>
@@ -25,3 +25,5 @@ top_srcdir            ?= ../../../../..<br>
 include $(top_srcdir)/include/mk/<a href="http://testcases.mk" rel="noreferrer" target="_blank">testcases.mk</a><br>
</span> include $(abs_srcdir)/../Makefile.inc<br>
 include $(top_srcdir)/include/mk/<a href="http://generic_leaf_target.mk" rel="noreferrer" target="_blank">generic_leaf_target.mk</a><br>
<span class="">+<br>
+hugemmap06: CFLAGS+=-pthread<br>
diff --git a/testcases/kernel/mem/hugetlb/hugemmap/hugemmap06.c b/testcases/kernel/mem/hugetlb/hugemmap/hugemmap06.c<br>
new file mode 100644<br>
</span>index 0000000..400d28a<br>
--- /dev/null<br>
+++ b/testcases/kernel/mem/hugetlb/hugemmap/hugemmap06.c<br>
@@ -0,0 +1,180 @@<br>
+/*<br>
+ *  Copyright (c) 2015 Red Hat, Inc.<br>
<span class="">+ *<br>
+ * This program is free software: you can redistribute it and/or modify<br>
+ * it under the terms of the GNU General Public License as published by<br>
</span>+ * the Free Software Foundation, either version 3 of the License, or<br>
<span class="">+ * (at your option) any later version.<br>
+ *<br>
+ * This program is distributed in the hope that it will be useful,<br>
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
</span>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br>
+ * GNU General Public License for more details.<br>
<span class="">+ *<br>
+ * You should have received a copy of the GNU General Public License<br>
</span>+ * along with this program. If not, see <<a href="http://www.gnu.org/licenses/" rel="noreferrer" target="_blank">http://www.gnu.org/licenses/</a>>.<br>
+ */<br>
<span class="">+<br>
+/*<br>
+ * DESCRIPTION<br>
+ *<br>
+ *   There is a race condition if we map a same file on different processes.<br>
+ *   Region tracking is protected by mmap_sem and hugetlb_instantiation_mutex.<br>
+ *   When we do mmap, we don't grab a hugetlb_instantiation_mutex, but only<br>
+ *   mmap_sem (exclusively).  This doesn't prevent other tasks from modifying<br>
+ *   the region structure, so it can be modified by two processes concurrently.<br>
</span>+ *<br>
+ *   This bug was fixed on stable kernel by commits:<br>
+ *       f522c3ac00(mm, hugetlb: change variable name reservations to resv)<br>
+ *       9119a41e90(mm, hugetlb: unify region structure handling)<br>
+ *       7b24d8616b(mm, hugetlb: fix race in region tracking)<br>
+ *       1406ec9ba6(mm, hugetlb: improve, cleanup resv_map parameters)<br>
+ *<br>
+ * AUTHOR:<br>
+ *    Herton R. Krzesinski <<a href="mailto:herton@redhat.com">herton@redhat.com</a>><br>
+ *    Li Wang <<a href="mailto:liwang@redhat.com">liwang@redhat.com</a>><br>
<span class="">+ */<br>
+<br>
+#define _GNU_SOURCE<br>
+#include <errno.h><br>
+#include <pthread.h><br>
+#include <stdio.h><br>
+#include <stdlib.h><br>
+#include <sys/mman.h><br>
+#include <sys/types.h><br>
+#include <unistd.h><br>
+<br>
+#include "test.h"<br>
+#include "mem.h"<br>
</span>+#include "hugetlb.h"<br>
<span class="">+<br>
+char *TCID = "hugemmap06";<br>
+int TST_TOTAL = 5;<br>
+<br>
+static long hpage_size;<br>
+static long hugepages;<br>
</span><div><div class="h5">+<br>
+struct mp {<br>
+       void *addr;<br>
+       int sz;<br>
+};<br>
+<br>
+#define ARSZ 50<br>
+<br>
+void setup(void)<br>
+{<br>
+       tst_require_root();<br>
+       check_hugepage();<br>
+<br>
+       hpage_size = read_meminfo("Hugepagesize:") * 1024;<br>
+       orig_hugepages = get_sys_tune("nr_hugepages");<br>
+<br>
+       hugepages = (ARSZ + 1) * TST_TOTAL;<br>
+<br>
+       if (hugepages * read_meminfo("Hugepagesize:") > read_meminfo("MemTotal:"))<br>
+               tst_brkm(TCONF, NULL, "System RAM is not enough to test.");<br>
+<br>
+       set_sys_tune("nr_hugepages", hugepages, 1);<br>
+<br>
+       TEST_PAUSE;<br>
+}<br>
+<br>
+void cleanup(void)<br>
+{<br>
+       set_sys_tune("nr_hugepages", orig_hugepages, 0);<br>
+}<br>
+<br>
+void *thr(void *arg)<br>
+{<br>
+       struct mp *mmap_sz = arg;<br>
+       int i, lim, a, b, c;<br>
+<br>
+       srand(time(NULL));<br>
+       lim = rand() % 10;<br>
</div></div>+       for (i = 0; i < lim; i++) {<br>
<span class="">+               a = rand() % mmap_sz->sz;<br>
+               for (c = 0; c <= a; c++) {<br>
+                       b = rand() % mmap_sz->sz;<br>
+                       *((int *)((char *)mmap_sz->addr + (b * hpage_size))) = rand();<br>
+               }<br>
+       }<br>
+       return NULL;<br>
+}<br>
+<br>
+void do_mmap(void)<br>
+{<br>
+       int i, sz;<br>
+       void *addr, *new_addr;<br>
+       struct mp mmap_sz[ARSZ];<br>
+       pthread_t tid[ARSZ];<br>
+<br>
</span>+       sz = ARSZ + 1;<br>
<span class="">+       addr = mmap(NULL, sz * hpage_size,<br>
+                       PROT_READ | PROT_WRITE,<br>
+                       MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB,<br>
+                       -1, 0);<br>
+<br>
+       if (addr == MAP_FAILED) {<br>
+               if (errno == ENOMEM) {<br>
+                       tst_brkm(TCONF, cleanup,<br>
+                               "Cannot allocate hugepage, memory too fragmented?");<br>
+               }<br>
+<br>
</span><span class="">+               tst_brkm(TBROK | TERRNO, cleanup, "Cannot allocate hugepage");<br>
+       }<br>
+<br>
</span>+       for (i = 0; i < ARSZ; ++i, --sz) {<br>
<span class="">+               mmap_sz[i].sz = sz;<br>
+               mmap_sz[i].addr = addr;<br>
+<br>
</span>+               TEST(pthread_create(&tid[i], NULL, thr, &mmap_sz[i]));<br>
<span class="">+               if (TEST_RETURN)<br>
+                       tst_brkm(TBROK | TRERRNO, cleanup,<br>
+                                       "pthread_create failed");<br>
+<br>
+               new_addr = mmap(addr, (sz - 1) * hpage_size,<br>
+                               PROT_READ | PROT_WRITE,<br>
+                               MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_FIXED,<br>
+                               -1, 0);<br>
+<br>
+               if (new_addr == MAP_FAILED) {<br>
+                       TEST(pthread_join(tid[i], NULL));<br>
+                       if (TEST_RETURN)<br>
+                               tst_brkm(TBROK | TRERRNO, cleanup,<br>
+                                               "pthread_join failed");<br>
+                       tst_brkm(TFAIL | TERRNO, cleanup, "mremap failed");<br>
+               }<br>
</span>+               addr = new_addr;<br>
+       }<br>
+<br>
+       for (i = 0; i < ARSZ; ++i) {<br>
<span class="">+               TEST(pthread_join(tid[i], NULL));<br>
+               if (TEST_RETURN)<br>
+                       tst_brkm(TBROK | TRERRNO, cleanup,<br>
+                                       "pthread_join failed");<br>
+       }<br>
+<br>
+       if (munmap(addr, sz * hpage_size) == -1)<br>
+               tst_brkm(TFAIL | TERRNO, cleanup, "huge munmap failed");<br>
+}<br>
+<br>
+int main(int ac, char **av)<br>
+{<br>
+       int lc, i;<br>
+<br>
+       tst_parse_opts(ac, av, NULL, NULL);<br>
+<br>
+       setup();<br>
+<br>
+       for (lc = 0; TEST_LOOPING(lc); lc++) {<br>
+               tst_count = 0;<br>
+<br>
</span>+               for (i = 0; i < TST_TOTAL; i++)<br>
<span class="im">+                       do_mmap();<br>
+<br>
+               tst_resm(TPASS, "No regression found.");<br>
+       }<br>
+<br>
+       cleanup();<br>
+       tst_exit();<br>
</span><div class=""><div class="h5">+}<br>
--<br>
1.8.3.1<br>
<br>
<br>
--<br>
Mailing list info: <a href="http://lists.linux.it/listinfo/ltp" rel="noreferrer" target="_blank">http://lists.linux.it/listinfo/ltp</a><br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br><div class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div>Regards,<br></div>Li Wang<br></div><div>Email: <a href="mailto:liwang@redhat.com" target="_blank">liwang@redhat.com</a><br></div></div></div></div></div></div>
</div></div></div>