Received: by 10.192.165.148 with SMTP id m20csp2715598imm; Sun, 22 Apr 2018 13:29:03 -0700 (PDT) X-Google-Smtp-Source: AIpwx49oTjkv6fDNlsh7eKTg0eVQF3f0j3wiH3qitHWqGl2sIIs8Mh463SaHe7R0GnO4siRHnURc X-Received: by 10.101.88.68 with SMTP id s4mr15059502pgr.232.1524428943271; Sun, 22 Apr 2018 13:29:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524428943; cv=none; d=google.com; s=arc-20160816; b=qRN7/bEPWBbie15OSQ73ARThG581zROmNOApYhOkm/+BYIvq/d4oVNUqoAdKyLVAFj G1V8CVC5C/QKXfKy6LRntc0RSlk7wuEnqLtnXsok7/tuwxKNTe2QODb8v6snllOe7eZ3 Jw6Xhqwx+Sete9BPtbUn6xSXimCyKL2F4Sb0Fj/Mqv4lBky/85b79KlZ2brqOGNzja8v 54ltJ1lOvlsAPOrRw5WZpKo6vUTRUaEV52POkQH2kThNva4iYO+77uuBpt9rD7fcZ6IQ ypPt+KqeQ4sJvgwGB4aVomUJH8LCQ3u+gMp7A5O9a6d3djkTEspE8NEmqJOnZFDcES/H EFuQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=ZzbUHbB2HPxLnCtsVnBBSIbscK/2FYBnUpFATD6VEUw=; b=JvUbAYCodeP+7yDYXY6FGSrFX1dbIujf3TlRNdpTmTzEJdEGMxtnfXbb83OU2wG6w2 nFMh/3I/SNs7Tr1ixoQrpyHXB/lZKKssd1+v4qC2KjjVmN7hOvP8D7G7xn8eBzsmoKjB 54/tc/Y+dgX8OBUB9YD18nXFzUGVztusk26iONcR5B8fPcsh+sSHVcjdvSh6BMCY4DNc lAfZi5aCPxWCTaXR6CiSo0Wz4NLiGuAX8ihjkISmeKis+Ysg53+6a7TgMzWOhCAkYW+1 hFhw+C00EkKHsl10SyBXh5aNN26H3kimL90bU69Y1Di1TQ2a6vxWHnaEdoctF2y2x3zj kB/A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=PQadZhaV; 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; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w8si8364897pgv.276.2018.04.22.13.28.49; Sun, 22 Apr 2018 13:29:03 -0700 (PDT) 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; dkim=pass header.i=@google.com header.s=20161025 header.b=PQadZhaV; 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; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753823AbeDVU1F (ORCPT + 99 others); Sun, 22 Apr 2018 16:27:05 -0400 Received: from mail-pf0-f194.google.com ([209.85.192.194]:33500 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753538AbeDVU1C (ORCPT ); Sun, 22 Apr 2018 16:27:02 -0400 Received: by mail-pf0-f194.google.com with SMTP id f15so7493207pfn.0 for ; Sun, 22 Apr 2018 13:27:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ZzbUHbB2HPxLnCtsVnBBSIbscK/2FYBnUpFATD6VEUw=; b=PQadZhaVwLWgB0COxhBdhc+5S6kMgNZ3piSueS49gtPy7cosrBhqIbASgb6BjaUj24 px0TsEh+Tq21FBMu6hMxs+YY1FyCjQSLWHIRNwoC8W+wGFrBjaumUF09DPFAp0Wniba4 ua1OHtmRcLkeFeBWkOTsEy8EsCqx7DMWHJ+98Zr9x5SnMtO43QMXd7ie9eRv2G/xCLrN lNogr1FdG9BcsM7SNvihcj2NrcfIa3icUhOR4lShc5bY+Q58b5zwH2+4uDXJu9pOFm1B w6CQTMEF5GkhqeNnr1Vd4OxPmdOeSWB2Pe06yWHIr7Z6YhUIPALDIOwfLnHc1hfryu0i ztOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ZzbUHbB2HPxLnCtsVnBBSIbscK/2FYBnUpFATD6VEUw=; b=NpIo4VTBbJTSFK+PlHk5QS6e/GsQEJx51ST/nIulW2rIuGjLKeigUrXvDsD6+gMo0t sVgakJECZc/4z+JINXZ4KxcvUt3TYUFTWZ0pnEHox5QhZG3YTd/U8PSrD/He09606oCR K31aGD0OBnlRtR634vFQ65GTqcjm+Cy9GBHdkerl0BrV13SevyY2mIhZH5fLX6WifTPQ BPbu/nfl9v3Qzd2a2pWXwGJrxm3axurmnUXrF1LiuklZt5F3HuUpUlpJY/pUd3TPfsnP c3jbH740aTpqaLKFWqnII+cSC9tii77Ljr6fqEPA9LRh7PnZGJyZH3fBjkM4N7vFCSo/ zxbg== X-Gm-Message-State: ALQs6tDhHXi032jKGsUh4OA17O54r9jfxnChTMYyFfVMFvYd/KJ0qdv2 N0Rjih551mEaVVyMFZ6K/FrhoA== X-Received: by 10.98.26.78 with SMTP id a75mr7063428pfa.84.1524428821172; Sun, 22 Apr 2018 13:27:01 -0700 (PDT) Received: from gthelen.svl.corp.google.com ([2620:15c:2cb:201:7fd0:97b4:747b:9bf1]) by smtp.gmail.com with ESMTPSA id p1sm20512726pfp.48.2018.04.22.13.26.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 22 Apr 2018 13:27:00 -0700 (PDT) From: Greg Thelen To: guro@fb.com, Johannes Weiner , Andrew Morton , Michal Hocko Cc: Vladimir Davydov , Tejun Heo , Cgroups , kernel-team@fb.com, Linux MM , LKML , Greg Thelen Subject: [RFC PATCH 2/2] memcg: add memory.min Date: Sun, 22 Apr 2018 13:26:12 -0700 Message-Id: <20180422202612.127760-3-gthelen@google.com> X-Mailer: git-send-email 2.17.0.484.g0c8726318c-goog In-Reply-To: <20180422202612.127760-1-gthelen@google.com> References: <20180320223353.5673-1-guro@fb.com> <20180422202612.127760-1-gthelen@google.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The new memory.min limit is similar to memory.low, just no bypassing it when reclaim is desparate. Prefer oom kills before reclaim memory below memory.min. Sharing more code with memory_cgroup_low() is possible, but the idea is posted here for simplicity. Signed-off-by: Greg Thelen --- include/linux/memcontrol.h | 8 ++++++ mm/memcontrol.c | 58 ++++++++++++++++++++++++++++++++++++++ mm/vmscan.c | 3 ++ 3 files changed, 69 insertions(+) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index c46016bb25eb..22bb4a88653a 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -178,6 +178,7 @@ struct mem_cgroup { struct page_counter tcpmem; /* Normal memory consumption range */ + unsigned long min; unsigned long low; unsigned long high; @@ -281,6 +282,7 @@ static inline bool mem_cgroup_disabled(void) return !cgroup_subsys_enabled(memory_cgrp_subsys); } +bool mem_cgroup_min(struct mem_cgroup *root, struct mem_cgroup *memcg); bool mem_cgroup_low(struct mem_cgroup *root, struct mem_cgroup *memcg); int mem_cgroup_try_charge(struct page *page, struct mm_struct *mm, @@ -726,6 +728,12 @@ static inline void mem_cgroup_event(struct mem_cgroup *memcg, { } +static inline bool mem_cgroup_min(struct mem_cgroup *root, + struct mem_cgroup *memcg) +{ + return false; +} + static inline bool mem_cgroup_low(struct mem_cgroup *root, struct mem_cgroup *memcg) { diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 9668f620203a..b2aaed4003b4 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -5058,6 +5058,36 @@ static u64 memory_current_read(struct cgroup_subsys_state *css, return (u64)page_counter_read(&memcg->memory) * PAGE_SIZE; } +static int memory_min_show(struct seq_file *m, void *v) +{ + struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m)); + unsigned long min = READ_ONCE(memcg->min); + + if (min == PAGE_COUNTER_MAX) + seq_puts(m, "max\n"); + else + seq_printf(m, "%llu\n", (u64)min * PAGE_SIZE); + + return 0; +} + +static ssize_t memory_min_write(struct kernfs_open_file *of, + char *buf, size_t nbytes, loff_t off) +{ + struct mem_cgroup *memcg = mem_cgroup_from_css(of_css(of)); + unsigned long min; + int err; + + buf = strstrip(buf); + err = page_counter_memparse(buf, "max", &min); + if (err) + return err; + + memcg->min = min; + + return nbytes; +} + static int memory_low_show(struct seq_file *m, void *v) { struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m)); @@ -5288,6 +5318,12 @@ static struct cftype memory_files[] = { .flags = CFTYPE_NOT_ON_ROOT, .read_u64 = memory_current_read, }, + { + .name = "min", + .flags = CFTYPE_NOT_ON_ROOT, + .seq_show = memory_min_show, + .write = memory_min_write, + }, { .name = "low", .flags = CFTYPE_NOT_ON_ROOT, @@ -5336,6 +5372,28 @@ struct cgroup_subsys memory_cgrp_subsys = { .early_init = 0, }; +/** + * mem_cgroup_min returns true for a memcg below its min limit. Such memcg are + * excempt from reclaim. + */ +bool mem_cgroup_min(struct mem_cgroup *root, struct mem_cgroup *memcg) +{ + if (mem_cgroup_disabled()) + return false; + + if (!root) + root = root_mem_cgroup; + + if (memcg == root) + return false; + + for (; memcg != root; memcg = parent_mem_cgroup(memcg)) { + if (page_counter_read(&memcg->memory) <= memcg->min) + return true; /* protect */ + } + return false; /* !protect */ +} + /** * mem_cgroup_low - check if memory consumption is below the normal range * @root: the top ancestor of the sub-tree being checked diff --git a/mm/vmscan.c b/mm/vmscan.c index cd5dc3faaa57..15ae19a38ad5 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -2539,6 +2539,9 @@ static bool shrink_node(pg_data_t *pgdat, struct scan_control *sc) unsigned long reclaimed; unsigned long scanned; + if (mem_cgroup_min(root, memcg)) + continue; + if (mem_cgroup_low(root, memcg)) { if (!sc->memcg_low_reclaim) { sc->memcg_low_skipped = 1; -- 2.17.0.484.g0c8726318c-goog