Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 83788
b: refs/heads/master
c: d52aa41
h: refs/heads/master
v: v3
  • Loading branch information
KAMEZAWA Hiroyuki authored and Linus Torvalds committed Feb 7, 2008
1 parent 25a8ed6 commit deca390
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3564c7c45156b358efe921ab2e4e516dad92c94c
refs/heads/master: d52aa412d43827033a8e2ce4415ef6e8f8d53635
77 changes: 72 additions & 5 deletions trunk/mm/memcontrol.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <linux/memcontrol.h>
#include <linux/cgroup.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/page-flags.h>
#include <linux/backing-dev.h>
#include <linux/bit_spinlock.h>
Expand All @@ -34,6 +35,47 @@
struct cgroup_subsys mem_cgroup_subsys;
static const int MEM_CGROUP_RECLAIM_RETRIES = 5;

/*
* Statistics for memory cgroup.
*/
enum mem_cgroup_stat_index {
/*
* For MEM_CONTAINER_TYPE_ALL, usage = pagecache + rss.
*/
MEM_CGROUP_STAT_CACHE, /* # of pages charged as cache */
MEM_CGROUP_STAT_RSS, /* # of pages charged as rss */

MEM_CGROUP_STAT_NSTATS,
};

struct mem_cgroup_stat_cpu {
s64 count[MEM_CGROUP_STAT_NSTATS];
} ____cacheline_aligned_in_smp;

struct mem_cgroup_stat {
struct mem_cgroup_stat_cpu cpustat[NR_CPUS];
};

/*
* For accounting under irq disable, no need for increment preempt count.
*/
static void __mem_cgroup_stat_add_safe(struct mem_cgroup_stat *stat,
enum mem_cgroup_stat_index idx, int val)
{
int cpu = smp_processor_id();
stat->cpustat[cpu].count[idx] += val;
}

static s64 mem_cgroup_read_stat(struct mem_cgroup_stat *stat,
enum mem_cgroup_stat_index idx)
{
int cpu;
s64 ret = 0;
for_each_possible_cpu(cpu)
ret += stat->cpustat[cpu].count[idx];
return ret;
}

/*
* The memory controller data structure. The memory controller controls both
* page cache and RSS per cgroup. We would eventually like to provide
Expand Down Expand Up @@ -63,6 +105,10 @@ struct mem_cgroup {
*/
spinlock_t lru_lock;
unsigned long control_type; /* control RSS or RSS+Pagecache */
/*
* statistics.
*/
struct mem_cgroup_stat stat;
};

/*
Expand Down Expand Up @@ -101,6 +147,24 @@ enum charge_type {
MEM_CGROUP_CHARGE_TYPE_MAPPED,
};

/*
* Always modified under lru lock. Then, not necessary to preempt_disable()
*/
static void mem_cgroup_charge_statistics(struct mem_cgroup *mem, int flags,
bool charge)
{
int val = (charge)? 1 : -1;
struct mem_cgroup_stat *stat = &mem->stat;
VM_BUG_ON(!irqs_disabled());

if (flags & PAGE_CGROUP_FLAG_CACHE)
__mem_cgroup_stat_add_safe(stat,
MEM_CGROUP_STAT_CACHE, val);
else
__mem_cgroup_stat_add_safe(stat, MEM_CGROUP_STAT_RSS, val);

}

static struct mem_cgroup init_mem_cgroup;

static inline
Expand Down Expand Up @@ -175,8 +239,8 @@ static void __always_inline unlock_page_cgroup(struct page *page)
* This can fail if the page has been tied to a page_cgroup.
* If success, returns 0.
*/
static inline int
page_cgroup_assign_new_page_cgroup(struct page *page, struct page_cgroup *pc)
static int page_cgroup_assign_new_page_cgroup(struct page *page,
struct page_cgroup *pc)
{
int ret = 0;

Expand All @@ -198,8 +262,8 @@ page_cgroup_assign_new_page_cgroup(struct page *page, struct page_cgroup *pc)
* clear_page_cgroup(page, pc) == pc
*/

static inline struct page_cgroup *
clear_page_cgroup(struct page *page, struct page_cgroup *pc)
static struct page_cgroup *clear_page_cgroup(struct page *page,
struct page_cgroup *pc)
{
struct page_cgroup *ret;
/* lock and clear */
Expand All @@ -211,7 +275,6 @@ clear_page_cgroup(struct page *page, struct page_cgroup *pc)
return ret;
}


static void __mem_cgroup_move_lists(struct page_cgroup *pc, bool active)
{
if (active) {
Expand Down Expand Up @@ -426,6 +489,8 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm,
}

spin_lock_irqsave(&mem->lru_lock, flags);
/* Update statistics vector */
mem_cgroup_charge_statistics(mem, pc->flags, true);
list_add(&pc->lru, &mem->active_list);
spin_unlock_irqrestore(&mem->lru_lock, flags);

Expand Down Expand Up @@ -496,6 +561,7 @@ void mem_cgroup_uncharge(struct page_cgroup *pc)
res_counter_uncharge(&mem->res, PAGE_SIZE);
spin_lock_irqsave(&mem->lru_lock, flags);
list_del_init(&pc->lru);
mem_cgroup_charge_statistics(mem, pc->flags, false);
spin_unlock_irqrestore(&mem->lru_lock, flags);
kfree(pc);
}
Expand Down Expand Up @@ -572,6 +638,7 @@ mem_cgroup_force_empty_list(struct mem_cgroup *mem, struct list_head *list)
css_put(&mem->css);
res_counter_uncharge(&mem->res, PAGE_SIZE);
list_del_init(&pc->lru);
mem_cgroup_charge_statistics(mem, pc->flags, false);
kfree(pc);
} else /* being uncharged ? ...do relax */
break;
Expand Down

0 comments on commit deca390

Please sign in to comment.