aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r--mm/memcontrol.c56
1 files changed, 44 insertions, 12 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index e5277e8a42a8..be5f478351bd 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -250,6 +250,7 @@ struct mem_cgroup {
250 */ 250 */
251enum move_type { 251enum move_type {
252 MOVE_CHARGE_TYPE_ANON, /* private anonymous page and swap of it */ 252 MOVE_CHARGE_TYPE_ANON, /* private anonymous page and swap of it */
253 MOVE_CHARGE_TYPE_FILE, /* file page(including tmpfs) and swap of it */
253 NR_MOVE_TYPE, 254 NR_MOVE_TYPE,
254}; 255};
255 256
@@ -272,6 +273,12 @@ static bool move_anon(void)
272 &mc.to->move_charge_at_immigrate); 273 &mc.to->move_charge_at_immigrate);
273} 274}
274 275
276static bool move_file(void)
277{
278 return test_bit(MOVE_CHARGE_TYPE_FILE,
279 &mc.to->move_charge_at_immigrate);
280}
281
275/* 282/*
276 * Maximum loops in mem_cgroup_hierarchical_reclaim(), used for soft 283 * Maximum loops in mem_cgroup_hierarchical_reclaim(), used for soft
277 * limit reclaim to prevent infinite loops, if they ever occur. 284 * limit reclaim to prevent infinite loops, if they ever occur.
@@ -4179,11 +4186,8 @@ static struct page *mc_handle_present_pte(struct vm_area_struct *vma,
4179 /* we don't move shared anon */ 4186 /* we don't move shared anon */
4180 if (!move_anon() || page_mapcount(page) > 2) 4187 if (!move_anon() || page_mapcount(page) > 2)
4181 return NULL; 4188 return NULL;
4182 } else 4189 } else if (!move_file())
4183 /* 4190 /* we ignore mapcount for file pages */
4184 * TODO: We don't move charges of file(including shmem/tmpfs)
4185 * pages for now.
4186 */
4187 return NULL; 4191 return NULL;
4188 if (!get_page_unless_zero(page)) 4192 if (!get_page_unless_zero(page))
4189 return NULL; 4193 return NULL;
@@ -4212,6 +4216,39 @@ static struct page *mc_handle_swap_pte(struct vm_area_struct *vma,
4212 return page; 4216 return page;
4213} 4217}
4214 4218
4219static struct page *mc_handle_file_pte(struct vm_area_struct *vma,
4220 unsigned long addr, pte_t ptent, swp_entry_t *entry)
4221{
4222 struct page *page = NULL;
4223 struct inode *inode;
4224 struct address_space *mapping;
4225 pgoff_t pgoff;
4226
4227 if (!vma->vm_file) /* anonymous vma */
4228 return NULL;
4229 if (!move_file())
4230 return NULL;
4231
4232 inode = vma->vm_file->f_path.dentry->d_inode;
4233 mapping = vma->vm_file->f_mapping;
4234 if (pte_none(ptent))
4235 pgoff = linear_page_index(vma, addr);
4236 else /* pte_file(ptent) is true */
4237 pgoff = pte_to_pgoff(ptent);
4238
4239 /* page is moved even if it's not RSS of this task(page-faulted). */
4240 if (!mapping_cap_swap_backed(mapping)) { /* normal file */
4241 page = find_get_page(mapping, pgoff);
4242 } else { /* shmem/tmpfs file. we should take account of swap too. */
4243 swp_entry_t ent;
4244 mem_cgroup_get_shmem_target(inode, pgoff, &page, &ent);
4245 if (do_swap_account)
4246 entry->val = ent.val;
4247 }
4248
4249 return page;
4250}
4251
4215static int is_target_pte_for_mc(struct vm_area_struct *vma, 4252static int is_target_pte_for_mc(struct vm_area_struct *vma,
4216 unsigned long addr, pte_t ptent, union mc_target *target) 4253 unsigned long addr, pte_t ptent, union mc_target *target)
4217{ 4254{
@@ -4224,7 +4261,8 @@ static int is_target_pte_for_mc(struct vm_area_struct *vma,
4224 page = mc_handle_present_pte(vma, addr, ptent); 4261 page = mc_handle_present_pte(vma, addr, ptent);
4225 else if (is_swap_pte(ptent)) 4262 else if (is_swap_pte(ptent))
4226 page = mc_handle_swap_pte(vma, addr, ptent, &ent); 4263 page = mc_handle_swap_pte(vma, addr, ptent, &ent);
4227 /* TODO: handle swap of shmes/tmpfs */ 4264 else if (pte_none(ptent) || pte_file(ptent))
4265 page = mc_handle_file_pte(vma, addr, ptent, &ent);
4228 4266
4229 if (!page && !ent.val) 4267 if (!page && !ent.val)
4230 return 0; 4268 return 0;
@@ -4285,9 +4323,6 @@ static unsigned long mem_cgroup_count_precharge(struct mm_struct *mm)
4285 }; 4323 };
4286 if (is_vm_hugetlb_page(vma)) 4324 if (is_vm_hugetlb_page(vma))
4287 continue; 4325 continue;
4288 /* TODO: We don't move charges of shmem/tmpfs pages for now. */
4289 if (vma->vm_flags & VM_SHARED)
4290 continue;
4291 walk_page_range(vma->vm_start, vma->vm_end, 4326 walk_page_range(vma->vm_start, vma->vm_end,
4292 &mem_cgroup_count_precharge_walk); 4327 &mem_cgroup_count_precharge_walk);
4293 } 4328 }
@@ -4484,9 +4519,6 @@ static void mem_cgroup_move_charge(struct mm_struct *mm)
4484 }; 4519 };
4485 if (is_vm_hugetlb_page(vma)) 4520 if (is_vm_hugetlb_page(vma))
4486 continue; 4521 continue;
4487 /* TODO: We don't move charges of shmem/tmpfs pages for now. */
4488 if (vma->vm_flags & VM_SHARED)
4489 continue;
4490 ret = walk_page_range(vma->vm_start, vma->vm_end, 4522 ret = walk_page_range(vma->vm_start, vma->vm_end,
4491 &mem_cgroup_move_charge_walk); 4523 &mem_cgroup_move_charge_walk);
4492 if (ret) 4524 if (ret)