From c47f6b8504f27be9a290c4af003ec28e74979cc0 Mon Sep 17 00:00:00 2001 From: Matej Kafka Date: Fri, 23 Jul 2021 19:33:55 +0200 Subject: [PATCH] per_process_pp: Use frequency in MHz instead of index --- src/config.cpp | 65 +++++++++++++++-------- src/power_policy/imx8_per_process.hpp | 8 +-- src/process.cpp | 4 +- src/process.hpp | 4 +- test/0210-config_validation.t | 28 +++++----- test_config/per_process_power_policy.yaml | 8 +-- 6 files changed, 69 insertions(+), 48 deletions(-) diff --git a/src/config.cpp b/src/config.cpp index 21346e7c..bd4c1a6f 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -69,7 +69,7 @@ static Node normalize_process(const Node &proc, float default_budget) norm_proc[k] = proc[k].as(); } else if (k == "_a53_freq" || k == "_a72_freq") { // TODO: when the interface is finalized, remove the leading underscore - norm_proc[k] = proc[k].as(); + norm_proc[k] = proc[k].as(); } else { throw runtime_error("Unexpected config key: " + k); } @@ -111,19 +111,6 @@ static Node normalize_process(const Node &proc, float default_budget) norm_proc["init"] = false; } - if (norm_proc["_a53_freq"]) { - int a53_freq = norm_proc["_a53_freq"].as(); - if (a53_freq < 0 || a53_freq > 3) { - throw runtime_error("'_a53_freq' must be a frequency index in the interval <0, 3>"); - } - } - if (norm_proc["_a72_freq"]) { - int a72_freq = norm_proc["_a72_freq"].as(); - if (a72_freq < 0 || a72_freq > 3) { - throw runtime_error("'_a72_freq' must be a frequency index in the interval <0, 3>"); - } - } - return norm_proc; } @@ -302,6 +289,30 @@ Node Config::normalize_window(const Node &win, // in: window to normalize return norm_win; } +static unsigned int imx8_freq_i_from_freq(bool is_a53, size_t freq_MHz) +{ + // clang-format off + if (is_a53) {switch (freq_MHz) { // A53 + case 600: return 0; + case 896: return 1; + case 1104: return 2; + case 1200: return 3; + default: break; + }} else {switch (freq_MHz) { // A72 + case 600: return 0; + case 1056: return 1; + case 1296: return 2; + case 1596: return 3; + default: break; + }} + // clang-format on + throw runtime_error( + "Frequency not supported by the "s + (is_a53 ? "A53" : "A72") + " cluster: '" + + to_string(freq_MHz) + "' MHz (supported frequencies: " + + (is_a53 ? "600 MHz, 896 MHz, 1104 MHz, 1200 MHz" : "600 MHz, 1056 MHz, 1296 MHz, 1596 MHz") + + ")"); +} + /** * Check if per-process frequencies for the i.MX8 are feasible; that is, if each process * is guaranteed to have the correct frequency set and there won't ever be 2 processes @@ -326,8 +337,15 @@ void Config::validate_per_process_freq_feasibility() Imx8FreqMap part_freqs_a53(0); Imx8FreqMap part_freqs_a72(0); for (const auto &proc : part["processes"]) { - if (proc["_a53_freq"]) part_freqs_a53.set(proc["_a53_freq"].as()); - if (proc["_a72_freq"]) part_freqs_a72.set(proc["_a72_freq"].as()); + if (proc["_a53_freq"]) { + auto freq = proc["_a53_freq"].as(); + // convert the frequency back to index, as it's easier to work with here + part_freqs_a53.set(imx8_freq_i_from_freq(true, freq)); + } + if (proc["_a72_freq"]) { + auto freq = proc["_a72_freq"].as(); + part_freqs_a72.set(imx8_freq_i_from_freq(false, freq)); + } } requested_freqs[part["name"].as()] = { part_freqs_a53, part_freqs_a72 }; } @@ -541,12 +559,15 @@ void Config::create_scheduler_objects(const CgroupConfig &c, for (const auto &yprocess : ypart["processes"]) { auto budget = chrono::milliseconds(yprocess["budget"].as()); auto budget_jitter = chrono::milliseconds(yprocess["jitter"].as()); - auto _a53_freq = yprocess["_a53_freq"] - ? std::optional(yprocess["_a53_freq"].as()) - : std::nullopt; - auto _a72_freq = yprocess["_a72_freq"] - ? std::optional(yprocess["_a72_freq"].as()) - : std::nullopt; + // the freqs are already checked during validation, they should be correct + auto _a53_freq = + yprocess["_a53_freq"] + ? std::optional(1000 * 1000 * yprocess["_a53_freq"].as()) + : std::nullopt; + auto _a72_freq = + yprocess["_a72_freq"] + ? std::optional(1000 * 1000 * yprocess["_a72_freq"].as()) + : std::nullopt; partitions.back().add_process(c.loop, yprocess["cmd"].as(), process_cwd, diff --git a/src/power_policy/imx8_per_process.hpp b/src/power_policy/imx8_per_process.hpp index 8a00e0a8..331338e3 100644 --- a/src/power_policy/imx8_per_process.hpp +++ b/src/power_policy/imx8_per_process.hpp @@ -36,11 +36,11 @@ class PowerPolicy_Imx8_PerProcess : public PowerPolicy // check if the process is requesting any specific frequency and // if its current cpuset intersects with the A53/A72 cluster cpu_set proc_cpus = proc.part.current_cpus; - if (proc.a53_freq_i && proc_cpus & a53_cpus) { - a53_pol.write_frequency_i(proc.a53_freq_i.value()); + if (proc.a53_freq && proc_cpus & a53_cpus) { + a53_pol.write_frequency(proc.a53_freq.value()); } - if (proc.a72_freq_i && proc_cpus & a72_cpus) { - a72_pol.write_frequency_i(proc.a72_freq_i.value()); + if (proc.a72_freq && proc_cpus & a72_cpus) { + a72_pol.write_frequency(proc.a72_freq.value()); } } }; diff --git a/src/process.cpp b/src/process.cpp index 0b64dbd7..e4ae42f4 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -27,8 +27,8 @@ Process::Process(ev::loop_ref loop, std::optional a72_freq, bool has_initialization) : part(partition) - , a53_freq_i{a53_freq} - , a72_freq_i{a72_freq} + , a53_freq{ a53_freq } + , a72_freq{ a72_freq } // budget +- (jitter / 2) , jitter_distribution_ms(-budget_jitter.count() / 2, budget_jitter.count() - budget_jitter.count() / 2) , loop(loop) diff --git a/src/process.hpp b/src/process.hpp index 9b22c9f9..c2b1bb83 100644 --- a/src/process.hpp +++ b/src/process.hpp @@ -79,8 +79,8 @@ class Process void mark_uncompleted(); Partition ∂ - const std::optional a53_freq_i; - const std::optional a72_freq_i; + const std::optional a53_freq; + const std::optional a72_freq; private: std::uniform_int_distribution jitter_distribution_ms; diff --git a/test/0210-config_validation.t b/test/0210-config_validation.t index d50af2db..2f2552b7 100644 --- a/test/0210-config_validation.t +++ b/test/0210-config_validation.t @@ -53,8 +53,8 @@ test_validation_fail "unfeasible per-process freq combination - A53" "{ {cpu: 1, sc_partition: SC2},]} ], partitions: [ - {name: SC1, processes: [{cmd: echo, budget: 1, _a53_freq: 1}]}, - {name: SC2, processes: [{cmd: echo, budget: 1, _a53_freq: 0}]}, + {name: SC1, processes: [{cmd: echo, budget: 1, _a53_freq: 896}]}, + {name: SC2, processes: [{cmd: echo, budget: 1, _a53_freq: 600}]}, ], }" "window #0, between SC partitions on CPU cluster '0-3'." @@ -65,8 +65,8 @@ test_validation_fail "unfeasible per-process freq combination - A72" "{ {cpu: 5, sc_partition: SC2},]} ], partitions: [ - {name: SC1, processes: [{cmd: echo, budget: 1, _a72_freq: 1}]}, - {name: SC2, processes: [{cmd: echo, budget: 1, _a72_freq: 0}]}, + {name: SC1, processes: [{cmd: echo, budget: 1, _a72_freq: 1056}]}, + {name: SC2, processes: [{cmd: echo, budget: 1, _a72_freq: 600}]}, ], }" "window #0, between SC partitions on CPU cluster '4,5'." @@ -77,8 +77,8 @@ test_validation_fail "unfeasible per-process freq combination - BE" "{ {cpu: 1, be_partition: BE2},]} ], partitions: [ - {name: BE1, processes: [{cmd: echo, budget: 1, _a53_freq: 1}]}, - {name: BE2, processes: [{cmd: echo, budget: 1, _a53_freq: 0}]}, + {name: BE1, processes: [{cmd: echo, budget: 1, _a53_freq: 896}]}, + {name: BE2, processes: [{cmd: echo, budget: 1, _a53_freq: 600}]}, ], }" "window #0, between BE partitions on CPU cluster '0-3'." @@ -89,8 +89,8 @@ test_validation_pass "collision between SC and BE is ignored" "{ {cpu: 1, be_partition: BE1},]} ], partitions: [ - {name: SC1, processes: [{cmd: echo, budget: 1, _a53_freq: 0}]}, - {name: BE1, processes: [{cmd: echo, budget: 1, _a53_freq: 1}]}, + {name: SC1, processes: [{cmd: echo, budget: 1, _a53_freq: 896}]}, + {name: BE1, processes: [{cmd: echo, budget: 1, _a53_freq: 600}]}, ], }" @@ -100,8 +100,8 @@ test_validation_pass "single partition requesting multiple freqs is feasible" "{ ], partitions: [ {name: SC1, processes: [ - {cmd: echo, budget: 1, _a53_freq: 0}, - {cmd: echo, budget: 1, _a53_freq: 1}, + {cmd: echo, budget: 1, _a53_freq: 896}, + {cmd: echo, budget: 1, _a53_freq: 600}, ]} ], }" @@ -114,8 +114,8 @@ test_validation_pass "same frequency from multiple partitions is feasible" "{ ]} ], partitions: [ - {name: SC1, processes: [{cmd: echo, budget: 1, _a53_freq: 0}]}, - {name: SC2, processes: [{cmd: echo, budget: 1, _a53_freq: 0}]}, + {name: SC1, processes: [{cmd: echo, budget: 1, _a53_freq: 600}]}, + {name: SC2, processes: [{cmd: echo, budget: 1, _a53_freq: 600}]}, ], }" @@ -127,7 +127,7 @@ test_validation_pass "freqs on different clusters are feasible" "{ ]} ], partitions: [ - {name: SC1, processes: [{cmd: echo, budget: 1, _a53_freq: 0}]}, - {name: SC2, processes: [{cmd: echo, budget: 1, _a72_freq: 1}]}, + {name: SC1, processes: [{cmd: echo, budget: 1, _a53_freq: 600}]}, + {name: SC2, processes: [{cmd: echo, budget: 1, _a72_freq: 1056}]}, ], }" \ No newline at end of file diff --git a/test_config/per_process_power_policy.yaml b/test_config/per_process_power_policy.yaml index 2abaa594..34820072 100644 --- a/test_config/per_process_power_policy.yaml +++ b/test_config/per_process_power_policy.yaml @@ -9,12 +9,12 @@ partitions: processes: - cmd: echo proc0; sleep 3600 budget: 500 - _a53_freq: 3 - _a72_freq: 2 + _a53_freq: 1200 + _a72_freq: 1296 - cmd: echo proc1; sleep 3600 budget: 500 - _a53_freq: 0 - _a72_freq: 0 + _a53_freq: 600 + _a72_freq: 600 windows: - length: 1500