res_counter: Merge res_counter_charge and res_counter_charge_nofail
These two functions do almost the same thing and duplicate some code. Merge their implementation into a single common function. res_counter_charge_locked() takes one more parameter but it doesn't seem to be used outside res_counter.c yet anyway. There is no (intended) change in the behaviour. Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Acked-by: Glauber Costa <glommer@parallels.com> Acked-by: Kirill A. Shutemov <kirill@shutemov.name> Cc: Li Zefan <lizefan@huawei.com>
This commit is contained in:
parent
c4c27fbdda
commit
4d8438f044
@ -77,11 +77,11 @@ to work with it.
|
||||
where the charging failed.
|
||||
|
||||
d. int res_counter_charge_locked
|
||||
(struct res_counter *rc, unsigned long val)
|
||||
(struct res_counter *rc, unsigned long val, bool force)
|
||||
|
||||
The same as res_counter_charge(), but it must not acquire/release the
|
||||
res_counter->lock internally (it must be called with res_counter->lock
|
||||
held).
|
||||
held). The force parameter indicates whether we can bypass the limit.
|
||||
|
||||
e. void res_counter_uncharge[_locked]
|
||||
(struct res_counter *rc, unsigned long val)
|
||||
|
@ -116,7 +116,7 @@ void res_counter_init(struct res_counter *counter, struct res_counter *parent);
|
||||
*/
|
||||
|
||||
int __must_check res_counter_charge_locked(struct res_counter *counter,
|
||||
unsigned long val);
|
||||
unsigned long val, bool force);
|
||||
int __must_check res_counter_charge(struct res_counter *counter,
|
||||
unsigned long val, struct res_counter **limit_fail_at);
|
||||
int __must_check res_counter_charge_nofail(struct res_counter *counter,
|
||||
|
@ -22,75 +22,70 @@ void res_counter_init(struct res_counter *counter, struct res_counter *parent)
|
||||
counter->parent = parent;
|
||||
}
|
||||
|
||||
int res_counter_charge_locked(struct res_counter *counter, unsigned long val)
|
||||
int res_counter_charge_locked(struct res_counter *counter, unsigned long val,
|
||||
bool force)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (counter->usage + val > counter->limit) {
|
||||
counter->failcnt++;
|
||||
return -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
if (!force)
|
||||
return ret;
|
||||
}
|
||||
|
||||
counter->usage += val;
|
||||
if (counter->usage > counter->max_usage)
|
||||
if (!force && counter->usage > counter->max_usage)
|
||||
counter->max_usage = counter->usage;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int res_counter_charge(struct res_counter *counter, unsigned long val,
|
||||
struct res_counter **limit_fail_at)
|
||||
{
|
||||
int ret;
|
||||
unsigned long 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;
|
||||
}
|
||||
|
||||
int res_counter_charge_nofail(struct res_counter *counter, unsigned long val,
|
||||
struct res_counter **limit_fail_at)
|
||||
static int __res_counter_charge(struct res_counter *counter, unsigned long val,
|
||||
struct res_counter **limit_fail_at, bool force)
|
||||
{
|
||||
int ret, r;
|
||||
unsigned long flags;
|
||||
struct res_counter *c;
|
||||
struct res_counter *c, *u;
|
||||
|
||||
r = ret = 0;
|
||||
*limit_fail_at = NULL;
|
||||
local_irq_save(flags);
|
||||
for (c = counter; c != NULL; c = c->parent) {
|
||||
spin_lock(&c->lock);
|
||||
r = res_counter_charge_locked(c, val);
|
||||
if (r)
|
||||
c->usage += val;
|
||||
r = res_counter_charge_locked(c, val, force);
|
||||
spin_unlock(&c->lock);
|
||||
if (r < 0 && ret == 0) {
|
||||
*limit_fail_at = c;
|
||||
if (r < 0 && !ret) {
|
||||
ret = r;
|
||||
*limit_fail_at = c;
|
||||
if (!force)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret < 0 && !force) {
|
||||
for (u = counter; u != c; u = u->parent) {
|
||||
spin_lock(&u->lock);
|
||||
res_counter_uncharge_locked(u, val);
|
||||
spin_unlock(&u->lock);
|
||||
}
|
||||
}
|
||||
local_irq_restore(flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int res_counter_charge(struct res_counter *counter, unsigned long val,
|
||||
struct res_counter **limit_fail_at)
|
||||
{
|
||||
return __res_counter_charge(counter, val, limit_fail_at, false);
|
||||
}
|
||||
|
||||
int res_counter_charge_nofail(struct res_counter *counter, unsigned long val,
|
||||
struct res_counter **limit_fail_at)
|
||||
{
|
||||
return __res_counter_charge(counter, val, limit_fail_at, true);
|
||||
}
|
||||
|
||||
void res_counter_uncharge_locked(struct res_counter *counter, unsigned long val)
|
||||
{
|
||||
if (WARN_ON(counter->usage < val))
|
||||
|
Loading…
Reference in New Issue
Block a user