aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r--mm/memcontrol.c47
1 files changed, 17 insertions, 30 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index c3f09b2dda5f..14c2f2017e37 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -259,11 +259,6 @@ static void mem_cgroup_oom_notify(struct mem_cgroup *memcg);
259 * page cache and RSS per cgroup. We would eventually like to provide 259 * page cache and RSS per cgroup. We would eventually like to provide
260 * statistics based on the statistics developed by Rik Van Riel for clock-pro, 260 * statistics based on the statistics developed by Rik Van Riel for clock-pro,
261 * to help the administrator determine what knobs to tune. 261 * to help the administrator determine what knobs to tune.
262 *
263 * TODO: Add a water mark for the memory controller. Reclaim will begin when
264 * we hit the water mark. May be even add a low water mark, such that
265 * no reclaim occurs from a cgroup at it's low water mark, this is
266 * a feature that will be implemented much later in the future.
267 */ 262 */
268struct mem_cgroup { 263struct mem_cgroup {
269 struct cgroup_subsys_state css; 264 struct cgroup_subsys_state css;
@@ -460,6 +455,12 @@ static inline unsigned short mem_cgroup_id(struct mem_cgroup *memcg)
460 return memcg->css.id; 455 return memcg->css.id;
461} 456}
462 457
458/*
459 * A helper function to get mem_cgroup from ID. must be called under
460 * rcu_read_lock(). The caller is responsible for calling
461 * css_tryget_online() if the mem_cgroup is used for charging. (dropping
462 * refcnt from swap can be called against removed memcg.)
463 */
463static inline struct mem_cgroup *mem_cgroup_from_id(unsigned short id) 464static inline struct mem_cgroup *mem_cgroup_from_id(unsigned short id)
464{ 465{
465 struct cgroup_subsys_state *css; 466 struct cgroup_subsys_state *css;
@@ -673,7 +674,7 @@ static void mem_cgroup_remove_exceeded(struct mem_cgroup_per_zone *mz,
673static unsigned long soft_limit_excess(struct mem_cgroup *memcg) 674static unsigned long soft_limit_excess(struct mem_cgroup *memcg)
674{ 675{
675 unsigned long nr_pages = page_counter_read(&memcg->memory); 676 unsigned long nr_pages = page_counter_read(&memcg->memory);
676 unsigned long soft_limit = ACCESS_ONCE(memcg->soft_limit); 677 unsigned long soft_limit = READ_ONCE(memcg->soft_limit);
677 unsigned long excess = 0; 678 unsigned long excess = 0;
678 679
679 if (nr_pages > soft_limit) 680 if (nr_pages > soft_limit)
@@ -1041,7 +1042,7 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root,
1041 goto out_unlock; 1042 goto out_unlock;
1042 1043
1043 do { 1044 do {
1044 pos = ACCESS_ONCE(iter->position); 1045 pos = READ_ONCE(iter->position);
1045 /* 1046 /*
1046 * A racing update may change the position and 1047 * A racing update may change the position and
1047 * put the last reference, hence css_tryget(), 1048 * put the last reference, hence css_tryget(),
@@ -1358,13 +1359,13 @@ static unsigned long mem_cgroup_margin(struct mem_cgroup *memcg)
1358 unsigned long limit; 1359 unsigned long limit;
1359 1360
1360 count = page_counter_read(&memcg->memory); 1361 count = page_counter_read(&memcg->memory);
1361 limit = ACCESS_ONCE(memcg->memory.limit); 1362 limit = READ_ONCE(memcg->memory.limit);
1362 if (count < limit) 1363 if (count < limit)
1363 margin = limit - count; 1364 margin = limit - count;
1364 1365
1365 if (do_swap_account) { 1366 if (do_swap_account) {
1366 count = page_counter_read(&memcg->memsw); 1367 count = page_counter_read(&memcg->memsw);
1367 limit = ACCESS_ONCE(memcg->memsw.limit); 1368 limit = READ_ONCE(memcg->memsw.limit);
1368 if (count <= limit) 1369 if (count <= limit)
1369 margin = min(margin, limit - count); 1370 margin = min(margin, limit - count);
1370 } 1371 }
@@ -2349,20 +2350,6 @@ static void cancel_charge(struct mem_cgroup *memcg, unsigned int nr_pages)
2349} 2350}
2350 2351
2351/* 2352/*
2352 * A helper function to get mem_cgroup from ID. must be called under
2353 * rcu_read_lock(). The caller is responsible for calling
2354 * css_tryget_online() if the mem_cgroup is used for charging. (dropping
2355 * refcnt from swap can be called against removed memcg.)
2356 */
2357static struct mem_cgroup *mem_cgroup_lookup(unsigned short id)
2358{
2359 /* ID 0 is unused ID */
2360 if (!id)
2361 return NULL;
2362 return mem_cgroup_from_id(id);
2363}
2364
2365/*
2366 * try_get_mem_cgroup_from_page - look up page's memcg association 2353 * try_get_mem_cgroup_from_page - look up page's memcg association
2367 * @page: the page 2354 * @page: the page
2368 * 2355 *
@@ -2388,7 +2375,7 @@ struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page)
2388 ent.val = page_private(page); 2375 ent.val = page_private(page);
2389 id = lookup_swap_cgroup_id(ent); 2376 id = lookup_swap_cgroup_id(ent);
2390 rcu_read_lock(); 2377 rcu_read_lock();
2391 memcg = mem_cgroup_lookup(id); 2378 memcg = mem_cgroup_from_id(id);
2392 if (memcg && !css_tryget_online(&memcg->css)) 2379 if (memcg && !css_tryget_online(&memcg->css))
2393 memcg = NULL; 2380 memcg = NULL;
2394 rcu_read_unlock(); 2381 rcu_read_unlock();
@@ -2650,7 +2637,7 @@ struct kmem_cache *__memcg_kmem_get_cache(struct kmem_cache *cachep)
2650 return cachep; 2637 return cachep;
2651 2638
2652 memcg = get_mem_cgroup_from_mm(current->mm); 2639 memcg = get_mem_cgroup_from_mm(current->mm);
2653 kmemcg_id = ACCESS_ONCE(memcg->kmemcg_id); 2640 kmemcg_id = READ_ONCE(memcg->kmemcg_id);
2654 if (kmemcg_id < 0) 2641 if (kmemcg_id < 0)
2655 goto out; 2642 goto out;
2656 2643
@@ -5020,7 +5007,7 @@ static int mem_cgroup_can_attach(struct cgroup_subsys_state *css,
5020 * tunable will only affect upcoming migrations, not the current one. 5007 * tunable will only affect upcoming migrations, not the current one.
5021 * So we need to save it, and keep it going. 5008 * So we need to save it, and keep it going.
5022 */ 5009 */
5023 move_flags = ACCESS_ONCE(memcg->move_charge_at_immigrate); 5010 move_flags = READ_ONCE(memcg->move_charge_at_immigrate);
5024 if (move_flags) { 5011 if (move_flags) {
5025 struct mm_struct *mm; 5012 struct mm_struct *mm;
5026 struct mem_cgroup *from = mem_cgroup_from_task(p); 5013 struct mem_cgroup *from = mem_cgroup_from_task(p);
@@ -5254,7 +5241,7 @@ static u64 memory_current_read(struct cgroup_subsys_state *css,
5254static int memory_low_show(struct seq_file *m, void *v) 5241static int memory_low_show(struct seq_file *m, void *v)
5255{ 5242{
5256 struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m)); 5243 struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m));
5257 unsigned long low = ACCESS_ONCE(memcg->low); 5244 unsigned long low = READ_ONCE(memcg->low);
5258 5245
5259 if (low == PAGE_COUNTER_MAX) 5246 if (low == PAGE_COUNTER_MAX)
5260 seq_puts(m, "max\n"); 5247 seq_puts(m, "max\n");
@@ -5284,7 +5271,7 @@ static ssize_t memory_low_write(struct kernfs_open_file *of,
5284static int memory_high_show(struct seq_file *m, void *v) 5271static int memory_high_show(struct seq_file *m, void *v)
5285{ 5272{
5286 struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m)); 5273 struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m));
5287 unsigned long high = ACCESS_ONCE(memcg->high); 5274 unsigned long high = READ_ONCE(memcg->high);
5288 5275
5289 if (high == PAGE_COUNTER_MAX) 5276 if (high == PAGE_COUNTER_MAX)
5290 seq_puts(m, "max\n"); 5277 seq_puts(m, "max\n");
@@ -5314,7 +5301,7 @@ static ssize_t memory_high_write(struct kernfs_open_file *of,
5314static int memory_max_show(struct seq_file *m, void *v) 5301static int memory_max_show(struct seq_file *m, void *v)
5315{ 5302{
5316 struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m)); 5303 struct mem_cgroup *memcg = mem_cgroup_from_css(seq_css(m));
5317 unsigned long max = ACCESS_ONCE(memcg->memory.limit); 5304 unsigned long max = READ_ONCE(memcg->memory.limit);
5318 5305
5319 if (max == PAGE_COUNTER_MAX) 5306 if (max == PAGE_COUNTER_MAX)
5320 seq_puts(m, "max\n"); 5307 seq_puts(m, "max\n");
@@ -5869,7 +5856,7 @@ void mem_cgroup_uncharge_swap(swp_entry_t entry)
5869 5856
5870 id = swap_cgroup_record(entry, 0); 5857 id = swap_cgroup_record(entry, 0);
5871 rcu_read_lock(); 5858 rcu_read_lock();
5872 memcg = mem_cgroup_lookup(id); 5859 memcg = mem_cgroup_from_id(id);
5873 if (memcg) { 5860 if (memcg) {
5874 if (!mem_cgroup_is_root(memcg)) 5861 if (!mem_cgroup_is_root(memcg))
5875 page_counter_uncharge(&memcg->memsw, 1); 5862 page_counter_uncharge(&memcg->memsw, 1);