populate_run_ext_all

Function populate_run_ext_all 

Source
pub fn populate_run_ext_all(stats: &mut ScenarioStats, samples: &SampleSeries)
Expand description

Run the FULL run-level ext_metrics population sequence into stats — the single source of truth shared by the eval layer (evaluate_vm_result) and crate::vmm::VmResult::run_metric, so the two produce byte-identical run-level ext maps for the same run. Reads samples + stats.phases + stats.cgroups, writes stats.ext_metrics, in the canonical order:

  1. populate_run_ext_metrics — the read_sample-wired registry family (over every freeze in samples), then the whole-run wall + IRQ rates.
  2. populate_run_ext_metrics_from_phases — the phase-only ext metrics whose read_sample is None (avg_imbalance_ratio, iteration_rate, system_time_ns, user_time_ns, the per-CPU IRQ spatial maxes, and the per-cgroup PSI-irq spatial maxes).
  3. populate_run_pooled_iterations_per_cpu_sec — the pooled cross-cgroup iterations_per_cpu_sec Rate (from stats.cgroups).
  4. populate_run_pooled_taobench — the whole-run taobench qps + hit Rates pooled cross-cgroup (from stats.cgroups[].taobench_whole).
  5. populate_run_pooled_taobench_distribution — the taobench whole-run open-loop serve-latency *_whole percentiles (union of the per-phase per-cgroup serve PlatStats histograms, percentile re-derived over the union).
  6. populate_run_pooled_schbench — the schbench whole-run loop Counter + role-separate run-delay gate-Rates (from stats.phases[].per_cgroup[].schbench raw pairs, summed over phases+cgroups).
  7. populate_run_pooled_schbench_distribution — the schbench whole-run latency/rps *_whole percentiles (union of the per-phase per-cgroup PlatStats histograms, percentile re-derived over the union).
  8. populate_run_distribution_metrics — the Distribution / WorstLowest / WakeLatencyTailRatio / WorstCrossNodeRatio re-pools (from stats.phases[].per_cgroup raw samples + stats.cgroups).

ORDER IS LOAD-BEARING: step 1 must precede step 2 so the whole-run wall + whole-run IRQ-counter deltas land before step 2’s contains_key skip (the multi-phase-rate fix); steps 3-8 fold the per-cgroup roll-up after the per-phase families.

stats.phases SHOULD be the PRE-derive_phase_metrics fold (the host buckets with the guest per-cgroup carriers folded in, before the per-phase scalar derivation) — the exact phase shape the eval layer feeds to step 2, since the eval path runs derive_phase_metrics AFTER this call. Feeding the pre-derive fold reproduces the eval sequence by construction (eval-faithful). Post-derive phases (e.g. crate::vmm::VmResult::phase_buckets) yield the SAME map today — step 2 skips is_derived keys, and every pooled scalar derive_phase_metrics writes to bucket.metrics (the schbench / taobench scalars) is MetricKind::PerPhase (which is_derived), so step 2 drops them either way — but the pre-derive fold avoids DEPENDING on that skip: a pooled key ever registered as non-derived would be folded run-level under post-derive, diverging from the eval map, but not under pre-derive. Pass the pre-derive fold (crate::vmm::VmResult::run_metric uses phase_buckets_pre_derive).