Skip to contentSkip to conversation

mm, memcontrol: Implement memory.swap.events

PATCH Superseded Tejun Heo 3 participants 7 messages Mar 24, 2018 – Apr 12, 2018

Subsystems (7)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore

Tejun Heo

author maintainer
#0 lore raw

PATCH 1/1 mm, memcontrol: Implement memory.swap.events

Hello,

This patchset implements memory.swap.events which contains max and fail events so that userland can monitor and respond to swap running out. It contains the following two patches.

0001-mm-memcontrol-Move-swap-charge-handling-into-get_swa.patch 0002-mm-memcontrol-Implement-memory.swap.events.patch

This patchset is on top of the "cgroup/for-4.17: Make cgroup_rstat available to controllers" patchset[1] and "mm, memcontrol: Make cgroup_rstat available to controllers" patchset[2] and also available in the following git branch.

git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git review-memcg-swap.events

diffstat follows.

 Documentation/cgroup-v2.txt |   16 ++++++++++++++++
 include/linux/memcontrol.h  |    5 +++++
 mm/memcontrol.c             |   25 +++++++++++++++++++++++++
 mm/shmem.c                  |    4 ----
 mm/swap_slots.c             |   10 +++++++---
 mm/swap_state.c             |    3 ---
 6 files changed, 53 insertions(+), 10 deletions(-)

Thanks.

--
tejun

[1] http://lkml.kernel.org/r/[email protected]
[2] http://lkml.kernel.org/r/[email protected]

author maintainer
#1 lore raw

PATCH 1/2 mm, memcontrol: Move swap charge handling into get_swap_page()

get_swap_page() is always followed by mem_cgroup_try_charge_swap(). This patch moves mem_cgroup_try_charge_swap() into get_swap_page() and makes get_swap_page() call the function even after swap allocation failure.

This simplifies the callers and consolidates memcg related logic and will ease adding swap related memcg events.

Cc Johannes Weiner <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Vladimir Davydov <[email protected]>
Cc Roman Gushchin <[email protected]>
Cc Rik van Riel <[email protected]>
Cc Andrew Morton <[email protected]>
---
 mm/memcontrol.c |  3 +++
 mm/shmem.c      |  4 ----
 mm/swap_slots.c | 10 +++++++---
 mm/swap_state.c |  3 ---
 4 files changed, 10 insertions(+), 10 deletions(-)
mm/memcontrol.c +3 -0
index d5bf01d..9f9c8a7 100644
@@ -5987,6 +5987,9 @@ int mem_cgroup_try_charge_swap(struct page *page, swp_entry_t entry)
 	if (!memcg)
 		return 0;
 
+	if (!entry.val)
+		return 0;
+
 	memcg = mem_cgroup_id_get_online(memcg);
 
 	if (!mem_cgroup_is_root(memcg) &&
mm/shmem.c +0 -4
index 1907688..4a07d21 100644
@@ -1313,9 +1313,6 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc)
 	if (!swap.val)
 		goto redirty;
 
-	if (mem_cgroup_try_charge_swap(page, swap))
-		goto free_swap;
-
 	/*
 	 * Add inode to shmem_unuse()'s list of swapped-out inodes,
 	 * if it's not already there.  Do it now before the page is
@@ -1344,7 +1341,6 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc)
 	}
 
 	mutex_unlock(&shmem_swaplist_mutex);
-free_swap:
 	put_swap_page(page, swap);
 redirty:
 	set_page_dirty(page);
mm/swap_slots.c +7 -3
index bebc192..7546eb2 100644
@@ -319,7 +319,7 @@ swp_entry_t get_swap_page(struct page *page)
 	if (PageTransHuge(page)) {
 		if (IS_ENABLED(CONFIG_THP_SWAP))
 			get_swap_pages(1, true, &entry);
-		return entry;
+		goto out;
 	}
 
 	/*
@@ -349,11 +349,15 @@ swp_entry_t get_swap_page(struct page *page)
 		}
 		mutex_unlock(&cache->alloc_lock);
 		if (entry.val)
-			return entry;
+			goto out;
 	}
 
 	get_swap_pages(1, false, &entry);
-
+out:
+	if (mem_cgroup_try_charge_swap(page, entry)) {
+		put_swap_page(page, entry);
+		entry.val = 0;
+	}
 	return entry;
 }
 
mm/swap_state.c +0 -3
index 39ae7cf..41f0809 100644
@@ -216,9 +216,6 @@ int add_to_swap(struct page *page)
 	if (!entry.val)
 		return 0;
 
-	if (mem_cgroup_try_charge_swap(page, entry))
-		goto fail;
-
 	/*
 	 * Radix-tree node allocations from PF_MEMALLOC contexts could
 	 * completely exhaust the page allocator. __GFP_NOMEMALLOC
Signature · 1 line
2.9.5
author maintainer
#2 lore raw

PATCH 2/2 mm, memcontrol: Implement memory.swap.events

In reply to Tejun Heo

Add swap max and fail events so that userland can monitor and respond to running out of swap.

Cc Johannes Weiner <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Vladimir Davydov <[email protected]>
Cc Roman Gushchin <[email protected]>
Cc Rik van Riel <[email protected]>
Cc Andrew Morton <[email protected]>
---
 Documentation/cgroup-v2.txt | 16 ++++++++++++++++
 include/linux/memcontrol.h  |  5 +++++
 mm/memcontrol.c             | 24 +++++++++++++++++++++++-
 3 files changed, 44 insertions(+), 1 deletion(-)
Documentation/cgroup-v2.txt +16 -0
index 74cdeae..b0dda10 100644
@@ -1199,6 +1199,22 @@ PAGE_SIZE multiple when read back.
 	Swap usage hard limit.  If a cgroup's swap usage reaches this
 	limit, anonymous memory of the cgroup will not be swapped out.
 
+  memory.swap.events
+	A read-only flat-keyed file which exists on non-root cgroups.
+	The following entries are defined.  Unless specified
+	otherwise, a value change in this file generates a file
+	modified event.
+
+	  max
+		The number of times the cgroup's swap usage was about
+		to go over the max boundary and swap allocation
+		failed.
+
+	  fail
+		The number of times swap allocation failed either
+		because of running out of swap system-wide or max
+		limit.
+
 
 Usage Guidelines
 ~~~~~~~~~~~~~~~~
include/linux/memcontrol.h +5 -0
index 85a8f00..f198339 100644
@@ -54,6 +54,8 @@ enum memcg_event_item {
 	MEMCG_HIGH,
 	MEMCG_MAX,
 	MEMCG_OOM,
+	MEMCG_SWAP_MAX,
+	MEMCG_SWAP_FAIL,
 	MEMCG_NR_EVENTS,
 };
 
@@ -202,6 +204,9 @@ struct mem_cgroup {
 	/* handle for "memory.events" */
 	struct cgroup_file events_file;
 
+	/* handle for "memory.swap.events" */
+	struct cgroup_file swap_events_file;
+
 	/* protect arrays of thresholds */
 	struct mutex thresholds_lock;
 
mm/memcontrol.c +23 -1
index 9f9c8a7..1a14d4a4 100644
@@ -5987,13 +5987,17 @@ int mem_cgroup_try_charge_swap(struct page *page, swp_entry_t entry)
 	if (!memcg)
 		return 0;
 
-	if (!entry.val)
+	if (!entry.val) {
+		mem_cgroup_event(memcg, MEMCG_SWAP_FAIL);
 		return 0;
+	}
 
 	memcg = mem_cgroup_id_get_online(memcg);
 
 	if (!mem_cgroup_is_root(memcg) &&
 	    !page_counter_try_charge(&memcg->swap, nr_pages, &counter)) {
+		mem_cgroup_event(memcg, MEMCG_SWAP_MAX);
+		mem_cgroup_event(memcg, MEMCG_SWAP_FAIL);
 		mem_cgroup_id_put(memcg);
 		return -ENOMEM;
 	}
@@ -6131,6 +6135,18 @@ static ssize_t swap_max_write(struct kernfs_open_file *of,
 	return nbytes;
 }
 
+static int swap_events_show(struct seq_file *m, void *v)
+{
+	struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m));
+
+	memcg_stat_flush(memcg);
+
+	seq_printf(m, "max %llu\n", memcg->events[MEMCG_SWAP_MAX]);
+	seq_printf(m, "fail %llu\n", memcg->events[MEMCG_SWAP_FAIL]);
+
+	return 0;
+}
+
 static struct cftype swap_files[] = {
 	{
 		.name = "swap.current",
@@ -6143,6 +6159,12 @@ static struct cftype swap_files[] = {
 		.seq_show = swap_max_show,
 		.write = swap_max_write,
 	},
+	{
+		.name = "swap.events",
+		.flags = CFTYPE_NOT_ON_ROOT,
+		.file_offset = offsetof(struct mem_cgroup, swap_events_file),
+		.seq_show = swap_events_show,
+	},
 	{ }	/* terminate */
 };
 
Signature · 1 line
2.9.5
maintainer
#3 lore raw
In reply to Tejun Heo
Quoted 7 lines · On Sat, 24 Mar 2018 09:51:25 -0700 Tejun Heo <[email protected]> wrote:

This patchset implements memory.swap.events which contains max and fail events so that userland can monitor and respond to swap running out. It contains the following two patches.

0001-mm-memcontrol-Move-swap-charge-handling-into-get_swa.patch 0002-mm-memcontrol-Implement-memory.swap.events.patch

Quoted 6 lines

This patchset is on top of the "cgroup/for-4.17: Make cgroup_rstat available to controllers" patchset[1] and "mm, memcontrol: Make cgroup_rstat available to controllers" patchset[2] and also available in the following git branch.

git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git review-memcg-swap.events

This doesn't appear to be in linux-next yet. It should be by now if it's targeted at 4.17?

author maintainer
#4 lore raw
Quoted 14 lines · Andrew Morton
Quoted 12 lines · On Sat, 24 Mar 2018 09:51:25 -0700 Tejun Heo <[email protected]> wrote:

This patchset implements memory.swap.events which contains max and fail events so that userland can monitor and respond to swap running out. It contains the following two patches.

0001-mm-memcontrol-Move-swap-charge-handling-into-get_swa.patch 0002-mm-memcontrol-Implement-memory.swap.events.patch

This patchset is on top of the "cgroup/for-4.17: Make cgroup_rstat available to controllers" patchset[1] and "mm, memcontrol: Make cgroup_rstat available to controllers" patchset[2] and also available in the following git branch.

Quoted 4 lines
Quoted 1 line

git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git review-memcg-swap.events

This doesn't appear to be in linux-next yet. It should be by now if it's targeted at 4.17?

You're right. It's too late for 4.17. Let's aim for 4.18.

Thanks.

Signature · 1 line
tejun
maintainer
#5 lore raw
In reply to Tejun Heo

Hi Tejun,
sorry for the late response. Are you plannig to repost?

Quoted 33 lines · Tejun Heo

Hello,

This patchset implements memory.swap.events which contains max and fail events so that userland can monitor and respond to swap running out. It contains the following two patches.

0001-mm-memcontrol-Move-swap-charge-handling-into-get_swa.patch 0002-mm-memcontrol-Implement-memory.swap.events.patch

This patchset is on top of the "cgroup/for-4.17: Make cgroup_rstat available to controllers" patchset[1] and "mm, memcontrol: Make cgroup_rstat available to controllers" patchset[2] and also available in the following git branch.

git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git review-memcg-swap.events

diffstat follows.

 Documentation/cgroup-v2.txt |   16 ++++++++++++++++
 include/linux/memcontrol.h  |    5 +++++
 mm/memcontrol.c             |   25 +++++++++++++++++++++++++
 mm/shmem.c                  |    4 ----
 mm/swap_slots.c             |   10 +++++++---
 mm/swap_state.c             |    3 ---
 6 files changed, 53 insertions(+), 10 deletions(-)

Thanks.

--
tejun

[1] http://lkml.kernel.org/r/[email protected]
[2] http://lkml.kernel.org/r/[email protected]

Signature · 2 lines
Michal Hocko
SUSE Labs
author maintainer
#6 lore raw
Quoted 2 lines · Michal Hocko

Hi Tejun,
sorry for the late response. Are you plannig to repost?

Yeah, will do later.

Thanks.

Signature · 1 line
tejun