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

Commit e61ef21

Browse files
edliawakpm00
authored andcommitted
selftests/mm: replace atomic_bool with pthread_barrier_t
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]>
1 parent 963a7f4 commit e61ef21

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
@@ -18,7 +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;
21+
pthread_barrier_t ready_for_fork;
2222

2323
static int uffd_mem_fd_create(off_t mem_size, bool hugetlb)
2424
{
@@ -519,7 +519,8 @@ void *uffd_poll_thread(void *arg)
519519
pollfd[1].fd = pipefd[cpu*2];
520520
pollfd[1].events = POLLIN;
521521

522-
ready_for_fork = true;
522+
/* Ready for parent thread to fork */
523+
pthread_barrier_wait(&ready_for_fork);
523524

524525
for (;;) {
525526
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"
@@ -105,7 +104,7 @@ extern bool map_shared;
105104
extern bool test_uffdio_wp;
106105
extern unsigned long long *count_verify;
107106
extern volatile bool test_uffdio_copy_eexist;
108-
extern atomic_bool ready_for_fork;
107+
extern pthread_barrier_t ready_for_fork;
109108

110109
extern uffd_test_ops_t anon_uffd_test_ops;
111110
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
@@ -774,7 +774,7 @@ static void uffd_sigbus_test_common(bool wp)
774774
char c;
775775
struct uffd_args args = { 0 };
776776

777-
ready_for_fork = false;
777+
pthread_barrier_init(&ready_for_fork, NULL, 2);
778778

779779
fcntl(uffd, F_SETFL, uffd_flags | O_NONBLOCK);
780780

@@ -791,8 +791,9 @@ static void uffd_sigbus_test_common(bool wp)
791791
if (pthread_create(&uffd_mon, NULL, uffd_poll_thread, &args))
792792
err("uffd_poll_thread create");
793793

794-
while (!ready_for_fork)
795-
; /* Wait for the poll_thread to start executing before forking */
794+
/* Wait for child thread to start before forking */
795+
pthread_barrier_wait(&ready_for_fork);
796+
pthread_barrier_destroy(&ready_for_fork);
796797

797798
pid = fork();
798799
if (pid < 0)
@@ -833,7 +834,7 @@ static void uffd_events_test_common(bool wp)
833834
char c;
834835
struct uffd_args args = { 0 };
835836

836-
ready_for_fork = false;
837+
pthread_barrier_init(&ready_for_fork, NULL, 2);
837838

838839
fcntl(uffd, F_SETFL, uffd_flags | O_NONBLOCK);
839840
if (uffd_register(uffd, area_dst, nr_pages * page_size,
@@ -844,8 +845,9 @@ static void uffd_events_test_common(bool wp)
844845
if (pthread_create(&uffd_mon, NULL, uffd_poll_thread, &args))
845846
err("uffd_poll_thread create");
846847

847-
while (!ready_for_fork)
848-
; /* Wait for the poll_thread to start executing before forking */
848+
/* Wait for child thread to start before forking */
849+
pthread_barrier_wait(&ready_for_fork);
850+
pthread_barrier_destroy(&ready_for_fork);
849851

850852
pid = fork();
851853
if (pid < 0)

0 commit comments

Comments
 (0)