From patchwork Wed Aug 30 17:53:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yosry Ahmed X-Patchwork-Id: 13370365 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 57D61C83F17 for ; Wed, 30 Aug 2023 17:53:53 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 7EB24440009; Wed, 30 Aug 2023 13:53:52 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 79A1D28005F; Wed, 30 Aug 2023 13:53:52 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 612F8440009; Wed, 30 Aug 2023 13:53:52 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id 4DA8B28005F for ; Wed, 30 Aug 2023 13:53:52 -0400 (EDT) Received: from smtpin03.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay09.hostedemail.com (Postfix) with ESMTP id 050FF802D4 for ; Wed, 30 Aug 2023 17:53:51 +0000 (UTC) X-FDA: 81181519104.03.F727EA1 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.202]) by imf19.hostedemail.com (Postfix) with ESMTP id 406F61A0004 for ; Wed, 30 Aug 2023 17:53:49 +0000 (UTC) Authentication-Results: imf19.hostedemail.com; dkim=pass header.d=google.com header.s=20221208 header.b=vrOWX6Aa; spf=pass (imf19.hostedemail.com: domain of 3LYLvZAoKCB4SIMLS4BG87AIIAF8.6IGFCHOR-GGEP46E.ILA@flex--yosryahmed.bounces.google.com designates 209.85.215.202 as permitted sender) smtp.mailfrom=3LYLvZAoKCB4SIMLS4BG87AIIAF8.6IGFCHOR-GGEP46E.ILA@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=1693418030; 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=ogw2uZiCm/cMvQMuQo8tpOc+9Ut9ubidtzhSqT66zzA=; b=BgdkIhNOJVycb4Zc654RTiO39TGagNezOEIkUJ0A/QGjdZAMk5rKjX2gFs8IMxfo498nZL yv5O048cCxxcRxRBtajN8dkQrvcUsGWJeUujG3Fbc60KQONJdJIKHqiCV/5CYb3FD8sMtG 3By8jHwzzuhCr/MbOoMaR1to/mM3NEA= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1693418030; a=rsa-sha256; cv=none; b=3sT9Vk62tHjlQjbuBbe3iPpvQRXX2aVUryOXeTv9zIBsMNnqXc8mc/naNFNTfoNNmdstid iIedZeV/ZtmfPAcdISAIrkAZOsTA4jPeuDaRKpnwqVWREFUVMRYAXeis4BOwga/K1L+sLw 8dwvhhN0yJTmAbKEGEvO416bDAgI/N4= ARC-Authentication-Results: i=1; imf19.hostedemail.com; dkim=pass header.d=google.com header.s=20221208 header.b=vrOWX6Aa; spf=pass (imf19.hostedemail.com: domain of 3LYLvZAoKCB4SIMLS4BG87AIIAF8.6IGFCHOR-GGEP46E.ILA@flex--yosryahmed.bounces.google.com designates 209.85.215.202 as permitted sender) smtp.mailfrom=3LYLvZAoKCB4SIMLS4BG87AIIAF8.6IGFCHOR-GGEP46E.ILA@flex--yosryahmed.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-563ab574cb5so93054a12.1 for ; Wed, 30 Aug 2023 10:53:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1693418029; x=1694022829; darn=kvack.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=ogw2uZiCm/cMvQMuQo8tpOc+9Ut9ubidtzhSqT66zzA=; b=vrOWX6AaTLXMDjjROOLrZVCH9sTynMUFsa/hVwvrOGhYg5hh2GJOwstZC5vORHUGon c8q4Y/34V3SkD/Hu8jOnHqS/oCBHicwioHvbC7Ww6OLtIlcGaKXoadNcUJxGMGHLKVdU 5IAic1KbUL1iN2DiyeOhQfgLrOF/U/ZvoHOyhSNFgF3BI6MdWhmqaJQuzZDqhEgDyP5y BhxmnvJwgpGxcgow4zsfy0Fy8JN6yEDD+ma7Xvnggb9T/ykA570XM6ISjeB5U/89b7a4 BXirC1hDs7YyofqMbpq+5eX/+99EYzoEUB1MR3695ognSTKTjEjIoslDTmdJ1tQJ6q0N Yefg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1693418029; x=1694022829; 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=ogw2uZiCm/cMvQMuQo8tpOc+9Ut9ubidtzhSqT66zzA=; b=TgTCKkdnKQV5t3xfzCa1j9Y3QoVL/Flb3WkS+LG5tXP6V6tIWpzaHW7kAvu3ok2tlW eFMqIEA5MQ0CKj6+vi/DVlqa1zZwW6ZbwA8tZazQdiVu09PqLgMx939bUBr1YcmyAv6v 6zu+KQ46/AGKLJdbFc2YsHgg1q2A1LyR10jN/NHTIUTRON4SmNUWqvjelCKTVtA9GXeZ iGbzGp0JP0fqQG/JSkhTMsv+NBJGXnhqQKQ09WgGrgb8P+3VarhfyTzPN94jTV72DcW+ IO3Nwjxci0CiYgostQfp/Ply8/7BmODuGQYuuuD3KonXd4DHTgwhdBnyLp+o0ksSAqEw IzNw== X-Gm-Message-State: AOJu0YxgeDgHdv9+bFJ1flsQS9ktfiQAMJKTA/66PIcipJ6wcd0qAOg7 rYPr83wOUq0IIimkju3VoYXeQcWhLUOQObsk X-Google-Smtp-Source: AGHT+IEDvg6/Dv2ZCiJE47oEUfI2O/1AZvAH6hhLiJqKfB4icsZoJ0gRHnfLWPgfZWkICJoRQkM/9BaaldrxU8Ck X-Received: from yosry.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:2327]) (user=yosryahmed job=sendgmr) by 2002:a63:3c54:0:b0:56c:24c2:488d with SMTP id i20-20020a633c54000000b0056c24c2488dmr486119pgn.4.1693418029016; Wed, 30 Aug 2023 10:53:49 -0700 (PDT) Date: Wed, 30 Aug 2023 17:53:35 +0000 In-Reply-To: <20230830175335.1536008-1-yosryahmed@google.com> Mime-Version: 1.0 References: <20230830175335.1536008-1-yosryahmed@google.com> X-Mailer: git-send-email 2.42.0.rc2.253.gd59a3bf2b4-goog Message-ID: <20230830175335.1536008-5-yosryahmed@google.com> Subject: [PATCH v3 4/4] mm: memcg: use non-unified stats flushing for userspace reads From: Yosry Ahmed To: Andrew Morton Cc: Johannes Weiner , Michal Hocko , Roman Gushchin , Shakeel Butt , Muchun Song , Ivan Babrou , Tejun Heo , " =?utf-8?q?Michal_Koutn=C3=BD?= " , Waiman Long , linux-mm@kvack.org, cgroups@vger.kernel.org, linux-kernel@vger.kernel.org, Yosry Ahmed X-Rspamd-Queue-Id: 406F61A0004 X-Rspam-User: X-Rspamd-Server: rspam11 X-Stat-Signature: xfq49syb7yacfqgj695ezfmjbhmnhr14 X-HE-Tag: 1693418029-467996 X-HE-Meta: U2FsdGVkX19n9jaEwrDdkmuJB3lbuqZCGRBeOSr1EMNgUJhJZMV417UjD5yI6UNa66n8Bq0Cm1igxWz2qyNjkshe2sDzAlet2tRw3Y5thnmmxp0YhbZUGX5mIkJK0ACQWN22CdQDQPryCeoV9ChfbDtPpbOqbaBK5XxDjqmErXLmGTXmnlMmKrPwZ/dPryUS5IsR2AyxOmx2sVNI4WdvKi4K5o4yPsR016eAncnRyC/3rhanG1TuJyvWSHJRp8mgMGQnsGT71yjCuwg0b+yh7CYCeYRmXffXTkqXYo4G2ZuVdlQ9vx0ELkNQhjmEZESkYKS++SHcOmdhr8LHXReW2N/QrfcWOcswJhG0aVAMH2b4p+IXaHaJzB7pTCydK5hfEj8s41oXL/uY/egHmi+dIJCe6/feGgFSPuk7EOiC/YB3cM7Isln9MlNOoti3u1K+02Rqd2LDysHK9jHobj4A3tK/qVCv2DvAWgTJwn9aeSihHpxXvpNIk0CoZwtEOJtghdMzcN4ncQp7lN+OiwJpaKoSKYF3lQBytPwhNhbm63lUZOD+VMBGfu3rVaqZJFSy9aUBqVl3o/GIFDdEYeCQG/lim7ZHml4u7BNbUEWaIRV7I8vDaHHnsV+TKZ3A//6WX6E+seK/SG9TPsTlXCVNIrCCHZ/J/o8Y8xL8ASH4S4aaw7KfBz6BaOfbtCxSw4T8ACoe+GaGyms0K0p0wa1piCZKruFJq1ojxix/jSuynFiMt5lOpOXdx9G4hhYPo4EMKlzj3olePiTQT3LzJ3MQMZSBJIAj5PEmVtcRHJGQowBmTVPddRW9vId27ctfE3D0xenBjExpcUW+YdawwBF5Jv8v1HgebCSYw3qG+Fu86WzhbjHNSbWPiQqHx0SaYOkDaFoEYWyLhaGCjTiADSq62mdT1oL8uHrcywD4AkgyHtS9GP19/1KatSj8+1QbXw58Py3GzNnvlDOxosuSb7e US8q9lFz 0JcKc01ahK2P3rWGOVlboOl53yUwn3N88tMtKxMhExvzEtpyM09Qa9wK/nZWSDbOFMfgR99oYqs2Bzo2MniDagv4Nh8UMFlUZIT2CfUtwnmsgrRD7G6p8sPMly3gwLSDw9jknKDMPV2tK3zekpkMqXsxvzHrTQz8OpUUB4gqZICQgvdrGhRSE6lme/UEikHaFEJhrTyetBlafVquw4iCGD7r11NbqFtaUeQl6oWTkEtMWXF5w/prkgrfexMU9qVog5erVfWBYwPR7vFlFn51dHyNPDJD9651KR7dU5zoC7GIpCgWBkabsZmsrAd/vVJPKSbwYFRJGfo+8IRq/0BRvumnhZGZKZ/q2JmlXNvUPCqnUPTXWY/PT5HLlwQrtd38DD6NedP1XQZkLWqoVxgpSyYW6cKj744QRAvFFv8KYY9uieJBgYjbmdQfALEAiygmLmu/CeR5cm/nt5sKUqNQclr/1BJRyUYLTM4BLlMYZRfHUYNU0tB44byjw07HBr7SISoNoBLkJJKZJ+Oe7nAXj7CjVf23PyjlBXzS66yhRzoE9KuKCRSPFuu8b2lvbk8o5AsstY/oLwyDjx3yZ1j9hl0RbRxj7GaO9effNhtckAq39lSv6TDsA9mqKOahFxWsk0q/pXUUZf91Pa7VM1rIum4xTGcccCjYwa14Y2Xop6EBVO/d/w7uHYqM4xA6HsEVTEw53vBI0fWql34tHd1uYnUqiTw== 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: Unified flushing allows for great concurrency for paths that attempt to flush the stats, at the expense of potential staleness and a single flusher paying the extra cost of flushing the full tree. This tradeoff makes sense for in-kernel flushers that may observe high concurrency (e.g. reclaim, refault). For userspace readers, stale stats may be unexpected and problematic, especially when such stats are used for critical paths such as userspace OOM handling. Additionally, a userspace reader will occasionally pay the cost of flushing the entire hierarchy, which also causes problems in some cases [1]. Opt userspace reads out of unified flushing. This makes the cost of reading the stats more predictable (proportional to the size of the subtree), as well as the freshness of the stats. Userspace readers are not expected to have similar concurrency to in-kernel flushers, serializing them among themselves and among in-kernel flushers should be okay. Nonetheless, for extra safety, introduce a mutex when flushing for userspace readers to make sure only a single userspace reader can compete with in-kernel flushers at a time. This takes away userspace ability to directly influence or hurt in-kernel lock contention. An alternative is to remove flushing from the stats reading path completely, and rely on the periodic flusher. This should be accompanied by making the periodic flushing period tunable, and providing an interface for userspace to force a flush, following a similar model to /proc/vmstat. However, such a change will be hard to reverse if the implementation needs to be changed because: - The cost of reading stats will be very cheap and we won't be able to take that back easily. - There are user-visible interfaces involved. Hence, let's go with the change that's most reversible first and revisit as needed. This was tested on a machine with 256 cpus by running a synthetic test script [2] that creates 50 top-level cgroups, each with 5 children (250 leaf cgroups). Each leaf cgroup has 10 processes running that allocate memory beyond the cgroup limit, invoking reclaim (which is an in-kernel unified flusher). Concurrently, one thread is spawned per-cgroup to read the stats every second (including root, top-level, and leaf cgroups -- so total 251 threads). No significant regressions were observed in the total run time, which means that userspace readers are not significantly affecting in-kernel flushers: Base (mm-unstable): real 0m22.500s user 0m9.399s sys 73m41.381s real 0m22.749s user 0m15.648s sys 73m13.113s real 0m22.466s user 0m10.000s sys 73m11.933s With this patch: real 0m23.092s user 0m10.110s sys 75m42.774s real 0m22.277s user 0m10.443s sys 72m7.182s real 0m24.127s user 0m12.617s sys 78m52.765s [1]https://lore.kernel.org/lkml/CABWYdi0c6__rh-K7dcM_pkf9BJdTRtAU08M43KO9ME4-dsgfoQ@mail.gmail.com/ [2]https://lore.kernel.org/lkml/CAJD7tka13M-zVZTyQJYL1iUAYvuQ1fcHbCjcOBZcz6POYTV-4g@mail.gmail.com/ Signed-off-by: Yosry Ahmed --- mm/memcontrol.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 94d5a6751a9e..1544c3964f19 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -588,6 +588,7 @@ mem_cgroup_largest_soft_limit_node(struct mem_cgroup_tree_per_node *mctz) static void flush_memcg_stats_dwork(struct work_struct *w); static DECLARE_DEFERRABLE_WORK(stats_flush_dwork, flush_memcg_stats_dwork); static DEFINE_PER_CPU(unsigned int, stats_updates); +static DEFINE_MUTEX(stats_user_flush_mutex); static atomic_t stats_unified_flush_ongoing = ATOMIC_INIT(0); static atomic_t stats_flush_threshold = ATOMIC_INIT(0); static u64 flush_next_time; @@ -655,6 +656,21 @@ static void do_stats_flush(struct mem_cgroup *memcg) cgroup_rstat_flush(memcg->css.cgroup); } +/* + * mem_cgroup_user_flush_stats - do a stats flush for a user read + * @memcg: memory cgroup to flush + * + * Flush the subtree of @memcg. A mutex is used for userspace readers to gate + * the global rstat spinlock. This protects in-kernel flushers from userspace + * readers hogging the lock. + */ +void mem_cgroup_user_flush_stats(struct mem_cgroup *memcg) +{ + mutex_lock(&stats_user_flush_mutex); + do_stats_flush(memcg); + mutex_unlock(&stats_user_flush_mutex); +} + /* * do_unified_stats_flush - do a unified flush of memory cgroup statistics * @@ -1608,7 +1624,7 @@ static void memcg_stat_format(struct mem_cgroup *memcg, struct seq_buf *s) * * Current memory state: */ - mem_cgroup_try_flush_stats(); + mem_cgroup_user_flush_stats(memcg); for (i = 0; i < ARRAY_SIZE(memory_stats); i++) { u64 size; @@ -4050,7 +4066,7 @@ static int memcg_numa_stat_show(struct seq_file *m, void *v) int nid; struct mem_cgroup *memcg = mem_cgroup_from_seq(m); - mem_cgroup_try_flush_stats(); + mem_cgroup_user_flush_stats(memcg); for (stat = stats; stat < stats + ARRAY_SIZE(stats); stat++) { seq_printf(m, "%s=%lu", stat->name, @@ -4125,7 +4141,7 @@ static void memcg1_stat_format(struct mem_cgroup *memcg, struct seq_buf *s) BUILD_BUG_ON(ARRAY_SIZE(memcg1_stat_names) != ARRAY_SIZE(memcg1_stats)); - mem_cgroup_try_flush_stats(); + mem_cgroup_user_flush_stats(memcg); for (i = 0; i < ARRAY_SIZE(memcg1_stats); i++) { unsigned long nr; @@ -6642,7 +6658,7 @@ static int memory_numa_stat_show(struct seq_file *m, void *v) int i; struct mem_cgroup *memcg = mem_cgroup_from_seq(m); - mem_cgroup_try_flush_stats(); + mem_cgroup_user_flush_stats(memcg); for (i = 0; i < ARRAY_SIZE(memory_stats); i++) { int nid;