Skip to content

Commit 8c86437

Browse files
edliawakpm00
authored andcommitted
selftests/mm: fix ARM related issue with fork after pthread_create
Following issue was observed while running the uffd-unit-tests selftest on ARM devices. On x86_64 no issues were detected: pthread_create followed by fork caused deadlock in certain cases wherein fork required some work to be completed by the created thread. Used synchronization to ensure that created thread's start function has started before invoking fork. [[email protected]: refactored to use atomic_bool] Link: https://lkml.kernel.org/r/[email protected] Fixes: 760aee0 ("selftests/mm: add tests for RO pinning vs fork()") Signed-off-by: Lokesh Gidra <[email protected]> Signed-off-by: Edward Liaw <[email protected]> Cc: Peter Xu <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 549aa96 commit 8c86437

File tree

3 files changed

+15
-0
lines changed

3 files changed

+15
-0
lines changed

tools/testing/selftests/mm/uffd-common.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ bool test_uffdio_wp = true;
1818
unsigned long long *count_verify;
1919
uffd_test_ops_t *uffd_test_ops;
2020
uffd_test_case_ops_t *uffd_test_case_ops;
21+
atomic_bool ready_for_fork;
2122

2223
static int uffd_mem_fd_create(off_t mem_size, bool hugetlb)
2324
{
@@ -518,6 +519,8 @@ void *uffd_poll_thread(void *arg)
518519
pollfd[1].fd = pipefd[cpu*2];
519520
pollfd[1].events = POLLIN;
520521

522+
ready_for_fork = true;
523+
521524
for (;;) {
522525
ret = poll(pollfd, 2, -1);
523526
if (ret <= 0) {

tools/testing/selftests/mm/uffd-common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <inttypes.h>
3333
#include <stdint.h>
3434
#include <sys/random.h>
35+
#include <stdatomic.h>
3536

3637
#include "../kselftest.h"
3738
#include "vm_util.h"
@@ -103,6 +104,7 @@ extern bool map_shared;
103104
extern bool test_uffdio_wp;
104105
extern unsigned long long *count_verify;
105106
extern volatile bool test_uffdio_copy_eexist;
107+
extern atomic_bool ready_for_fork;
106108

107109
extern uffd_test_ops_t anon_uffd_test_ops;
108110
extern uffd_test_ops_t shmem_uffd_test_ops;

tools/testing/selftests/mm/uffd-unit-tests.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,8 @@ static void uffd_sigbus_test_common(bool wp)
775775
char c;
776776
struct uffd_args args = { 0 };
777777

778+
ready_for_fork = false;
779+
778780
fcntl(uffd, F_SETFL, uffd_flags | O_NONBLOCK);
779781

780782
if (uffd_register(uffd, area_dst, nr_pages * page_size,
@@ -790,6 +792,9 @@ static void uffd_sigbus_test_common(bool wp)
790792
if (pthread_create(&uffd_mon, NULL, uffd_poll_thread, &args))
791793
err("uffd_poll_thread create");
792794

795+
while (!ready_for_fork)
796+
; /* Wait for the poll_thread to start executing before forking */
797+
793798
pid = fork();
794799
if (pid < 0)
795800
err("fork");
@@ -829,6 +834,8 @@ static void uffd_events_test_common(bool wp)
829834
char c;
830835
struct uffd_args args = { 0 };
831836

837+
ready_for_fork = false;
838+
832839
fcntl(uffd, F_SETFL, uffd_flags | O_NONBLOCK);
833840
if (uffd_register(uffd, area_dst, nr_pages * page_size,
834841
true, wp, false))
@@ -838,6 +845,9 @@ static void uffd_events_test_common(bool wp)
838845
if (pthread_create(&uffd_mon, NULL, uffd_poll_thread, &args))
839846
err("uffd_poll_thread create");
840847

848+
while (!ready_for_fork)
849+
; /* Wait for the poll_thread to start executing before forking */
850+
841851
pid = fork();
842852
if (pid < 0)
843853
err("fork");

0 commit comments

Comments
 (0)