Commit 7ddd8faf authored by Andrea Arcangeli's avatar Andrea Arcangeli Committed by Linus Torvalds

userfaultfd: selftest: exercise -EEXIST only in background transfer

I was stress testing some backports and with high load, after some time,
the latest version of the selftest showed some false positive in
connection with the uffdio_copy_retry.  This seems to fix it while still
exercising -EEXIST in the background transfer once in a while.

The fork child will quit after the last UFFDIO_COPY is run, so a
repeated UFFDIO_COPY may not return -EEXIST.  This change restricts the
-EEXIST stress to the background transfer where the memory can't go away
from under it.

Also updated uffdio_zeropage, so the interface is consistent.

Link: http://lkml.kernel.org/r/20171004171541.1495-2-aarcange@redhat.comSigned-off-by: default avatarAndrea Arcangeli <aarcange@redhat.com>
Cc: Pavel Emelyanov <xemul@virtuozzo.com>
Cc: Mike Rapoport <rppt@linux.vnet.ibm.com>
Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 064f0e93
...@@ -397,7 +397,7 @@ static void retry_copy_page(int ufd, struct uffdio_copy *uffdio_copy, ...@@ -397,7 +397,7 @@ static void retry_copy_page(int ufd, struct uffdio_copy *uffdio_copy,
} }
} }
static int copy_page(int ufd, unsigned long offset) static int __copy_page(int ufd, unsigned long offset, bool retry)
{ {
struct uffdio_copy uffdio_copy; struct uffdio_copy uffdio_copy;
...@@ -418,7 +418,7 @@ static int copy_page(int ufd, unsigned long offset) ...@@ -418,7 +418,7 @@ static int copy_page(int ufd, unsigned long offset)
fprintf(stderr, "UFFDIO_COPY unexpected copy %Ld\n", fprintf(stderr, "UFFDIO_COPY unexpected copy %Ld\n",
uffdio_copy.copy), exit(1); uffdio_copy.copy), exit(1);
} else { } else {
if (test_uffdio_copy_eexist) { if (test_uffdio_copy_eexist && retry) {
test_uffdio_copy_eexist = false; test_uffdio_copy_eexist = false;
retry_copy_page(ufd, &uffdio_copy, offset); retry_copy_page(ufd, &uffdio_copy, offset);
} }
...@@ -427,6 +427,16 @@ static int copy_page(int ufd, unsigned long offset) ...@@ -427,6 +427,16 @@ static int copy_page(int ufd, unsigned long offset)
return 0; return 0;
} }
static int copy_page_retry(int ufd, unsigned long offset)
{
return __copy_page(ufd, offset, true);
}
static int copy_page(int ufd, unsigned long offset)
{
return __copy_page(ufd, offset, false);
}
static void *uffd_poll_thread(void *arg) static void *uffd_poll_thread(void *arg)
{ {
unsigned long cpu = (unsigned long) arg; unsigned long cpu = (unsigned long) arg;
...@@ -544,7 +554,7 @@ static void *background_thread(void *arg) ...@@ -544,7 +554,7 @@ static void *background_thread(void *arg)
for (page_nr = cpu * nr_pages_per_cpu; for (page_nr = cpu * nr_pages_per_cpu;
page_nr < (cpu+1) * nr_pages_per_cpu; page_nr < (cpu+1) * nr_pages_per_cpu;
page_nr++) page_nr++)
copy_page(uffd, page_nr * page_size); copy_page_retry(uffd, page_nr * page_size);
return NULL; return NULL;
} }
...@@ -779,7 +789,7 @@ static void retry_uffdio_zeropage(int ufd, ...@@ -779,7 +789,7 @@ static void retry_uffdio_zeropage(int ufd,
} }
} }
static int uffdio_zeropage(int ufd, unsigned long offset) static int __uffdio_zeropage(int ufd, unsigned long offset, bool retry)
{ {
struct uffdio_zeropage uffdio_zeropage; struct uffdio_zeropage uffdio_zeropage;
int ret; int ret;
...@@ -814,7 +824,7 @@ static int uffdio_zeropage(int ufd, unsigned long offset) ...@@ -814,7 +824,7 @@ static int uffdio_zeropage(int ufd, unsigned long offset)
fprintf(stderr, "UFFDIO_ZEROPAGE unexpected %Ld\n", fprintf(stderr, "UFFDIO_ZEROPAGE unexpected %Ld\n",
uffdio_zeropage.zeropage), exit(1); uffdio_zeropage.zeropage), exit(1);
} else { } else {
if (test_uffdio_zeropage_eexist) { if (test_uffdio_zeropage_eexist && retry) {
test_uffdio_zeropage_eexist = false; test_uffdio_zeropage_eexist = false;
retry_uffdio_zeropage(ufd, &uffdio_zeropage, retry_uffdio_zeropage(ufd, &uffdio_zeropage,
offset); offset);
...@@ -830,6 +840,11 @@ static int uffdio_zeropage(int ufd, unsigned long offset) ...@@ -830,6 +840,11 @@ static int uffdio_zeropage(int ufd, unsigned long offset)
return 0; return 0;
} }
static int uffdio_zeropage(int ufd, unsigned long offset)
{
return __uffdio_zeropage(ufd, offset, false);
}
/* exercise UFFDIO_ZEROPAGE */ /* exercise UFFDIO_ZEROPAGE */
static int userfaultfd_zeropage_test(void) static int userfaultfd_zeropage_test(void)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment