[Devel] [PATCH rh7] ub: honor precharge when close to barrier/limit on charge
Konstantin Khorenko
khorenko at virtuozzo.com
Fri Jun 22 17:42:05 MSK 2018
charge_beancounter() does not check precharged value, it just prohibits
.held to grow more than limit/barrier which is wrong.
Solution: if fast path fails (i.e. .held is greater than limit/barrier)
than carefully count all precharges and consider them into accounting.
That way we allow .held to grow above limit/barrier due to precharge.
Fixes: d821108a8a1a ("ubc: initial patch")
https://jira.sw.ru/browse/PSBM-86044
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
kernel/bc/beancounter.c | 39 ++++++++++++++++++++++++++++++++-------
1 file changed, 32 insertions(+), 7 deletions(-)
diff --git a/kernel/bc/beancounter.c b/kernel/bc/beancounter.c
index d5de31008a5e..039b011e53af 100644
--- a/kernel/bc/beancounter.c
+++ b/kernel/bc/beancounter.c
@@ -271,6 +271,17 @@ static void __init init_beancounter_precharges_early(struct user_beancounter *ub
}
}
+static int get_ub_precharge(struct user_beancounter *ub, int resource)
+{
+ int cpu, precharge = 0;
+
+ for_each_possible_cpu(cpu) {
+ struct ub_percpu_struct *pcpu = ub_percpu(ub, cpu);
+ precharge += pcpu->precharge[resource];
+ }
+ return precharge;
+}
+
void ub_precharge_snapshot(struct user_beancounter *ub, int *precharge)
{
int cpu, resource;
@@ -841,21 +852,35 @@ EXPORT_SYMBOL(ub_subsys);
int __charge_beancounter_locked(struct user_beancounter *ub,
int resource, unsigned long val, enum ub_severity strict)
{
+ int precharge = 0;
+ unsigned long held, limit;
/*
* ub_value <= UB_MAXVALUE, value <= UB_MAXVALUE, and only one addition
- * at the moment is possible so an overflow is impossible.
+ * at the moment is possible so an overflow is impossible.
*/
ub->ub_parms[resource].held += val;
+ held = ub->ub_parms[resource].held;
switch (strict & ~UB_SEV_FLAGS) {
case UB_HARD:
- if (ub->ub_parms[resource].held >
- ub->ub_parms[resource].barrier)
- break;
+ if (held > ub->ub_parms[resource].barrier) {
+ /* close to barrier - check precharge */
+ limit = ub->ub_parms[resource].barrier;
+ precharge = get_ub_precharge(ub, resource);
+
+ if (held - precharge > limit)
+ break;
+ }
case UB_SOFT:
- if (ub->ub_parms[resource].held >
- ub->ub_parms[resource].limit)
- break;
+ if (held > ub->ub_parms[resource].limit) {
+ /* close to limit - check precharge */
+ limit = ub->ub_parms[resource].limit;
+ precharge = precharge ? :
+ get_ub_precharge(ub, resource);
+
+ if (held - precharge > limit)
+ break;
+ }
case UB_FORCE:
ub_adjust_maxheld(ub, resource);
return 0;
--
2.15.1
More information about the Devel
mailing list