Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4d8438f0 authored by Frederic Weisbecker's avatar Frederic Weisbecker Committed by Tejun Heo
Browse files

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: default avatarFrederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Acked-by: default avatarKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Acked-by: default avatarGlauber Costa <glommer@parallels.com>
Acked-by: default avatarKirill A. Shutemov <kirill@shutemov.name>
Cc: Li Zefan <lizefan@huawei.com>
parent c4c27fbd
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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)
+1 −1
Original line number Diff line number Diff line
@@ -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,
+34 −39
Original line number Diff line number Diff line
@@ -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;
	return ret;
}

int res_counter_charge(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;
	int ret, r;
	unsigned long flags;
	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);
		ret = res_counter_charge_locked(c, val);
		r = res_counter_charge_locked(c, val, force);
		spin_unlock(&c->lock);
		if (ret < 0) {
		if (r < 0 && !ret) {
			ret = r;
			*limit_fail_at = c;
			goto undo;
			if (!force)
				break;
		}
	}
	ret = 0;
	goto done;
undo:

	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);
		}
done:
	}
	local_irq_restore(flags);

	return ret;
}

int res_counter_charge_nofail(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, r;
	unsigned long flags;
	struct res_counter *c;

	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;
		spin_unlock(&c->lock);
		if (r < 0 && ret == 0) {
			*limit_fail_at = c;
			ret = r;
		}
	return __res_counter_charge(counter, val, limit_fail_at, false);
}
	local_irq_restore(flags);

	return ret;
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))