[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <156760519254.6560.3180815463616863318.stgit@buzz>
Date: Wed, 04 Sep 2019 16:53:12 +0300
From: Konstantin Khlebnikov <khlebnikov@...dex-team.ru>
To: linux-mm@...ck.org, linux-kernel@...r.kernel.org,
cgroups@...r.kernel.org
Cc: Michal Hocko <mhocko@...e.com>, Roman Gushchin <guro@...com>,
Johannes Weiner <hannes@...xchg.org>
Subject: [PATCH v1 2/7] mm/memcontrol: add mem_cgroup_recharge
This function tries to move page into other cgroup.
Caller must lock page and isolate it from LRU.
Signed-off-by: Konstantin Khlebnikov <khlebnikov@...dex-team.ru>
---
include/linux/memcontrol.h | 9 +++++++++
mm/memcontrol.c | 40 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 49 insertions(+)
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 2cd4359cb38c..d94950584f60 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -352,6 +352,8 @@ void mem_cgroup_uncharge(struct page *page);
void mem_cgroup_uncharge_list(struct list_head *page_list);
void mem_cgroup_migrate(struct page *oldpage, struct page *newpage);
+int mem_cgroup_try_recharge(struct page *page, struct mm_struct *mm,
+ gfp_t gfp_mask);
static struct mem_cgroup_per_node *
mem_cgroup_nodeinfo(struct mem_cgroup *memcg, int nid)
@@ -857,6 +859,13 @@ static inline void mem_cgroup_migrate(struct page *old, struct page *new)
{
}
+static inline int mem_cgroup_try_recharge(struct page *page,
+ struct mm_struct *mm,
+ gfp_t gfp_mask)
+{
+ return 0;
+}
+
static inline struct lruvec *mem_cgroup_lruvec(struct pglist_data *pgdat,
struct mem_cgroup *memcg)
{
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 40ddc233e973..953a0bbb9f43 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -6507,6 +6507,46 @@ void mem_cgroup_migrate(struct page *oldpage, struct page *newpage)
local_irq_restore(flags);
}
+/*
+ * mem_cgroup_try_recharge - try to recharge page to mm's memcg.
+ *
+ * Page must be locked and isolated.
+ */
+int mem_cgroup_try_recharge(struct page *page, struct mm_struct *mm,
+ gfp_t gfp_mask)
+{
+ struct mem_cgroup *from, *to;
+ int nr_pages;
+ int err = 0;
+
+ VM_BUG_ON_PAGE(!PageLocked(page), page);
+ VM_BUG_ON_PAGE(PageLRU(page), page);
+
+ if (mem_cgroup_disabled())
+ return 0;
+
+ from = page->mem_cgroup;
+ to = get_mem_cgroup_from_mm(mm);
+
+ if (likely(from == to) || !from)
+ goto out;
+
+ nr_pages = hpage_nr_pages(page);
+ err = try_charge(to, gfp_mask, nr_pages);
+ if (err)
+ goto out;
+
+ err = mem_cgroup_move_account(page, nr_pages > 1, from, to);
+ if (err)
+ cancel_charge(to, nr_pages);
+ else
+ cancel_charge(from, nr_pages);
+out:
+ css_put(&to->css);
+
+ return err;
+}
+
DEFINE_STATIC_KEY_FALSE(memcg_sockets_enabled_key);
EXPORT_SYMBOL(memcg_sockets_enabled_key);
Powered by blists - more mailing lists