|
@@ -6012,13 +6012,17 @@ int mem_cgroup_try_charge_swap(struct page *page, swp_entry_t entry)
|
|
|
if (!memcg)
|
|
|
return 0;
|
|
|
|
|
|
- if (!entry.val)
|
|
|
+ if (!entry.val) {
|
|
|
+ memcg_memory_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)) {
|
|
|
+ memcg_memory_event(memcg, MEMCG_SWAP_MAX);
|
|
|
+ memcg_memory_event(memcg, MEMCG_SWAP_FAIL);
|
|
|
mem_cgroup_id_put(memcg);
|
|
|
return -ENOMEM;
|
|
|
}
|
|
@@ -6156,6 +6160,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));
|
|
|
+
|
|
|
+ seq_printf(m, "max %lu\n",
|
|
|
+ atomic_long_read(&memcg->memory_events[MEMCG_SWAP_MAX]));
|
|
|
+ seq_printf(m, "fail %lu\n",
|
|
|
+ atomic_long_read(&memcg->memory_events[MEMCG_SWAP_FAIL]));
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static struct cftype swap_files[] = {
|
|
|
{
|
|
|
.name = "swap.current",
|
|
@@ -6168,6 +6184,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 */
|
|
|
};
|
|
|
|