From 2613a7d715f38d766dc2998aa4e704494f2a58ea Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 18 Aug 2016 20:58:10 +0200 Subject: [PATCH] core: cache last CPU usage counter, before destorying a cgroup It is useful for clients to be able to read the last CPU usage counter value of a unit even if the unit is already terminated. Hence, before destroying a cgroup's cgroup cache the last CPU usage counter and return it if the cgroup is gone. --- src/core/cgroup.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index a7bb97985..16045c2d5 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -1526,6 +1526,8 @@ void unit_prune_cgroup(Unit *u) { if (!u->cgroup_path) return; + (void) unit_get_cpu_usage(u, NULL); /* Cache the last CPU usage value before we destroy the cgroup */ + is_root_slice = unit_has_name(u, SPECIAL_ROOT_SLICE); r = cg_trim_everywhere(u->manager->cgroup_supported, u->cgroup_path, !is_root_slice); @@ -2089,7 +2091,21 @@ int unit_get_cpu_usage(Unit *u, nsec_t *ret) { nsec_t ns; int r; + assert(u); + + /* Retrieve the current CPU usage counter. This will subtract the CPU counter taken when the unit was + * started. If the cgroup has been removed already, returns the last cached value. To cache the value, simply + * call this function with a NULL return value. */ + r = unit_get_cpu_usage_raw(u, &ns); + if (r == -ENODATA && u->cpu_usage_last != NSEC_INFINITY) { + /* If we can't get the CPU usage anymore (because the cgroup was already removed, for example), use our + * cached value. */ + + if (ret) + *ret = u->cpu_usage_last; + return 0; + } if (r < 0) return r; @@ -2098,7 +2114,10 @@ int unit_get_cpu_usage(Unit *u, nsec_t *ret) { else ns = 0; - *ret = ns; + u->cpu_usage_last = ns; + if (ret) + *ret = ns; + return 0; } @@ -2108,6 +2127,8 @@ int unit_reset_cpu_usage(Unit *u) { assert(u); + u->cpu_usage_last = NSEC_INFINITY; + r = unit_get_cpu_usage_raw(u, &ns); if (r < 0) { u->cpu_usage_base = 0; -- 2.30.2