From 3c541e14bfa553133c3473a6ed3e4c0583ea2285 Mon Sep 17 00:00:00 2001 From: Balbir Singh Date: Thu, 7 Feb 2008 00:14:41 -0800 Subject: [PATCH] Memory controller remove control_type feature Based on the discussion at http://lkml.org/lkml/2007/12/20/383, it was felt that control_type might not be a good thing to implement right away. We can add this flexibility at a later point when required. Signed-off-by: Balbir Singh Acked-by: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 6 +-- mm/memcontrol.c | 91 +++++++------------------------------- 2 files changed, 18 insertions(+), 79 deletions(-) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index d87090eb14c0..9815951ec995 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -38,6 +38,7 @@ extern struct page_cgroup *page_get_page_cgroup(struct page *page); extern int mem_cgroup_charge(struct page *page, struct mm_struct *mm, gfp_t gfp_mask); extern void mem_cgroup_uncharge(struct page_cgroup *pc); +extern void mem_cgroup_uncharge_page(struct page *page); extern void mem_cgroup_move_lists(struct page_cgroup *pc, bool active); extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, struct list_head *dst, @@ -55,11 +56,6 @@ static inline struct mem_cgroup *mm_cgroup(const struct mm_struct *mm) return rcu_dereference(mm->mem_cgroup); } -static inline void mem_cgroup_uncharge_page(struct page *page) -{ - mem_cgroup_uncharge(page_get_page_cgroup(page)); -} - extern int mem_cgroup_prepare_migration(struct page *page); extern void mem_cgroup_end_migration(struct page *page); extern void mem_cgroup_page_migration(struct page *page, struct page *newpage); diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 315dee180129..5c2c702af617 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -131,7 +131,6 @@ struct mem_cgroup { */ struct mem_cgroup_lru_info info; - unsigned long control_type; /* control RSS or RSS+Pagecache */ int prev_priority; /* for recording reclaim priority */ /* * statistics. @@ -709,24 +708,17 @@ int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm, gfp_t gfp_mask) { int ret = 0; - struct mem_cgroup *mem; if (!mm) mm = &init_mm; - rcu_read_lock(); - mem = rcu_dereference(mm->mem_cgroup); - css_get(&mem->css); - rcu_read_unlock(); - if (mem->control_type == MEM_CGROUP_TYPE_ALL) - ret = mem_cgroup_charge_common(page, mm, gfp_mask, + ret = mem_cgroup_charge_common(page, mm, gfp_mask, MEM_CGROUP_CHARGE_TYPE_CACHE); - css_put(&mem->css); return ret; } /* * Uncharging is always a welcome operation, we never complain, simply - * uncharge. + * uncharge. This routine should be called with lock_page_cgroup held */ void mem_cgroup_uncharge(struct page_cgroup *pc) { @@ -736,8 +728,7 @@ void mem_cgroup_uncharge(struct page_cgroup *pc) unsigned long flags; /* - * This can handle cases when a page is not charged at all and we - * are switching between handling the control_type. + * Check if our page_cgroup is valid */ if (!pc) return; @@ -749,6 +740,7 @@ void mem_cgroup_uncharge(struct page_cgroup *pc) * get page->cgroup and clear it under lock. * force_empty can drop page->cgroup without checking refcnt. */ + unlock_page_cgroup(page); if (clear_page_cgroup(page, pc) == pc) { mem = pc->mem_cgroup; css_put(&mem->css); @@ -758,9 +750,17 @@ void mem_cgroup_uncharge(struct page_cgroup *pc) spin_unlock_irqrestore(&mz->lru_lock, flags); kfree(pc); } + lock_page_cgroup(page); } } +void mem_cgroup_uncharge_page(struct page *page) +{ + lock_page_cgroup(page); + mem_cgroup_uncharge(page_get_page_cgroup(page)); + unlock_page_cgroup(page); +} + /* * Returns non-zero if a page (under migration) has valid page_cgroup member. * Refcnt of page_cgroup is incremented. @@ -780,8 +780,12 @@ int mem_cgroup_prepare_migration(struct page *page) void mem_cgroup_end_migration(struct page *page) { - struct page_cgroup *pc = page_get_page_cgroup(page); + struct page_cgroup *pc; + + lock_page_cgroup(page); + pc = page_get_page_cgroup(page); mem_cgroup_uncharge(pc); + unlock_page_cgroup(page); } /* * We know both *page* and *newpage* are now not-on-LRU and Pg_locked. @@ -936,61 +940,6 @@ static ssize_t mem_cgroup_write(struct cgroup *cont, struct cftype *cft, mem_cgroup_write_strategy); } -static ssize_t mem_control_type_write(struct cgroup *cont, - struct cftype *cft, struct file *file, - const char __user *userbuf, - size_t nbytes, loff_t *pos) -{ - int ret; - char *buf, *end; - unsigned long tmp; - struct mem_cgroup *mem; - - mem = mem_cgroup_from_cont(cont); - buf = kmalloc(nbytes + 1, GFP_KERNEL); - ret = -ENOMEM; - if (buf == NULL) - goto out; - - buf[nbytes] = 0; - ret = -EFAULT; - if (copy_from_user(buf, userbuf, nbytes)) - goto out_free; - - ret = -EINVAL; - tmp = simple_strtoul(buf, &end, 10); - if (*end != '\0') - goto out_free; - - if (tmp <= MEM_CGROUP_TYPE_UNSPEC || tmp >= MEM_CGROUP_TYPE_MAX) - goto out_free; - - mem->control_type = tmp; - ret = nbytes; -out_free: - kfree(buf); -out: - return ret; -} - -static ssize_t mem_control_type_read(struct cgroup *cont, - struct cftype *cft, - struct file *file, char __user *userbuf, - size_t nbytes, loff_t *ppos) -{ - unsigned long val; - char buf[64], *s; - struct mem_cgroup *mem; - - mem = mem_cgroup_from_cont(cont); - s = buf; - val = mem->control_type; - s += sprintf(s, "%lu\n", val); - return simple_read_from_buffer((void __user *)userbuf, nbytes, - ppos, buf, s - buf); -} - - static ssize_t mem_force_empty_write(struct cgroup *cont, struct cftype *cft, struct file *file, const char __user *userbuf, @@ -1088,11 +1037,6 @@ static struct cftype mem_cgroup_files[] = { .private = RES_FAILCNT, .read = mem_cgroup_read, }, - { - .name = "control_type", - .write = mem_control_type_write, - .read = mem_control_type_read, - }, { .name = "force_empty", .write = mem_force_empty_write, @@ -1161,7 +1105,6 @@ mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) res_counter_init(&mem->res); - mem->control_type = MEM_CGROUP_TYPE_ALL; memset(&mem->info, 0, sizeof(mem->info)); for_each_node_state(node, N_POSSIBLE)