Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp9159297ybl; Fri, 17 Jan 2020 07:17:08 -0800 (PST) X-Google-Smtp-Source: APXvYqzszXUd4+W0GNRuVVZV70XvW2cOqb2ZOm9mU5XlxC2Hdcu1gEArNmTVdbQz7X43k1Y8uXXy X-Received: by 2002:a9d:67d2:: with SMTP id c18mr6281197otn.362.1579274228067; Fri, 17 Jan 2020 07:17:08 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1579274228; cv=none; d=google.com; s=arc-20160816; b=CSuUZP5Y14j5z1WzYPTTz1+izFFFPjzhdgs6LzCqIZHfu8lI8/ftl12P2fm5h9o8qi Emwhd2RB6FFM0nlj27IWA1IszK5WDivUTnQEe7cAfNzb8sS/tx0I7wu9nh9vNxnVAEBf Y2wKRc27ORTtLKHMNdFGlzEXSpkEwWo1NxUjWlKRkijoZCFnakV5zypwmb4PIUUH5WAE 82DP6R5Sj1rKnChKwfXGUeu10PfBASXsXVCq1B1MDajuArOODWCDetKpRmE+rHaHPRim UnR14kB7HfZ0CVsGXtT7yV+1vmy28Xuhj7Xkp7/X2lD5L5/ZUf5xHLbvVpe14Z6mQO0M n45w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=zVls3A3xMYlSgi5l2ykSOFB+f6c3mDatVBv7v81z3m8=; b=ByzhFHphDjIzpmOTBgF6te2O+IUwlZ/0UtL+rjTXtB291RHVeNyFI5eZX/OdV/ASiN I7wkJN6ZGWZOoCElF1dPUCm90lcdLgf6UA3S2OQQcG+66bKpXk1dlqcB5SKJ0Yfad3nw UiKqZknwTnX5qaZPc4pdgLWgAChOmqtaSF0xlcCeJkDtSvO+xzdRVPFO9DxAms2KNYbQ IbWxgqchL07m/R2u+u6oamQrk9lfnW7QwAA2Jhz4awpV3jqtcVhc3CCXbWbjy9R2+fEH BIS0Tz6NI2C660w0ScA4Vi7DsuDDe/k0yoctRooxC0RB2QPvSrRvXgbZEZA6DAZtJRsc Glzw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o15si14270022otp.314.2020.01.17.07.16.56; Fri, 17 Jan 2020 07:17:08 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729203AbgAQPPx (ORCPT + 99 others); Fri, 17 Jan 2020 10:15:53 -0500 Received: from mx2.suse.de ([195.135.220.15]:60106 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729061AbgAQPPt (ORCPT ); Fri, 17 Jan 2020 10:15:49 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 09FD5AF42; Fri, 17 Jan 2020 15:15:47 +0000 (UTC) From: =?UTF-8?q?Michal=20Koutn=C3=BD?= To: cgroups@vger.kernel.org Cc: Johannes Weiner , Li Zefan , Tejun Heo , alex.shi@linux.alibaba.com, guro@fb.com, kernel-team@android.com, linger.lee@mediatek.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mediatek@lists.infradead.org, matthias.bgg@gmail.com, shuah@kernel.org, tomcherry@google.com Subject: [PATCH 3/3] kselftest/cgroup: add cgroup destruction test Date: Fri, 17 Jan 2020 16:15:33 +0100 Message-Id: <20200117151533.12381-4-mkoutny@suse.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200117151533.12381-1-mkoutny@suse.com> References: <20200116043612.52782-1-surenb@google.com> <20200117151533.12381-1-mkoutny@suse.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Suren Baghdasaryan Add new test to verify that a cgroup with dead processes can be destroyed. The test spawns a child process which allocates and touches 100MB of RAM to ensure prolonged exit. Subsequently it kills the child, waits until the cgroup containing the child is empty and destroys the cgroup. Signed-off-by: Suren Baghdasaryan Signed-off-by: Michal Koutný --- tools/testing/selftests/cgroup/test_core.c | 113 +++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/tools/testing/selftests/cgroup/test_core.c b/tools/testing/selftests/cgroup/test_core.c index c5ca669feb2b..2a5242ec1a49 100644 --- a/tools/testing/selftests/cgroup/test_core.c +++ b/tools/testing/selftests/cgroup/test_core.c @@ -2,7 +2,10 @@ #include #include +#include +#include #include +#include #include #include #include @@ -12,6 +15,115 @@ #include "../kselftest.h" #include "cgroup_util.h" +static int touch_anon(char *buf, size_t size) +{ + int fd; + char *pos = buf; + + fd = open("/dev/urandom", O_RDONLY); + if (fd < 0) + return -1; + + while (size > 0) { + ssize_t ret = read(fd, pos, size); + + if (ret < 0) { + if (errno != EINTR) { + close(fd); + return -1; + } + } else { + pos += ret; + size -= ret; + } + } + close(fd); + + return 0; +} + +static int alloc_and_touch_anon_noexit(const char *cgroup, void *arg) +{ + int ppid = getppid(); + size_t size = (size_t)arg; + void *buf; + + buf = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, + 0, 0); + if (buf == MAP_FAILED) + return -1; + + if (touch_anon((char *)buf, size)) { + munmap(buf, size); + return -1; + } + + while (getppid() == ppid) + sleep(1); + + munmap(buf, size); + return 0; +} + +/* + * Create a child process that allocates and touches 100MB, then waits to be + * killed. Wait until the child is attached to the cgroup, kill all processes + * in that cgroup and wait until "cgroup.events" is empty. At this point try to + * destroy the empty cgroup. The test helps detect race conditions between + * dying processes leaving the cgroup and cgroup destruction path. + */ +static int test_cgcore_destroy(const char *root) +{ + int ret = KSFT_FAIL; + char *cg_test = NULL; + int child_pid; + char buf[PAGE_SIZE]; + + cg_test = cg_name(root, "cg_test"); + + if (!cg_test) + goto cleanup; + + for (int i = 0; i < 10; i++) { + if (cg_create(cg_test)) + goto cleanup; + + child_pid = cg_run_nowait(cg_test, alloc_and_touch_anon_noexit, + (void *) MB(100)); + + if (child_pid < 0) + goto cleanup; + + /* wait for the child to enter cgroup */ + if (cg_wait_for_proc_count(cg_test, 1)) + goto cleanup; + + if (cg_killall(cg_test)) + goto cleanup; + + /* wait for cgroup to be empty */ + while (1) { + if (cg_read(cg_test, "cgroup.procs", buf, sizeof(buf))) + goto cleanup; + if (buf[0] == '\0') + break; + usleep(1000); + } + + if (rmdir(cg_test)) + goto cleanup; + + if (waitpid(child_pid, NULL, 0) < 0) + goto cleanup; + } + ret = KSFT_PASS; +cleanup: + if (cg_test) + cg_destroy(cg_test); + free(cg_test); + return ret; +} + /* * A(0) - B(0) - C(1) * \ D(0) @@ -512,6 +624,7 @@ struct corecg_test { T(test_cgcore_populated), T(test_cgcore_proc_migration), T(test_cgcore_thread_migration), + T(test_cgcore_destroy), }; #undef T -- 2.24.1