From patchwork Fri Dec 2 03:15:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yosry Ahmed X-Patchwork-Id: 13062111 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 46063C4332F for ; Fri, 2 Dec 2022 03:15:34 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id C720C6B0074; Thu, 1 Dec 2022 22:15:33 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id C22446B0075; Thu, 1 Dec 2022 22:15:33 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id AEA206B0078; Thu, 1 Dec 2022 22:15:33 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id A16DE6B0074 for ; Thu, 1 Dec 2022 22:15:33 -0500 (EST) Received: from smtpin22.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay03.hostedemail.com (Postfix) with ESMTP id 73717A06AB for ; Fri, 2 Dec 2022 03:15:33 +0000 (UTC) X-FDA: 80195900946.22.0F01C3E Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) by imf17.hostedemail.com (Postfix) with ESMTP id 0520140002 for ; Fri, 2 Dec 2022 03:15:32 +0000 (UTC) Authentication-Results: imf17.hostedemail.com; dkim=pass header.d=google.com header.s=20210112 header.b=ZTA6jNpY; spf=pass (imf17.hostedemail.com: domain of 3022JYwoKCPYwmqpwYfkcbemmejc.amkjglsv-kkitYai.mpe@flex--yosryahmed.bounces.google.com designates 209.85.216.74 as permitted sender) smtp.mailfrom=3022JYwoKCPYwmqpwYfkcbemmejc.amkjglsv-kkitYai.mpe@flex--yosryahmed.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1669950933; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=XH6mwHf7EDaGC67MtDUhfOFlBKrgBczQTfSrrHT2Rug=; b=yRqkDem5n6Lhhjnv8V0AcMIZxroM93kuiXBsyql3y+sbgjp6kj25EC5fB8EoYGWfaPKzmV GyGjF0ZXFpG+UltaMxgFAlLORkm4C0MwSmGvFdhyyXvx9d0T+i2qKhBdKO6B6nPaISQDu4 VE8g5YknfClEbUGlY8aihiGxMj3Whxs= ARC-Authentication-Results: i=1; imf17.hostedemail.com; dkim=pass header.d=google.com header.s=20210112 header.b=ZTA6jNpY; spf=pass (imf17.hostedemail.com: domain of 3022JYwoKCPYwmqpwYfkcbemmejc.amkjglsv-kkitYai.mpe@flex--yosryahmed.bounces.google.com designates 209.85.216.74 as permitted sender) smtp.mailfrom=3022JYwoKCPYwmqpwYfkcbemmejc.amkjglsv-kkitYai.mpe@flex--yosryahmed.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1669950933; a=rsa-sha256; cv=none; b=QHpAwTC9KBgBdia1MCsVpwjLem4ZyLLb4bnjRjjttui8DnHKVdhjxxQj3BCCiEy9kFcfPD 42bmZbS3YFMBfXwJHbvMo5jQ5r1enfnN8f3Eeiz4iYnenaAf3T4PJkqfa45/Xg7jL3H+GY bwMvahuvXgolNKIWNvXKQ9E5QtQZtQQ= Received: by mail-pj1-f74.google.com with SMTP id my9-20020a17090b4c8900b002130d29fd7cso8178257pjb.7 for ; Thu, 01 Dec 2022 19:15:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=XH6mwHf7EDaGC67MtDUhfOFlBKrgBczQTfSrrHT2Rug=; b=ZTA6jNpY64q+OTD6IPuzuRI5YVchd2BVByQJxeZ+0jNgkDeRrpoOSkoYrs8JTmtO3d bQeuiSzvI8Ajv8CanGZU6FLXzkwcAwv8yy1vGr0fNUUydgPcY8g7mBvrUDpb0e/XO8fs T06y1p4yGVbIgmqg58n2Hwu6IDMMPHWVc0EEgdWfTYNjjs8rp/kWAwifEabu7DOLnPVo 8VTwxQgN+22poPKnK24M4MaFK+hfJ4iz2zC1d2eAK71nOT6Gep1QdONb5DEWjyPhqqtk JgQr59SzkaGqoo588LCfjHTJIbDJZ8Pyt8mGpq3V7fKVudzULA9iipwyeSMlqpqctAZ0 dNvg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=XH6mwHf7EDaGC67MtDUhfOFlBKrgBczQTfSrrHT2Rug=; b=eImCsEd0mXPV4u7vuKuuzi/1k7tLS5uCcvmhvK4UUfvVfOCYDWTSjGaidesG/cNsfS DQVTJ8j4SPTJ/bW8c0NMivRi6uzqTbyMxZAfWyxV7Y2l0V980ZuqmMeTSHfJOfU37HRM BUz4k0hNs8UhNn+kvq7u3+GGPORj8GK7wt7rFB2fvnKHyy1A263qWpsmYJ6GfzAN3UoG dEfhDQ0zMwhK/VZPXUxmPO7UWaGswJOrqClKLBy5wGRfcm5xNXD7Sft0U94nBmjyL22b K+zFePC3yVOEnedXFtw2na+jkEQwqfEYXfRtGmP0et3H9XCbdbLP5FR8laVQg/QJMJzQ 7Ufw== X-Gm-Message-State: ANoB5pnTElpwnxKpLZirOrPearna8L627k//xTtq+6QB1jXV0AY9Lym7 IzDAwTCXbZqG/mFU45mlvLGYqOpnBIh8aFxl X-Google-Smtp-Source: AA0mqf7PBETjtescCL3/FyX99YGmCALEDVA/h4FWTwolclKu6Pt0Ujihl1FAwjY7B0JyQYI/Hpzx3pIuupApd/fK X-Received: from yosry.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:2327]) (user=yosryahmed job=sendgmr) by 2002:a17:90b:f89:b0:219:5b3b:2b9f with SMTP id ft9-20020a17090b0f8900b002195b3b2b9fmr1432190pjb.2.1669950931626; Thu, 01 Dec 2022 19:15:31 -0800 (PST) Date: Fri, 2 Dec 2022 03:15:10 +0000 In-Reply-To: <20221202031512.1365483-1-yosryahmed@google.com> Mime-Version: 1.0 References: <20221202031512.1365483-1-yosryahmed@google.com> X-Mailer: git-send-email 2.39.0.rc0.267.gcb52ba06e7-goog Message-ID: <20221202031512.1365483-2-yosryahmed@google.com> Subject: [PATCH v3 1/3] mm: memcg: fix stale protection of reclaim target memcg From: Yosry Ahmed To: Andrew Morton , Shakeel Butt , Roman Gushchin , Johannes Weiner , Michal Hocko , Yu Zhao , Muchun Song , Tejun Heo Cc: "Matthew Wilcox (Oracle)" , Vasily Averin , Vlastimil Babka , Chris Down , David Rientjes , cgroups@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Yosry Ahmed X-Rspamd-Server: rspam04 X-Rspamd-Queue-Id: 0520140002 X-Stat-Signature: fkxcetjdd9hno71ogwabr93cywkzbyri X-Rspam-User: X-Spamd-Result: default: False [1.90 / 9.00]; SORBS_IRL_BL(3.00)[209.85.216.74:from]; BAYES_HAM(-3.00)[100.00%]; MID_CONTAINS_FROM(1.00)[]; MV_CASE(0.50)[]; FORGED_SENDER(0.30)[yosryahmed@google.com,3022JYwoKCPYwmqpwYfkcbemmejc.amkjglsv-kkitYai.mpe@flex--yosryahmed.bounces.google.com]; RCVD_NO_TLS_LAST(0.10)[]; MIME_GOOD(-0.10)[text/plain]; BAD_REP_POLICIES(0.10)[]; PREVIOUSLY_DELIVERED(0.00)[linux-mm@kvack.org]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; R_DKIM_ALLOW(0.00)[google.com:s=20210112]; RCVD_COUNT_TWO(0.00)[2]; MIME_TRACE(0.00)[0:+]; R_SPF_ALLOW(0.00)[+ip4:209.85.128.0/17]; RCPT_COUNT_TWELVE(0.00)[17]; DKIM_TRACE(0.00)[google.com:+]; ARC_SIGNED(0.00)[hostedemail.com:s=arc-20220608:i=1]; DMARC_POLICY_ALLOW(0.00)[google.com,reject]; FROM_NEQ_ENVFROM(0.00)[yosryahmed@google.com,3022JYwoKCPYwmqpwYfkcbemmejc.amkjglsv-kkitYai.mpe@flex--yosryahmed.bounces.google.com]; TO_MATCH_ENVRCPT_SOME(0.00)[]; ARC_NA(0.00)[] X-HE-Tag: 1669950932-156248 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000012, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: During reclaim, mem_cgroup_calculate_protection() is used to determine the effective protection (emin and elow) values of a memcg. The protection of the reclaim target is ignored, but we cannot set their effective protection to 0 due to a limitation of the current implementation (see comment in mem_cgroup_protection()). Instead, we leave their effective protection values unchaged, and later ignore it in mem_cgroup_protection(). However, mem_cgroup_protection() is called later in shrink_lruvec()->get_scan_count(), which is after the mem_cgroup_below_{min/low}() checks in shrink_node_memcgs(). As a result, the stale effective protection values of the target memcg may lead us to skip reclaiming from the target memcg entirely, before calling shrink_lruvec(). This can be even worse with recursive protection, where the stale target memcg protection can be higher than its standalone protection. See two examples below (a similar version of example (a) is added to test_memcontrol in a later patch). (a) A simple example with proactive reclaim is as follows. Consider the following hierarchy: ROOT | A | B (memory.min = 10M) Consider the following scenario: - B has memory.current = 10M. - The system undergoes global reclaim (or memcg reclaim in A). - In shrink_node_memcgs(): - mem_cgroup_calculate_protection() calculates the effective min (emin) of B as 10M. - mem_cgroup_below_min() returns true for B, we do not reclaim from B. - Now if we want to reclaim 5M from B using proactive reclaim (memory.reclaim), we should be able to, as the protection of the target memcg should be ignored. - In shrink_node_memcgs(): - mem_cgroup_calculate_protection() immediately returns for B without doing anything, as B is the target memcg, relying on mem_cgroup_protection() to ignore B's stale effective min (still 10M). - mem_cgroup_below_min() reads the stale effective min for B and we skip it instead of ignoring its protection as intended, as we never reach mem_cgroup_protection(). (b) An more complex example with recursive protection is as follows. Consider the following hierarchy with memory_recursiveprot: ROOT | A (memory.min = 50M) | B (memory.min = 10M, memory.high = 40M) Consider the following scenario: - B has memory.current = 35M. - The system undergoes global reclaim (target memcg is NULL). - B will have an effective min of 50M (all of A's unclaimed protection). - B will not be reclaimed from. - Now allocate 10M more memory in B, pushing it above it's high limit. - The system undergoes memcg reclaim from B (target memcg is B). - Like example (a), we do nothing in mem_cgroup_calculate_protection(), then call mem_cgroup_below_min(), which will read the stale effective min for B (50M) and skip it. In this case, it's even worse because we are not just considering B's standalone protection (10M), but we are reading a much higher stale protection (50M) which will cause us to not reclaim from B at all. This is an artifact of commit 45c7f7e1ef17 ("mm, memcg: decouple e{low,min} state mutations from protection checks") which made mem_cgroup_calculate_protection() only change the state without returning any value. Before that commit, we used to return MEMCG_PROT_NONE for the target memcg, which would cause us to skip the mem_cgroup_below_{min/low}() checks. After that commit we do not return anything and we end up checking the min & low effective protections for the target memcg, which are stale. Update mem_cgroup_supports_protection() to also check if we are reclaiming from the target, and rename it to mem_cgroup_unprotected() (now returns true if we should not protect the memcg, much simpler logic). Fixes: 45c7f7e1ef17 ("mm, memcg: decouple e{low,min} state mutations from protection checks") Signed-off-by: Yosry Ahmed Reviewed-by: Roman Gushchin --- include/linux/memcontrol.h | 31 +++++++++++++++++++++---------- mm/vmscan.c | 11 ++++++----- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index e1644a24009c..d3c8203cab6c 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -615,28 +615,32 @@ static inline void mem_cgroup_protection(struct mem_cgroup *root, void mem_cgroup_calculate_protection(struct mem_cgroup *root, struct mem_cgroup *memcg); -static inline bool mem_cgroup_supports_protection(struct mem_cgroup *memcg) +static inline bool mem_cgroup_unprotected(struct mem_cgroup *target, + struct mem_cgroup *memcg) { /* * The root memcg doesn't account charges, and doesn't support - * protection. + * protection. The target memcg's protection is ignored, see + * mem_cgroup_calculate_protection() and mem_cgroup_protection() */ - return !mem_cgroup_disabled() && !mem_cgroup_is_root(memcg); - + return mem_cgroup_disabled() || mem_cgroup_is_root(memcg) || + memcg == target; } -static inline bool mem_cgroup_below_low(struct mem_cgroup *memcg) +static inline bool mem_cgroup_below_low(struct mem_cgroup *target, + struct mem_cgroup *memcg) { - if (!mem_cgroup_supports_protection(memcg)) + if (mem_cgroup_unprotected(target, memcg)) return false; return READ_ONCE(memcg->memory.elow) >= page_counter_read(&memcg->memory); } -static inline bool mem_cgroup_below_min(struct mem_cgroup *memcg) +static inline bool mem_cgroup_below_min(struct mem_cgroup *target, + struct mem_cgroup *memcg) { - if (!mem_cgroup_supports_protection(memcg)) + if (mem_cgroup_unprotected(target, memcg)) return false; return READ_ONCE(memcg->memory.emin) >= @@ -1209,12 +1213,19 @@ static inline void mem_cgroup_calculate_protection(struct mem_cgroup *root, { } -static inline bool mem_cgroup_below_low(struct mem_cgroup *memcg) +static inline bool mem_cgroup_unprotected(struct mem_cgroup *target, + struct mem_cgroup *memcg) +{ + return true; +} +static inline bool mem_cgroup_below_low(struct mem_cgroup *target, + struct mem_cgroup *memcg) { return false; } -static inline bool mem_cgroup_below_min(struct mem_cgroup *memcg) +static inline bool mem_cgroup_below_min(struct mem_cgroup *target, + struct mem_cgroup *memcg) { return false; } diff --git a/mm/vmscan.c b/mm/vmscan.c index 04d8b88e5216..79ef0fe67518 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -4486,7 +4486,7 @@ static bool age_lruvec(struct lruvec *lruvec, struct scan_control *sc, unsigned mem_cgroup_calculate_protection(NULL, memcg); - if (mem_cgroup_below_min(memcg)) + if (mem_cgroup_below_min(NULL, memcg)) return false; need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, swappiness, &nr_to_scan); @@ -5047,8 +5047,9 @@ static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control * DEFINE_MAX_SEQ(lruvec); DEFINE_MIN_SEQ(lruvec); - if (mem_cgroup_below_min(memcg) || - (mem_cgroup_below_low(memcg) && !sc->memcg_low_reclaim)) + if (mem_cgroup_below_min(sc->target_mem_cgroup, memcg) || + (mem_cgroup_below_low(sc->target_mem_cgroup, memcg) && + !sc->memcg_low_reclaim)) return 0; *need_aging = should_run_aging(lruvec, max_seq, min_seq, sc, can_swap, &nr_to_scan); @@ -6048,13 +6049,13 @@ static void shrink_node_memcgs(pg_data_t *pgdat, struct scan_control *sc) mem_cgroup_calculate_protection(target_memcg, memcg); - if (mem_cgroup_below_min(memcg)) { + if (mem_cgroup_below_min(target_memcg, memcg)) { /* * Hard protection. * If there is no reclaimable memory, OOM. */ continue; - } else if (mem_cgroup_below_low(memcg)) { + } else if (mem_cgroup_below_low(target_memcg, memcg)) { /* * Soft protection. * Respect the protection only as long as From patchwork Fri Dec 2 03:15:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yosry Ahmed X-Patchwork-Id: 13062112 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2109FC47088 for ; Fri, 2 Dec 2022 03:15:36 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 9DA386B0075; Thu, 1 Dec 2022 22:15:35 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 98AFF6B0078; Thu, 1 Dec 2022 22:15:35 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 82C366B007B; Thu, 1 Dec 2022 22:15:35 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0017.hostedemail.com [216.40.44.17]) by kanga.kvack.org (Postfix) with ESMTP id 6F17C6B0075 for ; Thu, 1 Dec 2022 22:15:35 -0500 (EST) Received: from smtpin14.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id 327E0C0372 for ; Fri, 2 Dec 2022 03:15:35 +0000 (UTC) X-FDA: 80195901030.14.D6CDD2E Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) by imf19.hostedemail.com (Postfix) with ESMTP id D28DB1A000D for ; Fri, 2 Dec 2022 03:15:34 +0000 (UTC) Authentication-Results: imf19.hostedemail.com; dkim=pass header.d=google.com header.s=20210112 header.b=P8OpmCy+; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf19.hostedemail.com: domain of 31W2JYwoKCPg3txw3fmrjilttlqj.htrqnsz2-rrp0fhp.twl@flex--yosryahmed.bounces.google.com designates 209.85.216.74 as permitted sender) smtp.mailfrom=31W2JYwoKCPg3txw3fmrjilttlqj.htrqnsz2-rrp0fhp.twl@flex--yosryahmed.bounces.google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1669950934; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=DuRs+eCOo373fWFIamKdpS1DYx9E7KO6vBATpERNpN8=; b=DpXtCRafLhoQ5vxG6M0b4/o1bpsMO0FUiKQimgB5Znpu9qbP5taRAKUGw7uLwRUGqn7/kI rMZAZWiX/lNTTSSpdeqb34rnkPAurX4aXkN6s6FGG7xBeTk4JVE1fdT29EIgQWJ/XG41ee Vj962S2+AQahKUlXBwpiVDulD84LA0M= ARC-Authentication-Results: i=1; imf19.hostedemail.com; dkim=pass header.d=google.com header.s=20210112 header.b=P8OpmCy+; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf19.hostedemail.com: domain of 31W2JYwoKCPg3txw3fmrjilttlqj.htrqnsz2-rrp0fhp.twl@flex--yosryahmed.bounces.google.com designates 209.85.216.74 as permitted sender) smtp.mailfrom=31W2JYwoKCPg3txw3fmrjilttlqj.htrqnsz2-rrp0fhp.twl@flex--yosryahmed.bounces.google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1669950934; a=rsa-sha256; cv=none; b=iAQgtmVYB49Quh1iC4mIOmA87UL222JTBi1IYq3pH0nDENaNEuH9b6uaoYnRivSibKedCX 9NZlupM6Jpne3xMet2yY0GK7gH27l0NJb+u3bj6J5QX+S1SAaRznrjxxbonwUorIGSj/dF V90FB5+UeHZrB4dtlou3fJOWphO3jPY= Received: by mail-pj1-f74.google.com with SMTP id mh8-20020a17090b4ac800b0021348e084a0so8172063pjb.8 for ; Thu, 01 Dec 2022 19:15:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=DuRs+eCOo373fWFIamKdpS1DYx9E7KO6vBATpERNpN8=; b=P8OpmCy+hsdPsPghjVdy/8p6gbBKyWTBeA78u/eWGmraKF4XDkTC9BUAU4xols3RBJ Eb3T4ls0TY54/uxuYu7J+7atf4/xsoYt0KtUeRT9Zb5hY23o7MjxGkNxTpE6HlEG6JLX U4PTYctA7PHrrQ/iwUqeB94jmIuWs5SyK7sWXKJ1Nk2bdcheYAGV4dLM23SFnBy69R0L vBw+xnHv9O+RKwOcXilgLaN2TxlnG+nleMjWKyBjPB5guj+1LDHVlpKt8044WVFp6kV+ prfW9gEk3LyWoDGd81vPJOKNBNtQiWQcZaS9NglCCm5pty1GVtmv0As3GfjkM/d/SVij WH3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=DuRs+eCOo373fWFIamKdpS1DYx9E7KO6vBATpERNpN8=; b=UoWLPwzb1sWE3o3cV1fUH1LhawigGww9yvqDGXSR86FcIVYChwzTR9gTjImRR356p6 6OgmouC2df/+qVqKXgfI3CrVltB3wo9bY3tEN2+ByacDyedPH3wlDVMR3bfocuWd/+QD PgZ6A+h5LhTEF3fq51Igql4Ovuc9JQhKlX9tgFLf2qP2acwZYCrf8iVGEeh2QbMs3Fjx cG54litzjO4Xy7DaSYULaYebe4AYAV/T8b6va8EtNrl+cdnogTjODA2dppij96aWNZxe LHR/mYsb4uc1ewnjzAdKV+0brl53Fsvfr1qR3S/EY4BRFPt89UMiEUfHHB9u9KalJr1V uXnA== X-Gm-Message-State: ANoB5pnEvQH61Ppycv/DtorybPaSZUwCT0+V9hThpI/ASu7bDTm10QgF 6Qg8s2RsGh+Vn8mJKtTy9cMEirtHfpj/3Hd2 X-Google-Smtp-Source: AA0mqf6TTfBSxhIz81VhCaQGBqVtXZxPisNhr7Boyb7mKndn+6VVW50DIORS98OFuwLJLcf1hGpLLhUt4jIB/zNT X-Received: from yosry.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:2327]) (user=yosryahmed job=sendgmr) by 2002:a05:6a00:4396:b0:575:1493:88d0 with SMTP id bt22-20020a056a00439600b00575149388d0mr25914503pfb.70.1669950933870; Thu, 01 Dec 2022 19:15:33 -0800 (PST) Date: Fri, 2 Dec 2022 03:15:11 +0000 In-Reply-To: <20221202031512.1365483-1-yosryahmed@google.com> Mime-Version: 1.0 References: <20221202031512.1365483-1-yosryahmed@google.com> X-Mailer: git-send-email 2.39.0.rc0.267.gcb52ba06e7-goog Message-ID: <20221202031512.1365483-3-yosryahmed@google.com> Subject: [PATCH v3 2/3] selftests: cgroup: refactor proactive reclaim code to reclaim_until() From: Yosry Ahmed To: Andrew Morton , Shakeel Butt , Roman Gushchin , Johannes Weiner , Michal Hocko , Yu Zhao , Muchun Song , Tejun Heo Cc: "Matthew Wilcox (Oracle)" , Vasily Averin , Vlastimil Babka , Chris Down , David Rientjes , cgroups@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Yosry Ahmed X-Stat-Signature: xchx4qg83wz7zzh1nbtzoitff9gixgsf X-Spamd-Result: default: False [2.97 / 9.00]; SORBS_IRL_BL(3.00)[209.85.216.74:from]; BAYES_HAM(-2.93)[99.71%]; MID_CONTAINS_FROM(1.00)[]; SUBJECT_HAS_UNDERSCORES(1.00)[]; MV_CASE(0.50)[]; FORGED_SENDER(0.30)[yosryahmed@google.com,31W2JYwoKCPg3txw3fmrjilttlqj.htrqnsz2-rrp0fhp.twl@flex--yosryahmed.bounces.google.com]; RCVD_NO_TLS_LAST(0.10)[]; MIME_GOOD(-0.10)[text/plain]; BAD_REP_POLICIES(0.10)[]; PREVIOUSLY_DELIVERED(0.00)[linux-mm@kvack.org]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; R_DKIM_ALLOW(0.00)[google.com:s=20210112]; RCVD_COUNT_TWO(0.00)[2]; MIME_TRACE(0.00)[0:+]; R_SPF_ALLOW(0.00)[+ip4:209.85.128.0/17]; RCPT_COUNT_TWELVE(0.00)[17]; DKIM_TRACE(0.00)[google.com:+]; ARC_SIGNED(0.00)[hostedemail.com:s=arc-20220608:i=1]; DMARC_POLICY_ALLOW(0.00)[google.com,reject]; FROM_NEQ_ENVFROM(0.00)[yosryahmed@google.com,31W2JYwoKCPg3txw3fmrjilttlqj.htrqnsz2-rrp0fhp.twl@flex--yosryahmed.bounces.google.com]; TO_MATCH_ENVRCPT_SOME(0.00)[]; ARC_NA(0.00)[] X-Rspamd-Queue-Id: D28DB1A000D X-Rspamd-Server: rspam08 X-Rspam-User: X-HE-Tag: 1669950934-626104 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Refactor the code that drives writing to memory.reclaim (retrying, error handling, etc) from test_memcg_reclaim() to a helper called reclaim_until(), which proactively reclaims from a memcg until its usage reaches a certain value. While we are at it, refactor and simplify the reclaim loop. This will be used in a following patch in another test. Signed-off-by: Yosry Ahmed Suggested-by: Roman Gushchin Reviewed-by: Roman Gushchin --- .../selftests/cgroup/test_memcontrol.c | 80 ++++++++++--------- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/tools/testing/selftests/cgroup/test_memcontrol.c b/tools/testing/selftests/cgroup/test_memcontrol.c index 8833359556f3..a8f4700353a4 100644 --- a/tools/testing/selftests/cgroup/test_memcontrol.c +++ b/tools/testing/selftests/cgroup/test_memcontrol.c @@ -645,6 +645,48 @@ static int test_memcg_max(const char *root) return ret; } +/* + * Reclaim from @memcg until usage reaches @goal by writing to + * memory.reclaim. + * + * This function will return false if the usage is already below the + * goal. + * + * This function assumes that writing to memory.reclaim is the only + * source of change in memory.current (no concurrent allocations or + * reclaim). + * + * This function makes sure memory.reclaim is sane. It will return + * false if memory.reclaim's error codes do not make sense, even if + * the usage goal was satisfied. + */ +static bool reclaim_until(const char *memcg, long goal) +{ + char buf[64]; + int retries, err; + long current, to_reclaim; + bool reclaimed = false; + + for (retries = 5; retries > 0; retries--) { + current = cg_read_long(memcg, "memory.current"); + + if (current < goal || values_close(current, goal, 3)) + break; + /* Did memory.reclaim return 0 incorrectly? */ + else if (reclaimed) + return false; + + to_reclaim = current - goal; + snprintf(buf, sizeof(buf), "%ld", to_reclaim); + err = cg_write(memcg, "memory.reclaim", buf); + if (!err) + reclaimed = true; + else if (err != -EAGAIN) + return false; + } + return reclaimed; +} + /* * This test checks that memory.reclaim reclaims the given * amount of memory (from both anon and file, if possible). @@ -653,8 +695,7 @@ static int test_memcg_reclaim(const char *root) { int ret = KSFT_FAIL, fd, retries; char *memcg; - long current, expected_usage, to_reclaim; - char buf[64]; + long current, expected_usage; memcg = cg_name(root, "memcg_test"); if (!memcg) @@ -705,41 +746,8 @@ static int test_memcg_reclaim(const char *root) * Reclaim until current reaches 30M, this makes sure we hit both anon * and file if swap is enabled. */ - retries = 5; - while (true) { - int err; - - current = cg_read_long(memcg, "memory.current"); - to_reclaim = current - MB(30); - - /* - * We only keep looping if we get EAGAIN, which means we could - * not reclaim the full amount. - */ - if (to_reclaim <= 0) - goto cleanup; - - - snprintf(buf, sizeof(buf), "%ld", to_reclaim); - err = cg_write(memcg, "memory.reclaim", buf); - if (!err) { - /* - * If writing succeeds, then the written amount should have been - * fully reclaimed (and maybe more). - */ - current = cg_read_long(memcg, "memory.current"); - if (!values_close(current, MB(30), 3) && current > MB(30)) - goto cleanup; - break; - } - - /* The kernel could not reclaim the full amount, try again. */ - if (err == -EAGAIN && retries--) - continue; - - /* We got an unexpected error or ran out of retries. */ + if (!reclaim_until(memcg, MB(30))) goto cleanup; - } ret = KSFT_PASS; cleanup: From patchwork Fri Dec 2 03:15:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yosry Ahmed X-Patchwork-Id: 13062113 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2A5C3C4332F for ; Fri, 2 Dec 2022 03:15:38 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id B88226B0078; Thu, 1 Dec 2022 22:15:37 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id B37D16B007B; Thu, 1 Dec 2022 22:15:37 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 9FF446B007D; Thu, 1 Dec 2022 22:15:37 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id 8B69B6B0078 for ; Thu, 1 Dec 2022 22:15:37 -0500 (EST) Received: from smtpin03.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id 74826121240 for ; Fri, 2 Dec 2022 03:15:37 +0000 (UTC) X-FDA: 80195901114.03.3ABA79F Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.201]) by imf27.hostedemail.com (Postfix) with ESMTP id 2409A40009 for ; Fri, 2 Dec 2022 03:15:36 +0000 (UTC) Authentication-Results: imf27.hostedemail.com; dkim=pass header.d=google.com header.s=20210112 header.b=c5bVHWOV; spf=pass (imf27.hostedemail.com: domain of 32G2JYwoKCPs1rvu1dkphgjrrjoh.frpolqx0-ppnydfn.ruj@flex--yosryahmed.bounces.google.com designates 209.85.215.201 as permitted sender) smtp.mailfrom=32G2JYwoKCPs1rvu1dkphgjrrjoh.frpolqx0-ppnydfn.ruj@flex--yosryahmed.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1669950937; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=bNyz6y2Y8+pcZcYRhDrKnevmtY0/xVh2JMC54suzd2M=; b=u1lRHALytxLpfGr2ytcNOXrKKaqvjKLBg3fLmKUDE/3vFTbFtw1h+4fRs+OJmqo6mlzEIo Ii8jbe/lhvlkd5qHgafYTftZNLXIHm/J+AhjDLwyac8A+YvoYt644Yv2zt3SEG+RWvKLX5 glMQJqa/k1xzQD12rKOd4N+zhrJV86o= ARC-Authentication-Results: i=1; imf27.hostedemail.com; dkim=pass header.d=google.com header.s=20210112 header.b=c5bVHWOV; spf=pass (imf27.hostedemail.com: domain of 32G2JYwoKCPs1rvu1dkphgjrrjoh.frpolqx0-ppnydfn.ruj@flex--yosryahmed.bounces.google.com designates 209.85.215.201 as permitted sender) smtp.mailfrom=32G2JYwoKCPs1rvu1dkphgjrrjoh.frpolqx0-ppnydfn.ruj@flex--yosryahmed.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1669950937; a=rsa-sha256; cv=none; b=zGgzx6ZfxwWyGSyKSKXtOlqWlqapPgAmykmtblKUZU214UqUNc53TMl0mAsK1dnUQqWGco o3J+G2qIkN6MOb+sH141v9nLsc15m56YTyTeTN61Cb602rs9hQgL0uM6C6SE/k7t++4pJQ rcMH5AW8MO+G4abELHVhAkNHn7BHK7I= Received: by mail-pg1-f201.google.com with SMTP id r126-20020a632b84000000b004393806c06eso3442766pgr.4 for ; Thu, 01 Dec 2022 19:15:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=bNyz6y2Y8+pcZcYRhDrKnevmtY0/xVh2JMC54suzd2M=; b=c5bVHWOVWFxZh/IsKMqBecLiB8RmgVwYrX1GzaIQJrvdCmfUyfs8qg0W9hhScf5hH4 mG1HkIkP0USGP4r6R6YG/H5u+ozhVJBPbINAptVF+p7iL7Zdme2Si3JoPCUQg5PnuM8i 9sgrk6G5d9YLX23J/vJ2Mgm92LjuGfj+UUMBTfr4WknUpFkwvTonc3miyBG+12r8p9WO rKEJGNGnV/+QeTnBLn5B4wArNPSCesKqvyX6p+9fULbYoMK0hz3Mmtd+Zort4W8lRQ75 zHRyiG+ShUvq2dHWqAQo/BfIP9kKzWFVg6HrESVMYli7xM6bVzIBYa/ChJND9QG28tZc zf6A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=bNyz6y2Y8+pcZcYRhDrKnevmtY0/xVh2JMC54suzd2M=; b=C2/sWPdp4efw5rxNKNunSrzE4dC04Evogx1oSHjmteTjytjn+gKV48B8flY0HMwsrQ IoCTgfycKlMupwPoGQiohTQV56fk0pGtrC3xZlfmrWoyKl7rKyz6n2oke7B+oaiH5Jc7 i6tWy4JgzGHBgvPJOxAjJdfxV9up2hYD+ibl+eXobWPiCmPNcoLZeIhlCc/jfo3MUSnH QwQHs5YpqwZ35ebnTJcbGfwa/PNbp1IqTMkFBz01p3I2o2sDm0h1lGOw5RCfudRIBU1g q37Lm1AqTbZbVdtrE/rRKlAmrkvIyRawD6JpTC+T3fPlc+kKrxurbL/y8OIJEJVIRedH LYxQ== X-Gm-Message-State: ANoB5pnNP5dXqzIXw3FTRhehRYw2f65Pjv8j5lcElss/bzuxUHuZmjh1 i9LCoVWct++YtWyWRHV10sMl2F36Kov/xSJY X-Google-Smtp-Source: AA0mqf5+TNJlExQui1Z3kcvsElvim4BKI/6fNytWOv4a9T8n9JlH01lAtNxLgUNDVBfiWHcWgrDzDV9aKBY00gko X-Received: from yosry.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:2327]) (user=yosryahmed job=sendgmr) by 2002:a62:62c4:0:b0:575:e44e:3e0 with SMTP id w187-20020a6262c4000000b00575e44e03e0mr10149400pfb.53.1669950936154; Thu, 01 Dec 2022 19:15:36 -0800 (PST) Date: Fri, 2 Dec 2022 03:15:12 +0000 In-Reply-To: <20221202031512.1365483-1-yosryahmed@google.com> Mime-Version: 1.0 References: <20221202031512.1365483-1-yosryahmed@google.com> X-Mailer: git-send-email 2.39.0.rc0.267.gcb52ba06e7-goog Message-ID: <20221202031512.1365483-4-yosryahmed@google.com> Subject: [PATCH v3 3/3] selftests: cgroup: make sure reclaim target memcg is unprotected From: Yosry Ahmed To: Andrew Morton , Shakeel Butt , Roman Gushchin , Johannes Weiner , Michal Hocko , Yu Zhao , Muchun Song , Tejun Heo Cc: "Matthew Wilcox (Oracle)" , Vasily Averin , Vlastimil Babka , Chris Down , David Rientjes , cgroups@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Yosry Ahmed X-Rspamd-Server: rspam04 X-Rspamd-Queue-Id: 2409A40009 X-Stat-Signature: mkfkhcgbk6dx17t7tptexyz64wi4bqdn X-Rspam-User: X-Spamd-Result: default: False [3.39 / 9.00]; SORBS_IRL_BL(3.00)[209.85.215.201:from]; BAYES_HAM(-1.51)[91.76%]; MID_CONTAINS_FROM(1.00)[]; MV_CASE(0.50)[]; FORGED_SENDER(0.30)[yosryahmed@google.com,32G2JYwoKCPs1rvu1dkphgjrrjoh.frpolqx0-ppnydfn.ruj@flex--yosryahmed.bounces.google.com]; RCVD_NO_TLS_LAST(0.10)[]; MIME_GOOD(-0.10)[text/plain]; BAD_REP_POLICIES(0.10)[]; PREVIOUSLY_DELIVERED(0.00)[linux-mm@kvack.org]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; R_DKIM_ALLOW(0.00)[google.com:s=20210112]; RCVD_COUNT_TWO(0.00)[2]; MIME_TRACE(0.00)[0:+]; R_SPF_ALLOW(0.00)[+ip4:209.85.128.0/17]; RCPT_COUNT_TWELVE(0.00)[17]; DKIM_TRACE(0.00)[google.com:+]; ARC_SIGNED(0.00)[hostedemail.com:s=arc-20220608:i=1]; DMARC_POLICY_ALLOW(0.00)[google.com,reject]; FROM_NEQ_ENVFROM(0.00)[yosryahmed@google.com,32G2JYwoKCPs1rvu1dkphgjrrjoh.frpolqx0-ppnydfn.ruj@flex--yosryahmed.bounces.google.com]; TO_MATCH_ENVRCPT_SOME(0.00)[]; ARC_NA(0.00)[] X-HE-Tag: 1669950936-331678 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000002, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Make sure that we ignore protection of a memcg that is the target of memcg reclaim. Signed-off-by: Yosry Ahmed Reviewed-by: Roman Gushchin --- tools/testing/selftests/cgroup/test_memcontrol.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/testing/selftests/cgroup/test_memcontrol.c b/tools/testing/selftests/cgroup/test_memcontrol.c index a8f4700353a4..1e616a8c6a9c 100644 --- a/tools/testing/selftests/cgroup/test_memcontrol.c +++ b/tools/testing/selftests/cgroup/test_memcontrol.c @@ -238,6 +238,8 @@ static int cg_test_proc_killed(const char *cgroup) return -1; } +static bool reclaim_until(const char *memcg, long goal); + /* * First, this test creates the following hierarchy: * A memory.min = 0, memory.max = 200M @@ -266,6 +268,12 @@ static int cg_test_proc_killed(const char *cgroup) * unprotected memory in A available, and checks that: * a) memory.min protects pagecache even in this case, * b) memory.low allows reclaiming page cache with low events. + * + * Then we try to reclaim from A/B/C using memory.reclaim until its + * usage reaches 10M. + * This makes sure that: + * (a) We ignore the protection of the reclaim target memcg. + * (b) The previously calculated emin value (~29M) should be dismissed. */ static int test_memcg_protection(const char *root, bool min) { @@ -385,6 +393,9 @@ static int test_memcg_protection(const char *root, bool min) if (!values_close(cg_read_long(parent[1], "memory.current"), MB(50), 3)) goto cleanup; + if (!reclaim_until(children[0], MB(10))) + goto cleanup; + if (min) { ret = KSFT_PASS; goto cleanup;