aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
authorBalbir Singh <balbir@linux.vnet.ibm.com>2008-02-07 03:13:57 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-07 11:42:18 -0500
commit0eea10301708c64a6b793894c156e21ddd15eb64 (patch)
treea0dcbe47d48d35ec0554faa5f86068cfab94ca6e /mm/memcontrol.c
parent66e1707bc34609f626e2e7b4fe7e454c9748bad5 (diff)
Memory controller improve user interface
Change the interface to use bytes instead of pages. Page sizes can vary across platforms and configurations. A new strategy routine has been added to the resource counters infrastructure to format the data as desired. Suggested by David Rientjes, Andrew Morton and Herbert Poetzl Tested on a UML setup with the config for memory control enabled. [kamezawa.hiroyu@jp.fujitsu.com: possible race fix in res_counter] Signed-off-by: Balbir Singh <balbir@linux.vnet.ibm.com> Signed-off-by: Pavel Emelianov <xemul@openvz.org> Cc: Paul Menage <menage@google.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Nick Piggin <nickpiggin@yahoo.com.au> Cc: Kirill Korotaev <dev@sw.ru> Cc: Herbert Poetzl <herbert@13thfloor.at> Cc: David Rientjes <rientjes@google.com> Cc: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com> Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r--mm/memcontrol.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 9e9ff914c0f1..d73692279ab1 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -302,7 +302,7 @@ retry:
302 * If we created the page_cgroup, we should free it on exceeding 302 * If we created the page_cgroup, we should free it on exceeding
303 * the cgroup limit. 303 * the cgroup limit.
304 */ 304 */
305 while (res_counter_charge(&mem->res, 1)) { 305 while (res_counter_charge(&mem->res, PAGE_SIZE)) {
306 if (try_to_free_mem_cgroup_pages(mem)) 306 if (try_to_free_mem_cgroup_pages(mem))
307 continue; 307 continue;
308 308
@@ -341,7 +341,7 @@ retry:
341 kfree(pc); 341 kfree(pc);
342 pc = race_pc; 342 pc = race_pc;
343 atomic_inc(&pc->ref_cnt); 343 atomic_inc(&pc->ref_cnt);
344 res_counter_uncharge(&mem->res, 1); 344 res_counter_uncharge(&mem->res, PAGE_SIZE);
345 css_put(&mem->css); 345 css_put(&mem->css);
346 goto done; 346 goto done;
347 } 347 }
@@ -384,7 +384,7 @@ void mem_cgroup_uncharge(struct page_cgroup *pc)
384 css_put(&mem->css); 384 css_put(&mem->css);
385 page_assign_page_cgroup(page, NULL); 385 page_assign_page_cgroup(page, NULL);
386 unlock_page_cgroup(page); 386 unlock_page_cgroup(page);
387 res_counter_uncharge(&mem->res, 1); 387 res_counter_uncharge(&mem->res, PAGE_SIZE);
388 388
389 spin_lock_irqsave(&mem->lru_lock, flags); 389 spin_lock_irqsave(&mem->lru_lock, flags);
390 list_del_init(&pc->lru); 390 list_del_init(&pc->lru);
@@ -393,12 +393,26 @@ void mem_cgroup_uncharge(struct page_cgroup *pc)
393 } 393 }
394} 394}
395 395
396static ssize_t mem_cgroup_read(struct cgroup *cont, struct cftype *cft, 396int mem_cgroup_write_strategy(char *buf, unsigned long long *tmp)
397 struct file *file, char __user *userbuf, size_t nbytes, 397{
398 loff_t *ppos) 398 *tmp = memparse(buf, &buf);
399 if (*buf != '\0')
400 return -EINVAL;
401
402 /*
403 * Round up the value to the closest page size
404 */
405 *tmp = ((*tmp + PAGE_SIZE - 1) >> PAGE_SHIFT) << PAGE_SHIFT;
406 return 0;
407}
408
409static ssize_t mem_cgroup_read(struct cgroup *cont,
410 struct cftype *cft, struct file *file,
411 char __user *userbuf, size_t nbytes, loff_t *ppos)
399{ 412{
400 return res_counter_read(&mem_cgroup_from_cont(cont)->res, 413 return res_counter_read(&mem_cgroup_from_cont(cont)->res,
401 cft->private, userbuf, nbytes, ppos); 414 cft->private, userbuf, nbytes, ppos,
415 NULL);
402} 416}
403 417
404static ssize_t mem_cgroup_write(struct cgroup *cont, struct cftype *cft, 418static ssize_t mem_cgroup_write(struct cgroup *cont, struct cftype *cft,
@@ -406,17 +420,18 @@ static ssize_t mem_cgroup_write(struct cgroup *cont, struct cftype *cft,
406 size_t nbytes, loff_t *ppos) 420 size_t nbytes, loff_t *ppos)
407{ 421{
408 return res_counter_write(&mem_cgroup_from_cont(cont)->res, 422 return res_counter_write(&mem_cgroup_from_cont(cont)->res,
409 cft->private, userbuf, nbytes, ppos); 423 cft->private, userbuf, nbytes, ppos,
424 mem_cgroup_write_strategy);
410} 425}
411 426
412static struct cftype mem_cgroup_files[] = { 427static struct cftype mem_cgroup_files[] = {
413 { 428 {
414 .name = "usage", 429 .name = "usage_in_bytes",
415 .private = RES_USAGE, 430 .private = RES_USAGE,
416 .read = mem_cgroup_read, 431 .read = mem_cgroup_read,
417 }, 432 },
418 { 433 {
419 .name = "limit", 434 .name = "limit_in_bytes",
420 .private = RES_LIMIT, 435 .private = RES_LIMIT,
421 .write = mem_cgroup_write, 436 .write = mem_cgroup_write,
422 .read = mem_cgroup_read, 437 .read = mem_cgroup_read,