manager: free the jobs hashmap after we have no jobs

After a larger transaction, e.g. after bootup, we're left with an empty hashmap
with hundreds of buckets. Long-term, it'd be better to size hashmaps down when
they are less than 1/4 full, but even if we implement that, jobs hashmap is
likely to be empty almost always, so it seems useful to deallocate it once the
jobs count reaches 0.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2020-05-28 18:39:27 +02:00
parent f6173cb955
commit a4ac27c1af
3 changed files with 13 additions and 4 deletions

View File

@ -263,6 +263,10 @@ int job_install_deserialized(Job *j) {
return log_unit_debug_errno(j->unit, SYNTHETIC_ERRNO(EEXIST),
"Unit already has a job installed. Not installing deserialized job.");
r = hashmap_ensure_allocated(&j->manager->jobs, NULL);
if (r < 0)
return r;
r = hashmap_put(j->manager->jobs, UINT32_TO_PTR(j->id), j);
if (r == -EEXIST)
return log_unit_debug_errno(j->unit, r, "Job ID %" PRIu32 " already used, cannot deserialize job.", j->id);

View File

@ -833,10 +833,6 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager
if (r < 0)
return r;
r = hashmap_ensure_allocated(&m->jobs, NULL);
if (r < 0)
return r;
r = hashmap_ensure_allocated(&m->cgroup_unit, &path_hash_ops);
if (r < 0)
return r;
@ -3963,6 +3959,11 @@ void manager_check_finished(Manager *m) {
return;
}
/* The jobs hashmap tends to grow a lot during boot, and then it's not reused until shutdown. Let's
kill the hashmap if it is relatively large. */
if (hashmap_buckets(m->jobs) > hashmap_size(m->units) / 10)
m->jobs = hashmap_free(m->jobs);
manager_flip_auto_status(m, false, "boot finished");
/* Notify Type=idle units that we are done now */

View File

@ -656,6 +656,10 @@ static int transaction_apply(
assert(!j->transaction_prev);
assert(!j->transaction_next);
r = hashmap_ensure_allocated(&m->jobs, NULL);
if (r < 0)
return r;
r = hashmap_put(m->jobs, UINT32_TO_PTR(j->id), j);
if (r < 0)
goto rollback;