Skip to content

Commit

Permalink
per_process_pp: Use frequency in MHz instead of index
Browse files Browse the repository at this point in the history
  • Loading branch information
MatejKafka committed Sep 3, 2021
1 parent 862c42e commit c47f6b8
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 48 deletions.
65 changes: 43 additions & 22 deletions src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ static Node normalize_process(const Node &proc, float default_budget)
norm_proc[k] = proc[k].as<bool>();
} else if (k == "_a53_freq" || k == "_a72_freq") {
// TODO: when the interface is finalized, remove the leading underscore
norm_proc[k] = proc[k].as<int>();
norm_proc[k] = proc[k].as<unsigned int>();
} else {
throw runtime_error("Unexpected config key: " + k);
}
Expand Down Expand Up @@ -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<int>();
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<int>();
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;
}

Expand Down Expand Up @@ -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
Expand All @@ -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<size_t>());
if (proc["_a72_freq"]) part_freqs_a72.set(proc["_a72_freq"].as<size_t>());
if (proc["_a53_freq"]) {
auto freq = proc["_a53_freq"].as<size_t>();
// 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<size_t>();
part_freqs_a72.set(imx8_freq_i_from_freq(false, freq));
}
}
requested_freqs[part["name"].as<string>()] = { part_freqs_a53, part_freqs_a72 };
}
Expand Down Expand Up @@ -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<int>());
auto budget_jitter = chrono::milliseconds(yprocess["jitter"].as<int>());
auto _a53_freq = yprocess["_a53_freq"]
? std::optional(yprocess["_a53_freq"].as<unsigned int>())
: std::nullopt;
auto _a72_freq = yprocess["_a72_freq"]
? std::optional(yprocess["_a72_freq"].as<unsigned int>())
: 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<unsigned int>())
: std::nullopt;
auto _a72_freq =
yprocess["_a72_freq"]
? std::optional(1000 * 1000 * yprocess["_a72_freq"].as<unsigned int>())
: std::nullopt;
partitions.back().add_process(c.loop,
yprocess["cmd"].as<string>(),
process_cwd,
Expand Down
8 changes: 4 additions & 4 deletions src/power_policy/imx8_per_process.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}
};
4 changes: 2 additions & 2 deletions src/process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ Process::Process(ev::loop_ref loop,
std::optional<unsigned int> 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)
Expand Down
4 changes: 2 additions & 2 deletions src/process.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ class Process
void mark_uncompleted();

Partition &part;
const std::optional<unsigned int> a53_freq_i;
const std::optional<unsigned int> a72_freq_i;
const std::optional<unsigned int> a53_freq;
const std::optional<unsigned int> a72_freq;

private:
std::uniform_int_distribution<long> jitter_distribution_ms;
Expand Down
28 changes: 14 additions & 14 deletions test/0210-config_validation.t
Original file line number Diff line number Diff line change
Expand Up @@ -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'."

Expand All @@ -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'."

Expand All @@ -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'."

Expand All @@ -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}]},
],
}"

Expand All @@ -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},
]}
],
}"
Expand All @@ -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}]},
],
}"

Expand All @@ -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}]},
],
}"
8 changes: 4 additions & 4 deletions test_config/per_process_power_policy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit c47f6b8

Please sign in to comment.