[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <a5fc83e3-4d4a-49da-8dc8-8bf3973bc851@huaweicloud.com>
Date: Fri, 25 Jul 2025 09:48:09 +0800
From: Chen Ridong <chenridong@...weicloud.com>
To: tj@...nel.org, hannes@...xchg.org, mkoutny@...e.com, lizefan@...wei.com
Cc: cgroups@...r.kernel.org, linux-kernel@...r.kernel.org,
lujialin4@...wei.com, chenridong@...wei.com, gaoyingjie@...ontech.com
Subject: Re: [PATCH v2 -next] cgroup: remove offline draining in root
destruction to avoid hung_tasks
On 2025/7/22 19:27, Chen Ridong wrote:
> From: Chen Ridong <chenridong@...wei.com>
>
> A hung task can occur during [1] LTP cgroup testing when repeatedly
> mounting/unmounting perf_event and net_prio controllers with
> systemd.unified_cgroup_hierarchy=1. The hang manifests in
> cgroup_lock_and_drain_offline() during root destruction.
>
> Related case:
> cgroup_fj_function_perf_event cgroup_fj_function.sh perf_event
> cgroup_fj_function_net_prio cgroup_fj_function.sh net_prio
This can be easily reproduced by the process(offered by Yingjie):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <unistd.h>
#define LOOPS 10000
#define TMPDIR "/tmp"
#define CGROUP_BASE "ltp_cgtest"
#define CONTROLLERS_COUNT 2
const char *controllers[CONTROLLERS_COUNT] = {"perf_event", "net_prio"};
void safe_mkdir(const char *path) {
if (mkdir(path, 0777) == -1 && errno != EEXIST) {
fprintf(stderr, "mkdir(%s) failed: %s\n", path, strerror(errno));
exit(1);
}
}
void safe_rmdir(const char *path) {
if (rmdir(path) == -1 && errno != ENOENT) {
fprintf(stderr, "rmdir(%s) failed: %s\n", path, strerror(errno));
}
}
int is_mounted(const char *mnt) {
FILE *fp = fopen("/proc/mounts", "r");
if (!fp) return 0;
char line[512];
int found = 0;
while (fgets(line, sizeof(line), fp)) {
if (strstr(line, mnt)) {
found = 1;
break;
}
}
fclose(fp);
return found;
}
int main(void) {
if (getuid() != 0) {
fprintf(stderr, "This program must be run as root\n");
return 1;
}
FILE *fcg = fopen("/proc/cgroups", "r");
if (!fcg) {
fprintf(stderr, "Kernel does not support cgroups\n");
return 1;
}
fclose(fcg);
char mnt[256];
for (int i = 1; i <= LOOPS; ++i) {
for (int c = 0; c < CONTROLLERS_COUNT; ++c) {
snprintf(mnt, sizeof(mnt), "%s/cgroup_%s", TMPDIR, controllers[c]);
printf("=== Loop %d: %s ===\n", i, controllers[c]);
fflush(stdout);
safe_mkdir(mnt);
if (!is_mounted(mnt)) {
if (mount(controllers[c], mnt, "cgroup", 0, controllers[c]) == -1) {
fprintf(stderr, "Failed to mount cgroup v1 for %s at %s: %s\n",
controllers[c], mnt, strerror(errno));
safe_rmdir(mnt);
continue;
}
}
if (umount2(mnt, 0) == -1) {
fprintf(stderr, "umount(%s) failed: %s\n", mnt, strerror(errno));
}
safe_rmdir(mnt);
}
}
return 0;
}
Powered by blists - more mailing lists