Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 8f5fa1c

Browse files
edliawgregkh
authored andcommitted
selftests/mm: replace atomic_bool with pthread_barrier_t
commit e61ef21 upstream. Patch series "selftests/mm: fix deadlock after pthread_create". On Android arm, pthread_create followed by a fork caused a deadlock in the case where the fork required work to be completed by the created thread. Update the synchronization primitive to use pthread_barrier instead of atomic_bool. Apply the same fix to the wp-fork-with-event test. This patch (of 2): Swap synchronization primitive with pthread_barrier, so that stdatomic.h does not need to be included. The synchronization is needed on Android ARM64; we see a deadlock with pthread_create when the parent thread races forward before the child has a chance to start doing work. Link: https://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected] Fixes: cff2945 ("selftests/mm: extend and rename uffd pagemap test") Signed-off-by: Edward Liaw <[email protected]> Cc: Lokesh Gidra <[email protected]> Cc: Peter Xu <[email protected]> Cc: Shuah Khan <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent a9af9d5 commit 8f5fa1c

File tree

3 files changed

+12
-10
lines changed

3 files changed

+12
-10
lines changed

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ bool map_shared;
1717
bool test_uffdio_wp = true;
1818
unsigned long long *count_verify;
1919
uffd_test_ops_t *uffd_test_ops;
20-
atomic_bool ready_for_fork;
20+
pthread_barrier_t ready_for_fork;
2121

2222
static int uffd_mem_fd_create(off_t mem_size, bool hugetlb)
2323
{
@@ -508,7 +508,8 @@ void *uffd_poll_thread(void *arg)
508508
pollfd[1].fd = pipefd[cpu*2];
509509
pollfd[1].events = POLLIN;
510510

511-
ready_for_fork = true;
511+
/* Ready for parent thread to fork */
512+
pthread_barrier_wait(&ready_for_fork);
512513

513514
for (;;) {
514515
ret = poll(pollfd, 2, -1);

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
#include <inttypes.h>
3434
#include <stdint.h>
3535
#include <sys/random.h>
36-
#include <stdatomic.h>
3736

3837
#include "../kselftest.h"
3938
#include "vm_util.h"
@@ -99,7 +98,7 @@ extern bool map_shared;
9998
extern bool test_uffdio_wp;
10099
extern unsigned long long *count_verify;
101100
extern volatile bool test_uffdio_copy_eexist;
102-
extern atomic_bool ready_for_fork;
101+
extern pthread_barrier_t ready_for_fork;
103102

104103
extern uffd_test_ops_t anon_uffd_test_ops;
105104
extern uffd_test_ops_t shmem_uffd_test_ops;

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,7 @@ static void uffd_sigbus_test_common(bool wp)
770770
char c;
771771
struct uffd_args args = { 0 };
772772

773-
ready_for_fork = false;
773+
pthread_barrier_init(&ready_for_fork, NULL, 2);
774774

775775
fcntl(uffd, F_SETFL, uffd_flags | O_NONBLOCK);
776776

@@ -787,8 +787,9 @@ static void uffd_sigbus_test_common(bool wp)
787787
if (pthread_create(&uffd_mon, NULL, uffd_poll_thread, &args))
788788
err("uffd_poll_thread create");
789789

790-
while (!ready_for_fork)
791-
; /* Wait for the poll_thread to start executing before forking */
790+
/* Wait for child thread to start before forking */
791+
pthread_barrier_wait(&ready_for_fork);
792+
pthread_barrier_destroy(&ready_for_fork);
792793

793794
pid = fork();
794795
if (pid < 0)
@@ -829,7 +830,7 @@ static void uffd_events_test_common(bool wp)
829830
char c;
830831
struct uffd_args args = { 0 };
831832

832-
ready_for_fork = false;
833+
pthread_barrier_init(&ready_for_fork, NULL, 2);
833834

834835
fcntl(uffd, F_SETFL, uffd_flags | O_NONBLOCK);
835836
if (uffd_register(uffd, area_dst, nr_pages * page_size,
@@ -840,8 +841,9 @@ static void uffd_events_test_common(bool wp)
840841
if (pthread_create(&uffd_mon, NULL, uffd_poll_thread, &args))
841842
err("uffd_poll_thread create");
842843

843-
while (!ready_for_fork)
844-
; /* Wait for the poll_thread to start executing before forking */
844+
/* Wait for child thread to start before forking */
845+
pthread_barrier_wait(&ready_for_fork);
846+
pthread_barrier_destroy(&ready_for_fork);
845847

846848
pid = fork();
847849
if (pid < 0)

0 commit comments

Comments
 (0)