fn exec_one_cmd()

in resctl-demo/src/doc.rs [189:410]


fn exec_one_cmd(siv: &mut Cursive, cmd: &RdCmd) {
    info!("executing {:?}", cmd);

    let mut cs = CMD_STATE.lock().unwrap();
    let wbps = AGENT_FILES.bench().iocost.model.wbps as f64;

    match cmd {
        RdCmd::On(sw) | RdCmd::Off(sw) => {
            let is_on = if let RdCmd::On(_) = cmd { true } else { false };

            if is_on {
                // sync so that we don't clobber a preceding off command
                if let Err(e) = cs.sync() {
                    warn!("failed to wait for command ack ({:?})", &e);
                }
            }

            match sw {
                RdSwitch::BenchHashd => {
                    cs.bench_hashd_next = cs.bench_hashd_cur + if is_on { 1 } else { 0 };
                }
                RdSwitch::BenchHashdLoop => {
                    cs.bench_hashd_next = if is_on {
                        std::u64::MAX
                    } else {
                        cs.bench_hashd_cur
                    };
                }
                RdSwitch::BenchIoCost => {
                    cs.bench_iocost_next = cs.bench_iocost_cur + if is_on { 1 } else { 0 };
                }
                RdSwitch::BenchNeeded => {
                    if cs.bench_hashd_cur == 0 {
                        cs.bench_hashd_next = 1;
                    }
                    if cs.bench_iocost_cur == 0 {
                        cs.bench_iocost_next = 1;
                    }
                }
                RdSwitch::HashdA => cs.hashd[0].active = is_on,
                RdSwitch::HashdB => cs.hashd[1].active = is_on,
                RdSwitch::Sideload(tag, id) => {
                    if is_on {
                        cs.sideloads.insert(tag.clone(), id.clone());
                    } else {
                        cs.sideloads.remove(tag);
                    }
                }
                RdSwitch::Sysload(tag, id) => {
                    if is_on {
                        cs.sysloads.insert(tag.clone(), id.clone());
                    } else {
                        cs.sysloads.remove(tag);
                    }
                }
                RdSwitch::CpuResCtl => cs.cpu = is_on,
                RdSwitch::MemResCtl => cs.mem = is_on,
                RdSwitch::IoResCtl => cs.io = is_on,
                RdSwitch::Oomd => cs.oomd = is_on,
                RdSwitch::OomdWorkMemPressure => cs.oomd_work_mempress = is_on,
                RdSwitch::OomdWorkSenpai => cs.oomd_work_senpai = is_on,
                RdSwitch::OomdSysMemPressure => cs.oomd_sys_mempress = is_on,
                RdSwitch::OomdSysSenpai => cs.oomd_sys_senpai = is_on,
            }
        }
        RdCmd::Knob(knob, val) => match knob {
            RdKnob::HashdALoad => cs.hashd[0].rps_target_ratio = *val,
            RdKnob::HashdBLoad => cs.hashd[1].rps_target_ratio = *val,
            RdKnob::HashdALatTargetPct => cs.hashd[0].lat_target_pct = *val,
            RdKnob::HashdBLatTargetPct => cs.hashd[1].lat_target_pct = *val,
            RdKnob::HashdALatTarget => cs.hashd[0].lat_target = *val,
            RdKnob::HashdBLatTarget => cs.hashd[1].lat_target = *val,
            RdKnob::HashdAMem => cs.hashd[0].mem_ratio = Some(*val),
            RdKnob::HashdBMem => cs.hashd[1].mem_ratio = Some(*val),
            RdKnob::HashdAFileAddrStdev => {
                cs.hashd[0].file_addr_stdev = Some(if *val < 1.0 { *val } else { 100.0 });
            }
            RdKnob::HashdAAnonAddrStdev => {
                cs.hashd[0].anon_addr_stdev = Some(if *val < 1.0 { *val } else { 100.0 });
            }
            RdKnob::HashdBFileAddrStdev => {
                cs.hashd[1].file_addr_stdev = Some(if *val < 1.0 { *val } else { 100.0 });
            }
            RdKnob::HashdBAnonAddrStdev => {
                cs.hashd[1].anon_addr_stdev = Some(if *val < 1.0 { *val } else { 100.0 });
            }
            RdKnob::HashdAFile => cs.hashd[0].file_ratio = *val,
            RdKnob::HashdBFile => cs.hashd[1].file_ratio = *val,
            RdKnob::HashdAFileMax => cs.hashd[0].file_max_ratio = *val,
            RdKnob::HashdBFileMax => cs.hashd[1].file_max_ratio = *val,
            RdKnob::HashdALogBps => cs.hashd[0].log_bps = (wbps * *val).round() as u64,
            RdKnob::HashdBLogBps => cs.hashd[1].log_bps = (wbps * *val).round() as u64,
            RdKnob::HashdAWeight => cs.hashd[0].weight = *val,
            RdKnob::HashdBWeight => cs.hashd[1].weight = *val,
            RdKnob::SysCpuRatio => cs.sys_cpu_ratio = *val,
            RdKnob::SysIoRatio => cs.sys_io_ratio = *val,
            RdKnob::MemMargin => cs.mem_margin = *val,
            RdKnob::Balloon => cs.balloon_ratio = *val,
            RdKnob::CpuHeadroom => cs.cpu_headroom = *val,
        },
        RdCmd::Graph(tag_name) => {
            if tag_name.len() > 0 {
                let tag = GraphTag::into_enum_iter()
                    .filter(|x| &format!("{:?}", x) == tag_name)
                    .next()
                    .unwrap();
                set_main_graph(siv, tag);
            } else {
                clear_main_graph(siv);
            }
        }
        RdCmd::Reset(reset) => {
            let reset_benches = |cs: &mut CmdState| {
                cs.bench_hashd_next = cs.bench_hashd_cur;
                cs.bench_iocost_next = cs.bench_iocost_cur;
            };
            let reset_hashds = |cs: &mut CmdState| {
                cs.hashd[0].active = false;
                cs.hashd[1].active = false;
            };
            let reset_hashd_params = |cs: &mut CmdState| {
                cs.hashd[0] = HashdCmd {
                    active: cs.hashd[0].active,
                    ..Default::default()
                };
                cs.hashd[1] = HashdCmd {
                    active: cs.hashd[1].active,
                    ..Default::default()
                };
            };
            let reset_secondaries = |cs: &mut CmdState| {
                cs.sideloads.clear();
                cs.sysloads.clear();
            };
            let reset_resctl = |cs: &mut CmdState| {
                cs.cpu = true;
                cs.mem = true;
                cs.io = true;
            };
            let reset_resctl_params = |cs: &mut CmdState| {
                let dfl_cmd = Cmd::default();

                cs.sys_cpu_ratio = SliceConfig::DFL_SYS_CPU_RATIO;
                cs.sys_io_ratio = SliceConfig::DFL_SYS_IO_RATIO;
                cs.mem_margin = SliceConfig::dfl_mem_margin(total_memory(), *IS_FB_PROD) as f64
                    / total_memory() as f64;
                cs.balloon_ratio = dfl_cmd.balloon_ratio;
                cs.cpu_headroom = dfl_cmd.sideloader.cpu_headroom;
            };
            let reset_oomd = |cs: &mut CmdState| {
                cs.oomd = true;
                cs.oomd_work_mempress = true;
                cs.oomd_work_senpai = false;
                cs.oomd_sys_mempress = true;
                cs.oomd_sys_senpai = false;
            };
            let reset_graph = |siv: &mut Cursive| {
                clear_main_graph(siv);
            };
            let reset_all = |cs: &mut CmdState, siv: &mut Cursive| {
                reset_benches(cs);
                reset_hashds(cs);
                reset_secondaries(cs);
                reset_resctl(cs);
                reset_oomd(cs);
                reset_graph(siv);
            };
            let reset_prep = |cs: &mut CmdState, siv: &mut Cursive| {
                reset_secondaries(cs);
                reset_resctl(cs);
                reset_oomd(cs);
                reset_hashd_params(cs);
                reset_resctl_params(cs);
                reset_graph(siv);
            };

            match reset {
                RdReset::Benches => reset_benches(&mut cs),
                RdReset::Hashds => reset_hashds(&mut cs),
                RdReset::HashdParams => reset_hashd_params(&mut cs),
                RdReset::Sideloads => cs.sideloads.clear(),
                RdReset::Sysloads => cs.sysloads.clear(),
                RdReset::ResCtl => reset_resctl(&mut cs),
                RdReset::ResCtlParams => reset_resctl_params(&mut cs),
                RdReset::Oomd => reset_oomd(&mut cs),
                RdReset::Graph => reset_graph(siv),
                RdReset::Secondaries => reset_secondaries(&mut cs),
                RdReset::AllWorkloads => {
                    reset_hashds(&mut cs);
                    reset_secondaries(&mut cs);
                }
                RdReset::Protections => {
                    reset_resctl(&mut cs);
                    reset_oomd(&mut cs);
                }
                RdReset::All => {
                    reset_all(&mut cs, siv);
                }
                RdReset::Params => {
                    reset_hashd_params(&mut cs);
                    reset_resctl_params(&mut cs);
                }
                RdReset::AllWithParams => {
                    reset_all(&mut cs, siv);
                    reset_hashd_params(&mut cs);
                    reset_resctl_params(&mut cs);
                }
                RdReset::Prep => {
                    reset_prep(&mut cs, siv);
                }
            }
        }
        _ => panic!("exec_cmd: unexpected command {:?}", cmd),
    }

    if let Err(e) = cs.apply() {
        error!("failed to apply {:?} cmd ({})", cmd, &e);
    }

    drop(cs);
    refresh_cur_doc(siv);
}