Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 127569
b: refs/heads/master
c: 28dbc4b
h: refs/heads/master
i:
  127567: 3fc64e6
v: v3
  • Loading branch information
Balbir Singh authored and Linus Torvalds committed Jan 8, 2009
1 parent d1942f3 commit 7e31513
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 19 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: 52bc0d82100cd896213a9a25ec01c1ba87b939db
refs/heads/master: 28dbc4b6a01fb579a9441c7b81e3d3413dc452df
8 changes: 6 additions & 2 deletions trunk/include/linux/res_counter.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ struct res_counter {
* the routines below consider this to be IRQ-safe
*/
spinlock_t lock;
/*
* Parent counter, used for hierarchial resource accounting
*/
struct res_counter *parent;
};

/**
Expand Down Expand Up @@ -87,7 +91,7 @@ enum {
* helpers for accounting
*/

void res_counter_init(struct res_counter *counter);
void res_counter_init(struct res_counter *counter, struct res_counter *parent);

/*
* charge - try to consume more resource.
Expand All @@ -103,7 +107,7 @@ void res_counter_init(struct res_counter *counter);
int __must_check res_counter_charge_locked(struct res_counter *counter,
unsigned long val);
int __must_check res_counter_charge(struct res_counter *counter,
unsigned long val);
unsigned long val, struct res_counter **limit_fail_at);

/*
* uncharge - tell that some portion of the resource is released
Expand Down
44 changes: 35 additions & 9 deletions trunk/kernel/res_counter.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
#include <linux/uaccess.h>
#include <linux/mm.h>

void res_counter_init(struct res_counter *counter)
void res_counter_init(struct res_counter *counter, struct res_counter *parent)
{
spin_lock_init(&counter->lock);
counter->limit = (unsigned long long)LLONG_MAX;
counter->parent = parent;
}

int res_counter_charge_locked(struct res_counter *counter, unsigned long val)
Expand All @@ -34,14 +35,34 @@ int res_counter_charge_locked(struct res_counter *counter, unsigned long val)
return 0;
}

int res_counter_charge(struct res_counter *counter, unsigned long val)
int res_counter_charge(struct res_counter *counter, unsigned long val,
struct res_counter **limit_fail_at)
{
int ret;
unsigned long flags;

spin_lock_irqsave(&counter->lock, flags);
ret = res_counter_charge_locked(counter, val);
spin_unlock_irqrestore(&counter->lock, flags);
struct res_counter *c, *u;

*limit_fail_at = NULL;
local_irq_save(flags);
for (c = counter; c != NULL; c = c->parent) {
spin_lock(&c->lock);
ret = res_counter_charge_locked(c, val);
spin_unlock(&c->lock);
if (ret < 0) {
*limit_fail_at = c;
goto undo;
}
}
ret = 0;
goto done;
undo:
for (u = counter; u != c; u = u->parent) {
spin_lock(&u->lock);
res_counter_uncharge_locked(u, val);
spin_unlock(&u->lock);
}
done:
local_irq_restore(flags);
return ret;
}

Expand All @@ -56,10 +77,15 @@ void res_counter_uncharge_locked(struct res_counter *counter, unsigned long val)
void res_counter_uncharge(struct res_counter *counter, unsigned long val)
{
unsigned long flags;
struct res_counter *c;

spin_lock_irqsave(&counter->lock, flags);
res_counter_uncharge_locked(counter, val);
spin_unlock_irqrestore(&counter->lock, flags);
local_irq_save(flags);
for (c = counter; c != NULL; c = c->parent) {
spin_lock(&c->lock);
res_counter_uncharge_locked(c, val);
spin_unlock(&c->lock);
}
local_irq_restore(flags);
}


Expand Down
20 changes: 13 additions & 7 deletions trunk/mm/memcontrol.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
{
struct mem_cgroup *mem;
int nr_retries = MEM_CGROUP_RECLAIM_RETRIES;
struct res_counter *fail_res;
/*
* We always charge the cgroup the mm_struct belongs to.
* The mm_struct's mem_cgroup changes on task migration if the
Expand Down Expand Up @@ -499,11 +500,12 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
int ret;
bool noswap = false;

ret = res_counter_charge(&mem->res, PAGE_SIZE);
ret = res_counter_charge(&mem->res, PAGE_SIZE, &fail_res);
if (likely(!ret)) {
if (!do_swap_account)
break;
ret = res_counter_charge(&mem->memsw, PAGE_SIZE);
ret = res_counter_charge(&mem->memsw, PAGE_SIZE,
&fail_res);
if (likely(!ret))
break;
/* mem+swap counter fails */
Expand Down Expand Up @@ -1709,22 +1711,26 @@ static void __init enable_swap_cgroup(void)
static struct cgroup_subsys_state *
mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont)
{
struct mem_cgroup *mem;
struct mem_cgroup *mem, *parent;
int node;

mem = mem_cgroup_alloc();
if (!mem)
return ERR_PTR(-ENOMEM);

res_counter_init(&mem->res);
res_counter_init(&mem->memsw);

for_each_node_state(node, N_POSSIBLE)
if (alloc_mem_cgroup_per_zone_info(mem, node))
goto free_out;
/* root ? */
if (cont->parent == NULL)
if (cont->parent == NULL) {
enable_swap_cgroup();
parent = NULL;
} else
parent = mem_cgroup_from_cont(cont->parent);

res_counter_init(&mem->res, parent ? &parent->res : NULL);
res_counter_init(&mem->memsw, parent ? &parent->memsw : NULL);


return &mem->css;
free_out:
Expand Down

0 comments on commit 7e31513

Please sign in to comment.