|
@@ -189,6 +189,7 @@ enum charge_type {
|
|
|
MEM_CGROUP_CHARGE_TYPE_SHMEM, /* used by page migration of shmem */
|
|
|
MEM_CGROUP_CHARGE_TYPE_FORCE, /* used by force_empty */
|
|
|
MEM_CGROUP_CHARGE_TYPE_SWAPOUT, /* for accounting swapcache */
|
|
|
+ MEM_CGROUP_CHARGE_TYPE_DROP, /* a page was unused swap cache */
|
|
|
NR_CHARGE_TYPE,
|
|
|
};
|
|
|
|
|
@@ -1493,6 +1494,7 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype)
|
|
|
|
|
|
switch (ctype) {
|
|
|
case MEM_CGROUP_CHARGE_TYPE_MAPPED:
|
|
|
+ case MEM_CGROUP_CHARGE_TYPE_DROP:
|
|
|
if (page_mapped(page))
|
|
|
goto unlock_out;
|
|
|
break;
|
|
@@ -1556,18 +1558,23 @@ void mem_cgroup_uncharge_cache_page(struct page *page)
|
|
|
* called after __delete_from_swap_cache() and drop "page" account.
|
|
|
* memcg information is recorded to swap_cgroup of "ent"
|
|
|
*/
|
|
|
-void mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent)
|
|
|
+void
|
|
|
+mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent, bool swapout)
|
|
|
{
|
|
|
struct mem_cgroup *memcg;
|
|
|
+ int ctype = MEM_CGROUP_CHARGE_TYPE_SWAPOUT;
|
|
|
+
|
|
|
+ if (!swapout) /* this was a swap cache but the swap is unused ! */
|
|
|
+ ctype = MEM_CGROUP_CHARGE_TYPE_DROP;
|
|
|
+
|
|
|
+ memcg = __mem_cgroup_uncharge_common(page, ctype);
|
|
|
|
|
|
- memcg = __mem_cgroup_uncharge_common(page,
|
|
|
- MEM_CGROUP_CHARGE_TYPE_SWAPOUT);
|
|
|
/* record memcg information */
|
|
|
- if (do_swap_account && memcg) {
|
|
|
+ if (do_swap_account && swapout && memcg) {
|
|
|
swap_cgroup_record(ent, css_id(&memcg->css));
|
|
|
mem_cgroup_get(memcg);
|
|
|
}
|
|
|
- if (memcg)
|
|
|
+ if (swapout && memcg)
|
|
|
css_put(&memcg->css);
|
|
|
}
|
|
|
#endif
|