[v2] beancounter: /sys/fs/cgroup/beancounter/{CT}/beancounter.numproc.failcnt output fixed

Submitted by Valeriy Vdovin on March 17, 2020, 12:40 p.m.

Details

Message ID 1584448824-49865-1-git-send-email-valeriy.vdovin@virtuozzo.com
State New
Series "beancounter: /sys/fs/cgroup/beancounter/{CT}/beancounter.numproc.failcnt output fixed"
Headers show

Commit Message

Valeriy Vdovin March 17, 2020, 12:40 p.m.
v2: 
  - Removed unnecessary precharge sutraction while reading attribute 'held'
  - Added sync for pid statistics in statd code.

Signed-off-by: Valeriy Vdovin <valeriy.vdovin@virtuozzo.com>
---
 include/bc/beancounter.h | 28 ++++++++++++++++++++++++++++
 kernel/bc/beancounter.c  | 30 ++++++++++++++++++++++++++++--
 kernel/bc/proc.c         |  9 ++++-----
 kernel/bc/statd.c        | 12 ++++++++++++
 4 files changed, 72 insertions(+), 7 deletions(-)

Patch hide | download patch | download mbox

diff --git a/include/bc/beancounter.h b/include/bc/beancounter.h
index a06d9b6..385c497 100644
--- a/include/bc/beancounter.h
+++ b/include/bc/beancounter.h
@@ -483,6 +483,24 @@  static inline void uncharge_beancounter_fast(struct user_beancounter *ub,
 	local_irq_restore(flags);
 }
 
+/*
+ * For a particular beancounter param return real 'held' value with
+ * respect to precharge.
+ */
+static inline unsigned long get_beancounter_held_real(struct ubparm *ubparm,
+               int precharge)
+{
+       unsigned long val = ubparm->held;
+
+       /*
+        * We want to catch cases where precharge might be greater
+        * than held.
+        */
+       WARN_ON_ONCE(val < precharge);
+
+       return (val > precharge) ? (val - precharge) : 0;
+}
+
 unsigned long __get_beancounter_usage_percpu(struct user_beancounter *ub,
 		int resource);
 
@@ -490,6 +508,16 @@  int precharge_beancounter(struct user_beancounter *ub,
 		int resource, unsigned long val);
 void ub_precharge_snapshot(struct user_beancounter *ub, int *precharge);
 
+/*
+ * Collect precharge for a single resource from all cpus
+ */
+int ub_precharge_snapshot_one(struct user_beancounter *ub, int resource);
+
+/*
+ * Collect precharge for each beancounter resource from all cpus
+ */
+void ub_precharge_snapshot_all(struct user_beancounter *ub, int *precharge);
+
 #define UB_IOPRIO_MIN 0
 #define UB_IOPRIO_MAX 8
 
diff --git a/kernel/bc/beancounter.c b/kernel/bc/beancounter.c
index fb63023..54c6336 100644
--- a/kernel/bc/beancounter.c
+++ b/kernel/bc/beancounter.c
@@ -292,7 +292,17 @@  static void __init init_beancounter_precharges_early(struct user_beancounter *ub
 	}
 }
 
-void ub_precharge_snapshot(struct user_beancounter *ub, int *precharge)
+int ub_precharge_snapshot_one(struct user_beancounter *ub, int resource)
+{
+       int cpu, result = 0;
+       for_each_possible_cpu(cpu) {
+               struct ub_percpu_struct *pcpu = ub_percpu(ub, cpu);
+               result += pcpu->precharge[resource];
+       }
+       return result;
+}
+
+void ub_precharge_snapshot_all(struct user_beancounter *ub, int *precharge)
 {
 	int cpu, resource;
 
@@ -308,7 +318,7 @@  static void uncharge_beancounter_precharge(struct user_beancounter *ub)
 {
 	int resource, precharge[UB_RESOURCES];
 
-	ub_precharge_snapshot(ub, precharge);
+	ub_precharge_snapshot_all(ub, precharge);
 	for ( resource = 0 ; resource < UB_RESOURCES ; resource++ )
 		ub->ub_parms[resource].held -= precharge[resource];
 }
@@ -729,6 +739,22 @@  static ssize_t ub_cgroup_resource_read(struct cgroup *cg, struct cftype *cft,
 	char str[32];
 
 	res = UB_CGROUP_RES(cft->private);
+
+	switch (res) {
+	case UB_NUMPROC:
+		ub_sync_pids(ub);
+		break;
+	case UB_KMEMSIZE:
+	case UB_DCACHESIZE:
+	case UB_PHYSPAGES:
+	case UB_SWAPPAGES:
+	case UB_OOMGUARPAGES:
+		ub_sync_memcg(ub);
+		break;
+	default:
+		break;
+	}
+
 	attr = UB_CGROUP_ATTR(cft->private);
 
 	ubparm = &ub->ub_parms[res];
diff --git a/kernel/bc/proc.c b/kernel/bc/proc.c
index efcfdbc..a65c2ae 100644
--- a/kernel/bc/proc.c
+++ b/kernel/bc/proc.c
@@ -52,8 +52,7 @@  static void ub_show_res(struct seq_file *f, struct user_beancounter *ub,
 	unsigned long held;
 
 	p = &ub->ub_parms[r];
-	held = p->held;
-	held = (held > precharge) ? (held - precharge) : 0;
+	held = get_beancounter_held_real(p, precharge);
 
 	seq_printf(f, res_fmt,
 			show_uid && r == 0 ? ub->ub_name : "",
@@ -73,7 +72,7 @@  static void __show_resources(struct seq_file *f, struct user_beancounter *ub,
 
 	ub_sync_memcg(ub);
 	ub_sync_pids(ub);
-	ub_precharge_snapshot(ub, precharge);
+	ub_precharge_snapshot_all(ub, precharge);
 
 	for (i = 0; i < UB_RESOURCES_COMPAT; i++)
 		if (strcmp(ub_rnames[i], "dummy") != 0)
@@ -104,7 +103,7 @@  static int bc_precharge_show(struct seq_file *f, void *v)
 			"resource", "real_held", "precharge", "max_precharge");
 
 	ub = seq_beancounter(f);
-	ub_precharge_snapshot(ub, precharge);
+	ub_precharge_snapshot_all(ub, precharge);
 	for ( i = 0 ; i < UB_RESOURCES ; i++ ) {
 		if (!strcmp(ub_rnames[i], "dummy"))
 			continue;
@@ -183,7 +182,7 @@  static int ub_show(struct seq_file *f, void *v)
 
 	ub_sync_memcg(ub);
 	ub_sync_pids(ub);
-	ub_precharge_snapshot(ub, precharge);
+	ub_precharge_snapshot_all(ub, precharge);
 
 	for (i = 0; i < UB_RESOURCES_COMPAT; i++)
 		ub_show_res(f, ub, i, precharge[i], 1);
diff --git a/kernel/bc/statd.c b/kernel/bc/statd.c
index a49252e..dc81959 100644
--- a/kernel/bc/statd.c
+++ b/kernel/bc/statd.c
@@ -223,6 +223,16 @@  int ubstat_alloc_store(struct user_beancounter *ub)
 }
 EXPORT_SYMBOL(ubstat_alloc_store);
 
+static bool ubstat_need_pids_sync(long cmd)
+{
+	if (UBSTAT_CMD(cmd) != UBSTAT_READ_ONE)
+		return true;
+
+	if (UBSTAT_PARMID(cmd) == UB_NUMPROC)
+		return true;
+	return false;
+}
+
 static bool ubstat_need_memcg_sync(long cmd)
 {
 	if (UBSTAT_CMD(cmd) != UBSTAT_READ_ONE)
@@ -272,6 +282,8 @@  static int ubstat_get_stat(struct user_beancounter *ub, long cmd,
 
 	if (ubstat_need_memcg_sync(cmd))
 		ub_sync_memcg(ub);
+	if (ubstat_need_pids_sync(cmd))
+		ub_sync_pids(ub);
 
 	spin_lock(&ubs_notify_lock);
 	switch (UBSTAT_CMD(cmd)) {