mirror of
https://github.com/systemd/systemd.git
synced 2024-10-30 06:25:37 +03:00
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.
This commit is contained in:
parent
8b3b6f588c
commit
fe700f46ec
@ -1524,6 +1524,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);
|
||||
@ -2044,7 +2046,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;
|
||||
|
||||
@ -2053,7 +2069,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;
|
||||
}
|
||||
|
||||
@ -2063,6 +2082,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;
|
||||
|
@ -102,6 +102,7 @@ Unit *unit_new(Manager *m, size_t size) {
|
||||
u->job_timeout = USEC_INFINITY;
|
||||
u->ref_uid = UID_INVALID;
|
||||
u->ref_gid = GID_INVALID;
|
||||
u->cpu_usage_last = NSEC_INFINITY;
|
||||
|
||||
RATELIMIT_INIT(u->start_limit, m->default_start_limit_interval, m->default_start_limit_burst);
|
||||
RATELIMIT_INIT(u->auto_stop_ratelimit, 10 * USEC_PER_SEC, 16);
|
||||
@ -2620,7 +2621,10 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
|
||||
unit_serialize_item(u, f, "assert-result", yes_no(u->assert_result));
|
||||
|
||||
unit_serialize_item(u, f, "transient", yes_no(u->transient));
|
||||
|
||||
unit_serialize_item_format(u, f, "cpu-usage-base", "%" PRIu64, u->cpu_usage_base);
|
||||
if (u->cpu_usage_last != NSEC_INFINITY)
|
||||
unit_serialize_item_format(u, f, "cpu-usage-last", "%" PRIu64, u->cpu_usage_last);
|
||||
|
||||
if (u->cgroup_path)
|
||||
unit_serialize_item(u, f, "cgroup", u->cgroup_path);
|
||||
@ -2843,11 +2847,19 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
|
||||
|
||||
continue;
|
||||
|
||||
} else if (streq(l, "cpu-usage-base") || streq(l, "cpuacct-usage-base")) {
|
||||
} else if (STR_IN_SET(l, "cpu-usage-base", "cpuacct-usage-base")) {
|
||||
|
||||
r = safe_atou64(v, &u->cpu_usage_base);
|
||||
if (r < 0)
|
||||
log_unit_debug(u, "Failed to parse CPU usage %s, ignoring.", v);
|
||||
log_unit_debug(u, "Failed to parse CPU usage base %s, ignoring.", v);
|
||||
|
||||
continue;
|
||||
|
||||
} else if (streq(l, "cpu-usage-last")) {
|
||||
|
||||
r = safe_atou64(v, &u->cpu_usage_last);
|
||||
if (r < 0)
|
||||
log_unit_debug(u, "Failed to read CPU usage last %s, ignoring.", v);
|
||||
|
||||
continue;
|
||||
|
||||
|
@ -194,6 +194,7 @@ struct Unit {
|
||||
|
||||
/* Where the cpu.stat or cpuacct.usage was at the time the unit was started */
|
||||
nsec_t cpu_usage_base;
|
||||
nsec_t cpu_usage_last; /* the most recently read value */
|
||||
|
||||
/* Counterparts in the cgroup filesystem */
|
||||
char *cgroup_path;
|
||||
|
Loading…
Reference in New Issue
Block a user