From: Waiman Long <longman@redhat.com>
To: "Tejun Heo" <tj@kernel.org>,
"Johannes Weiner" <hannes@cmpxchg.org>,
"Michal Koutný" <mkoutny@suse.com>,
"Shuah Khan" <shuah@kernel.org>
Cc: cgroups@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-kselftest@vger.kernel.org, Waiman Long <longman@redhat.com>
Subject: [PATCH v2] selftests/cgroup: Fix intermittent test_cgfreezer_ptrace test failures
Date: Tue, 14 Jul 2026 23:54:46 -0400 [thread overview]
Message-ID: <20260715035446.565625-1-longman@redhat.com> (raw)
It is found that the test_cgfreezer_ptrace test of test_freezer can
intermittently fail on some architectures like arm64 and ppc64.
After further tracing of the mechanics of the test_cgfreezer_ptrace test,
it is found that the ptrace(PTRACE_DETACH) call will spawn another process
to perform the detach by temporarily unfreezes the cgroup and then freezes
it again afterward during the detaching process. The reading of the
frozen flag from cgroup.events is done by the main test_freezer process
running probably on a different CPU. As a result, racing is possible and
the intermediate unfrozen state can be read leading to occasional test
failures especially on architectures with a weak memory model like arm64.
Fix that by using the cg_prepare_for_wait() and cg_wait_for() helpers to
wait until frozen state is set or it times out. A suppress_debug_msg flag
is added to suppress the printing of debug message when cg_check_frozen()
is used during this waiting process.
By running test_freezer 100 times in a loop, there were 28
test_cgfreezer_ptrace failures out of 100 on an arm64 test system before
the patch. After applying the patch, there was no test failure at all
in 100 runs of test_freezer.
Suggested-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Waiman Long <longman@redhat.com>
---
tools/testing/selftests/cgroup/test_freezer.c | 41 +++++++++++++++++--
1 file changed, 38 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/cgroup/test_freezer.c b/tools/testing/selftests/cgroup/test_freezer.c
index 0569e93fa6b0..9edb2d34658c 100644
--- a/tools/testing/selftests/cgroup/test_freezer.c
+++ b/tools/testing/selftests/cgroup/test_freezer.c
@@ -14,9 +14,11 @@
#include "kselftest.h"
#include "cgroup_util.h"
+static bool suppress_debug_msg;
+
#define DEBUG
#ifdef DEBUG
-#define debug(args...) fprintf(stderr, args)
+#define debug(args...) do { if (!suppress_debug_msg) fprintf(stderr, args); } while (0)
#else
#define debug(args...)
#endif
@@ -585,7 +587,8 @@ static int test_cgfreezer_ptrace(const char *root)
int ret = KSFT_FAIL;
char *cgroup = NULL;
siginfo_t siginfo;
- int pid;
+ int fd = -1, pid, retries;
+ bool frozen;
cgroup = cg_name(root, "cg_test_ptrace");
if (!cgroup)
@@ -622,15 +625,47 @@ static int test_cgfreezer_ptrace(const char *root)
if (ptrace(PTRACE_GETSIGINFO, pid, NULL, &siginfo))
goto cleanup;
+ /*
+ * The ptrace(PTRACE_DETACH) call spawns a different a process to
+ * temporarily unfreeze the cgroup and then freeze it again in the
+ * detaching process. The reading of the frozen flag from cgroup.events
+ * is done by the main test process running probably on a different CPU.
+ * As a result, racing is possible and the intermediate unfrozen state
+ * can be read leading to occasional test failure especially on
+ * architectures with a weak memory model like arm64.
+ *
+ * This intermittent test failure can be avoided by using the
+ * cg_prepare_for_wait() and cg_wait_for() helpers to wait for change
+ * in the frozen state if necessary.
+ */
+ fd = cg_prepare_for_wait(cgroup);
+ if (fd < 0)
+ goto cleanup;
+
if (ptrace(PTRACE_DETACH, pid, NULL, NULL))
goto cleanup;
- if (cg_check_frozen(cgroup, true))
+ suppress_debug_msg = true;
+ frozen = !cg_check_frozen(cgroup, true);
+ if (!frozen) {
+ /* Attempt to wait until frozen */
+ for (retries = 0; retries < 3; retries++) {
+ if (cg_wait_for(fd))
+ break;
+ frozen = !cg_check_frozen(cgroup, true);
+ if (frozen)
+ break;
+ }
+ }
+ suppress_debug_msg = false;
+ if (!frozen)
goto cleanup;
ret = KSFT_PASS;
cleanup:
+ if (fd >= 0)
+ close(fd);
if (cgroup)
cg_destroy(cgroup);
free(cgroup);
--
2.55.0
next reply other threads:[~2026-07-15 3:55 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-15 3:54 Waiman Long [this message]
2026-07-15 9:36 ` [PATCH v2] selftests/cgroup: Fix intermittent test_cgfreezer_ptrace test failures Michal Koutný
2026-07-15 15:47 ` Waiman Long
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260715035446.565625-1-longman@redhat.com \
--to=longman@redhat.com \
--cc=cgroups@vger.kernel.org \
--cc=hannes@cmpxchg.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=mkoutny@suse.com \
--cc=shuah@kernel.org \
--cc=tj@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.