|
@@ -4108,8 +4108,6 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype,
|
|
|
if (mem_cgroup_disabled())
|
|
|
return NULL;
|
|
|
|
|
|
- VM_BUG_ON(PageSwapCache(page));
|
|
|
-
|
|
|
if (PageTransHuge(page)) {
|
|
|
nr_pages <<= compound_order(page);
|
|
|
VM_BUG_ON(!PageTransHuge(page));
|
|
@@ -4205,6 +4203,18 @@ void mem_cgroup_uncharge_page(struct page *page)
|
|
|
if (page_mapped(page))
|
|
|
return;
|
|
|
VM_BUG_ON(page->mapping && !PageAnon(page));
|
|
|
+ /*
|
|
|
+ * If the page is in swap cache, uncharge should be deferred
|
|
|
+ * to the swap path, which also properly accounts swap usage
|
|
|
+ * and handles memcg lifetime.
|
|
|
+ *
|
|
|
+ * Note that this check is not stable and reclaim may add the
|
|
|
+ * page to swap cache at any time after this. However, if the
|
|
|
+ * page is not in swap cache by the time page->mapcount hits
|
|
|
+ * 0, there won't be any page table references to the swap
|
|
|
+ * slot, and reclaim will free it and not actually write the
|
|
|
+ * page to disk.
|
|
|
+ */
|
|
|
if (PageSwapCache(page))
|
|
|
return;
|
|
|
__mem_cgroup_uncharge_common(page, MEM_CGROUP_CHARGE_TYPE_ANON, false);
|