fn run()

in resctl-bench/src/bench/storage.rs [354:441]


    fn run(&mut self, rctx: &mut RunCtx) -> Result<serde_json::Value> {
        rctx.set_prep_testfiles()
            .disable_zswap()
            .start_agent(vec![])?;

        // Depending on mem-profile, we might be using a large balloon which
        // can push down available memory below workload's memory.low
        // cratering memory reclaim. Make sure memory protection is off. We
        // aren't testing memory protection.
        rctx.access_agent_files(|af| {
            af.slices.data.disable_seqs.mem = af.report.data.seq;
            af.slices.save().unwrap();
        });

        let saved_mem_avail_inner_retries = self.mem_avail_inner_retries;

        let mut started_at;
        let mut final_mem_probe_periods = vec![];
        let mut mem_usages = vec![];
        let mut mem_sizes = vec![];
        let mut fake_cpu_bench;

        'outer: loop {
            final_mem_probe_periods.clear();
            mem_usages.clear();
            mem_sizes.clear();
            self.mem_avail_inner_retries = saved_mem_avail_inner_retries;
            started_at = unix_now();

            let base = HashdFakeCpuBench::base(rctx);
            fake_cpu_bench = HashdFakeCpuBench {
                rps_max: self.rps_max.unwrap_or(base.rps_max),
                hash_size: self.hash_size.unwrap_or(base.hash_size),
                chunk_pages: self.chunk_pages.unwrap_or(base.chunk_pages),
                log_bps: self.log_bps,
                ..base
            };

            // We now know all the parameters. Let's run the actual benchmark.
            'inner: loop {
                info!(
                    "storage: Measuring supportable memory footprint and IO latencies ({}/{})",
                    mem_sizes.len() + 1,
                    self.loops
                );
                let (mem_size, mem_avail_err) =
                    self.measure_supportable_memory_size(rctx, &fake_cpu_bench)?;

                // check for both going over and under, see the above function
                if mem_avail_err.abs() > self.mem_avail_err_max && !rctx.test {
                    warn!(
                        "storage: mem_avail error |{:.2}|% > {:.2}%, please keep system idle",
                        mem_avail_err * 100.0,
                        self.mem_avail_err_max * 100.0
                    );

                    if self.process_retry(rctx)? {
                        continue 'outer;
                    } else {
                        continue 'inner;
                    }
                } else {
                    self.prev_mem_avail = 0;
                    self.first_try = false;
                }

                final_mem_probe_periods.push((self.mem_probe_at, unix_now()));
                mem_usages.push(self.mem_usage as f64);
                mem_sizes.push(mem_size as f64);
                info!(
                    "storage: Supportable memory footprint {}",
                    format_size(mem_size)
                );
                if mem_sizes.len() >= self.loops as usize {
                    break 'outer;
                }
            }
        }

        Ok(serde_json::to_value(&StorageRecord {
            period: (started_at, unix_now()),
            final_mem_probe_periods,
            base_hashd_knobs: rctx.access_agent_files(|af| af.bench.data.hashd.clone()),
            mem: rctx.mem_info().clone(),
            mem_usages,
            mem_sizes,
        })?)
    }