aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/cgroups/memory.txt9
-rw-r--r--include/linux/swap.h9
-rw-r--r--mm/memcontrol.c22
-rw-r--r--mm/swapfile.c31
4 files changed, 18 insertions, 53 deletions
diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt
index e479007f1a75..6a066a270fc5 100644
--- a/Documentation/cgroups/memory.txt
+++ b/Documentation/cgroups/memory.txt
@@ -184,12 +184,14 @@ behind this approach is that a cgroup that aggressively uses a shared
184page will eventually get charged for it (once it is uncharged from 184page will eventually get charged for it (once it is uncharged from
185the cgroup that brought it in -- this will happen on memory pressure). 185the cgroup that brought it in -- this will happen on memory pressure).
186 186
187But see section 8.2: when moving a task to another cgroup, its pages may
188be recharged to the new cgroup, if move_charge_at_immigrate has been chosen.
189
187Exception: If CONFIG_CGROUP_CGROUP_MEM_RES_CTLR_SWAP is not used. 190Exception: If CONFIG_CGROUP_CGROUP_MEM_RES_CTLR_SWAP is not used.
188When you do swapoff and make swapped-out pages of shmem(tmpfs) to 191When you do swapoff and make swapped-out pages of shmem(tmpfs) to
189be backed into memory in force, charges for pages are accounted against the 192be backed into memory in force, charges for pages are accounted against the
190caller of swapoff rather than the users of shmem. 193caller of swapoff rather than the users of shmem.
191 194
192
1932.4 Swap Extension (CONFIG_CGROUP_MEM_RES_CTLR_SWAP) 1952.4 Swap Extension (CONFIG_CGROUP_MEM_RES_CTLR_SWAP)
194 196
195Swap Extension allows you to record charge for swap. A swapped-in page is 197Swap Extension allows you to record charge for swap. A swapped-in page is
@@ -615,8 +617,7 @@ memory cgroup.
615 bit | what type of charges would be moved ? 617 bit | what type of charges would be moved ?
616 -----+------------------------------------------------------------------------ 618 -----+------------------------------------------------------------------------
617 0 | A charge of an anonymous page(or swap of it) used by the target task. 619 0 | A charge of an anonymous page(or swap of it) used by the target task.
618 | Those pages and swaps must be used only by the target task. You must 620 | You must enable Swap Extension(see 2.4) to enable move of swap charges.
619 | enable Swap Extension(see 2.4) to enable move of swap charges.
620 -----+------------------------------------------------------------------------ 621 -----+------------------------------------------------------------------------
621 1 | A charge of file pages(normal file, tmpfs file(e.g. ipc shared memory) 622 1 | A charge of file pages(normal file, tmpfs file(e.g. ipc shared memory)
622 | and swaps of tmpfs file) mmapped by the target task. Unlike the case of 623 | and swaps of tmpfs file) mmapped by the target task. Unlike the case of
@@ -629,8 +630,6 @@ memory cgroup.
629 630
6308.3 TODO 6318.3 TODO
631 632
632- Implement madvise(2) to let users decide the vma to be moved or not to be
633 moved.
634- All of moving charge operations are done under cgroup_mutex. It's not good 633- All of moving charge operations are done under cgroup_mutex. It's not good
635 behavior to hold the mutex too long, so we may need some trick. 634 behavior to hold the mutex too long, so we may need some trick.
636 635
diff --git a/include/linux/swap.h b/include/linux/swap.h
index d965c4bfab3a..49c0fa9ef5cf 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -359,7 +359,6 @@ struct backing_dev_info;
359#ifdef CONFIG_CGROUP_MEM_RES_CTLR 359#ifdef CONFIG_CGROUP_MEM_RES_CTLR
360extern void 360extern void
361mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent, bool swapout); 361mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent, bool swapout);
362extern int mem_cgroup_count_swap_user(swp_entry_t ent, struct page **pagep);
363#else 362#else
364static inline void 363static inline void
365mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent, bool swapout) 364mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent, bool swapout)
@@ -470,14 +469,6 @@ mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent)
470{ 469{
471} 470}
472 471
473#ifdef CONFIG_CGROUP_MEM_RES_CTLR
474static inline int
475mem_cgroup_count_swap_user(swp_entry_t ent, struct page **pagep)
476{
477 return 0;
478}
479#endif
480
481#endif /* CONFIG_SWAP */ 472#endif /* CONFIG_SWAP */
482#endif /* __KERNEL__*/ 473#endif /* __KERNEL__*/
483#endif /* _LINUX_SWAP_H */ 474#endif /* _LINUX_SWAP_H */
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index d7ce417cae7c..e7db70f3d2d6 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -5154,7 +5154,7 @@ static struct page *mc_handle_present_pte(struct vm_area_struct *vma,
5154 return NULL; 5154 return NULL;
5155 if (PageAnon(page)) { 5155 if (PageAnon(page)) {
5156 /* we don't move shared anon */ 5156 /* we don't move shared anon */
5157 if (!move_anon() || page_mapcount(page) > 2) 5157 if (!move_anon())
5158 return NULL; 5158 return NULL;
5159 } else if (!move_file()) 5159 } else if (!move_file())
5160 /* we ignore mapcount for file pages */ 5160 /* we ignore mapcount for file pages */
@@ -5165,26 +5165,32 @@ static struct page *mc_handle_present_pte(struct vm_area_struct *vma,
5165 return page; 5165 return page;
5166} 5166}
5167 5167
5168#ifdef CONFIG_SWAP
5168static struct page *mc_handle_swap_pte(struct vm_area_struct *vma, 5169static struct page *mc_handle_swap_pte(struct vm_area_struct *vma,
5169 unsigned long addr, pte_t ptent, swp_entry_t *entry) 5170 unsigned long addr, pte_t ptent, swp_entry_t *entry)
5170{ 5171{
5171 int usage_count;
5172 struct page *page = NULL; 5172 struct page *page = NULL;
5173 swp_entry_t ent = pte_to_swp_entry(ptent); 5173 swp_entry_t ent = pte_to_swp_entry(ptent);
5174 5174
5175 if (!move_anon() || non_swap_entry(ent)) 5175 if (!move_anon() || non_swap_entry(ent))
5176 return NULL; 5176 return NULL;
5177 usage_count = mem_cgroup_count_swap_user(ent, &page); 5177 /*
5178 if (usage_count > 1) { /* we don't move shared anon */ 5178 * Because lookup_swap_cache() updates some statistics counter,
5179 if (page) 5179 * we call find_get_page() with swapper_space directly.
5180 put_page(page); 5180 */
5181 return NULL; 5181 page = find_get_page(&swapper_space, ent.val);
5182 }
5183 if (do_swap_account) 5182 if (do_swap_account)
5184 entry->val = ent.val; 5183 entry->val = ent.val;
5185 5184
5186 return page; 5185 return page;
5187} 5186}
5187#else
5188static struct page *mc_handle_swap_pte(struct vm_area_struct *vma,
5189 unsigned long addr, pte_t ptent, swp_entry_t *entry)
5190{
5191 return NULL;
5192}
5193#endif
5188 5194
5189static struct page *mc_handle_file_pte(struct vm_area_struct *vma, 5195static struct page *mc_handle_file_pte(struct vm_area_struct *vma,
5190 unsigned long addr, pte_t ptent, swp_entry_t *entry) 5196 unsigned long addr, pte_t ptent, swp_entry_t *entry)
diff --git a/mm/swapfile.c b/mm/swapfile.c
index b0c86e92f42c..457b10baef59 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -717,37 +717,6 @@ int free_swap_and_cache(swp_entry_t entry)
717 return p != NULL; 717 return p != NULL;
718} 718}
719 719
720#ifdef CONFIG_CGROUP_MEM_RES_CTLR
721/**
722 * mem_cgroup_count_swap_user - count the user of a swap entry
723 * @ent: the swap entry to be checked
724 * @pagep: the pointer for the swap cache page of the entry to be stored
725 *
726 * Returns the number of the user of the swap entry. The number is valid only
727 * for swaps of anonymous pages.
728 * If the entry is found on swap cache, the page is stored to pagep with
729 * refcount of it being incremented.
730 */
731int mem_cgroup_count_swap_user(swp_entry_t ent, struct page **pagep)
732{
733 struct page *page;
734 struct swap_info_struct *p;
735 int count = 0;
736
737 page = find_get_page(&swapper_space, ent.val);
738 if (page)
739 count += page_mapcount(page);
740 p = swap_info_get(ent);
741 if (p) {
742 count += swap_count(p->swap_map[swp_offset(ent)]);
743 spin_unlock(&swap_lock);
744 }
745
746 *pagep = page;
747 return count;
748}
749#endif
750
751#ifdef CONFIG_HIBERNATION 720#ifdef CONFIG_HIBERNATION
752/* 721/*
753 * Find the swap type that corresponds to given device (if any). 722 * Find the swap type that corresponds to given device (if any).