diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 3f96f64dad..fb89a22d2e 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -3571,12 +3571,17 @@ void unit_prune_cgroup(Unit *u) { if (!crt || !crt->cgroup_path) return; - /* Cache the last CPU and memory usage values before we destroy the cgroup */ + /* Cache the last resource usage values before we destroy the cgroup */ (void) unit_get_cpu_usage(u, /* ret = */ NULL); for (CGroupMemoryAccountingMetric metric = 0; metric <= _CGROUP_MEMORY_ACCOUNTING_METRIC_CACHED_LAST; metric++) (void) unit_get_memory_accounting(u, metric, /* ret = */ NULL); + /* All IO metrics are read at once from the underlying cgroup, so issue just a single call */ + (void) unit_get_io_accounting(u, _CGROUP_IO_ACCOUNTING_METRIC_INVALID, /* ret = */ NULL); + + /* We do not cache IP metrics here because the firewall objects are not freed with cgroups */ + #if BPF_FRAMEWORK (void) bpf_restrict_fs_cleanup(u); /* Remove cgroup from the global LSM BPF map */ #endif @@ -4858,13 +4863,19 @@ static int unit_get_io_accounting_raw( int unit_get_io_accounting( Unit *u, CGroupIOAccountingMetric metric, - bool allow_cache, uint64_t *ret) { uint64_t raw[_CGROUP_IO_ACCOUNTING_METRIC_MAX]; int r; - /* Retrieve an IO account parameter. This will subtract the counter when the unit was started. */ + /* + * Retrieve an IO counter, subtracting the value of the counter value at the time the unit was started. + * If ret == NULL and metric == _<...>_INVALID, no return value is expected (refresh the caches only). + */ + + assert(u); + assert(metric >= 0 || (!ret && metric == _CGROUP_IO_ACCOUNTING_METRIC_INVALID)); + assert(metric < _CGROUP_IO_ACCOUNTING_METRIC_MAX); if (!UNIT_CGROUP_BOOL(u, io_accounting)) return -ENODATA; @@ -4873,11 +4884,8 @@ int unit_get_io_accounting( if (!crt) return -ENODATA; - if (allow_cache && crt->io_accounting_last[metric] != UINT64_MAX) - goto done; - r = unit_get_io_accounting_raw(u, crt, raw); - if (r == -ENODATA && crt->io_accounting_last[metric] != UINT64_MAX) + if (r == -ENODATA && metric >= 0 && crt->io_accounting_last[metric] != UINT64_MAX) goto done; if (r < 0) return r; diff --git a/src/core/cgroup.h b/src/core/cgroup.h index 1c5c1f75ab..7525da728e 100644 --- a/src/core/cgroup.h +++ b/src/core/cgroup.h @@ -481,7 +481,7 @@ int unit_get_memory_current(Unit *u, uint64_t *ret); int unit_get_memory_accounting(Unit *u, CGroupMemoryAccountingMetric metric, uint64_t *ret); int unit_get_tasks_current(Unit *u, uint64_t *ret); int unit_get_cpu_usage(Unit *u, nsec_t *ret); -int unit_get_io_accounting(Unit *u, CGroupIOAccountingMetric metric, bool allow_cache, uint64_t *ret); +int unit_get_io_accounting(Unit *u, CGroupIOAccountingMetric metric, uint64_t *ret); int unit_get_ip_accounting(Unit *u, CGroupIPAccountingMetric metric, uint64_t *ret); int unit_get_effective_limit(Unit *u, CGroupLimitType type, uint64_t *ret); diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index d7869f115a..2db473fbed 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -1456,7 +1456,7 @@ static int property_get_io_counter( assert(property); assert_se((metric = cgroup_io_accounting_metric_from_string(property)) >= 0); - (void) unit_get_io_accounting(u, metric, /* allow_cache= */ false, &value); + (void) unit_get_io_accounting(u, metric, &value); return sd_bus_message_append(reply, "t", value); } diff --git a/src/core/unit.c b/src/core/unit.c index cebae4d53e..ae3cefcdde 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2385,7 +2385,7 @@ static int unit_log_resources(Unit *u) { assert(io_fields[k].journal_field); - (void) unit_get_io_accounting(u, k, k > 0, &value); + (void) unit_get_io_accounting(u, k, &value); if (value == UINT64_MAX) continue;