aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/memcontrol.h4
-rw-r--r--mm/memcontrol.c33
-rw-r--r--mm/shmem.c8
3 files changed, 20 insertions, 25 deletions
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index a9e3b76aa884..25b9ca93d232 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -56,7 +56,7 @@ extern void mem_cgroup_move_lists(struct page *page,
56 enum lru_list from, enum lru_list to); 56 enum lru_list from, enum lru_list to);
57extern void mem_cgroup_uncharge_page(struct page *page); 57extern void mem_cgroup_uncharge_page(struct page *page);
58extern void mem_cgroup_uncharge_cache_page(struct page *page); 58extern void mem_cgroup_uncharge_cache_page(struct page *page);
59extern int mem_cgroup_shrink_usage(struct page *page, 59extern int mem_cgroup_shmem_charge_fallback(struct page *page,
60 struct mm_struct *mm, gfp_t gfp_mask); 60 struct mm_struct *mm, gfp_t gfp_mask);
61 61
62extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, 62extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan,
@@ -155,7 +155,7 @@ static inline void mem_cgroup_uncharge_cache_page(struct page *page)
155{ 155{
156} 156}
157 157
158static inline int mem_cgroup_shrink_usage(struct page *page, 158static inline int mem_cgroup_shmem_charge_fallback(struct page *page,
159 struct mm_struct *mm, gfp_t gfp_mask) 159 struct mm_struct *mm, gfp_t gfp_mask)
160{ 160{
161 return 0; 161 return 0;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 575203ae2109..01c2d8f14685 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1617,37 +1617,28 @@ void mem_cgroup_end_migration(struct mem_cgroup *mem,
1617} 1617}
1618 1618
1619/* 1619/*
1620 * A call to try to shrink memory usage under specified resource controller. 1620 * A call to try to shrink memory usage on charge failure at shmem's swapin.
1621 * This is typically used for page reclaiming for shmem for reducing side 1621 * Calling hierarchical_reclaim is not enough because we should update
1622 * effect of page allocation from shmem, which is used by some mem_cgroup. 1622 * last_oom_jiffies to prevent pagefault_out_of_memory from invoking global OOM.
1623 * Moreover considering hierarchy, we should reclaim from the mem_over_limit,
1624 * not from the memcg which this page would be charged to.
1625 * try_charge_swapin does all of these works properly.
1623 */ 1626 */
1624int mem_cgroup_shrink_usage(struct page *page, 1627int mem_cgroup_shmem_charge_fallback(struct page *page,
1625 struct mm_struct *mm, 1628 struct mm_struct *mm,
1626 gfp_t gfp_mask) 1629 gfp_t gfp_mask)
1627{ 1630{
1628 struct mem_cgroup *mem = NULL; 1631 struct mem_cgroup *mem = NULL;
1629 int progress = 0; 1632 int ret;
1630 int retry = MEM_CGROUP_RECLAIM_RETRIES;
1631 1633
1632 if (mem_cgroup_disabled()) 1634 if (mem_cgroup_disabled())
1633 return 0; 1635 return 0;
1634 if (page)
1635 mem = try_get_mem_cgroup_from_swapcache(page);
1636 if (!mem && mm)
1637 mem = try_get_mem_cgroup_from_mm(mm);
1638 if (unlikely(!mem))
1639 return 0;
1640 1636
1641 do { 1637 ret = mem_cgroup_try_charge_swapin(mm, page, gfp_mask, &mem);
1642 progress = mem_cgroup_hierarchical_reclaim(mem, 1638 if (!ret)
1643 gfp_mask, true, false); 1639 mem_cgroup_cancel_charge_swapin(mem); /* it does !mem check */
1644 progress += mem_cgroup_check_under_limit(mem);
1645 } while (!progress && --retry);
1646 1640
1647 css_put(&mem->css); 1641 return ret;
1648 if (!retry)
1649 return -ENOMEM;
1650 return 0;
1651} 1642}
1652 1643
1653static DEFINE_MUTEX(set_limit_mutex); 1644static DEFINE_MUTEX(set_limit_mutex);
diff --git a/mm/shmem.c b/mm/shmem.c
index f9cb20ebb990..b25f95ce3db7 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1340,8 +1340,12 @@ repeat:
1340 shmem_swp_unmap(entry); 1340 shmem_swp_unmap(entry);
1341 spin_unlock(&info->lock); 1341 spin_unlock(&info->lock);
1342 if (error == -ENOMEM) { 1342 if (error == -ENOMEM) {
1343 /* allow reclaim from this memory cgroup */ 1343 /*
1344 error = mem_cgroup_shrink_usage(swappage, 1344 * reclaim from proper memory cgroup and
1345 * call memcg's OOM if needed.
1346 */
1347 error = mem_cgroup_shmem_charge_fallback(
1348 swappage,
1345 current->mm, 1349 current->mm,
1346 gfp); 1350 gfp);
1347 if (error) { 1351 if (error) {