Skip to content

Commit 97f9b8c

Browse files
committed
rebalance_interrupts: Run through clang-format
Change-Id: I76495309d747349077fef7980864fc794807723a
1 parent 435d54d commit 97f9b8c

1 file changed

Lines changed: 133 additions & 146 deletions

File tree

rebalance_interrupts/rebalance_interrupts.cpp

Lines changed: 133 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
*
3636
*/
3737

38-
#include <sys/types.h>
3938
#include <dirent.h>
39+
#include <sys/types.h>
4040

4141
#include <iostream>
4242
#include <list>
@@ -51,7 +51,6 @@
5151
#include <android-base/parseint.h>
5252
#include <android-base/strings.h>
5353

54-
5554
#define POLICY0_CORES_PATH "/sys/devices/system/cpu/cpufreq/policy0/affected_cpus"
5655
#define SYSFS_IRQDIR "/sys/kernel/irq"
5756
#define PROC_IRQDIR "/proc/irq"
@@ -70,158 +69,147 @@ using std::vector;
7069
// Return a vector of strings describing the affected CPUs for cpufreq
7170
// Policy 0.
7271
vector<int> Policy0AffectedCpus() {
73-
string policy0_cores_unparsed;
74-
if (!ReadFileToString(POLICY0_CORES_PATH, &policy0_cores_unparsed))
75-
return vector<int>();
76-
string policy0_trimmed = android::base::Trim(policy0_cores_unparsed);
77-
vector<string> cpus_as_string = android::base::Split(policy0_trimmed, " ");
78-
79-
vector<int> cpus_as_int;
80-
for (int i = 0; i < cpus_as_string.size(); ++i) {
81-
int cpu;
82-
if (!ParseInt(cpus_as_string[i].c_str(), &cpu))
83-
return vector<int>();
84-
cpus_as_int.push_back(cpu);
85-
}
86-
return cpus_as_int;
72+
string policy0_cores_unparsed;
73+
if (!ReadFileToString(POLICY0_CORES_PATH, &policy0_cores_unparsed)) return vector<int>();
74+
string policy0_trimmed = android::base::Trim(policy0_cores_unparsed);
75+
vector<string> cpus_as_string = android::base::Split(policy0_trimmed, " ");
76+
77+
vector<int> cpus_as_int;
78+
for (int i = 0; i < cpus_as_string.size(); ++i) {
79+
int cpu;
80+
if (!ParseInt(cpus_as_string[i].c_str(), &cpu)) return vector<int>();
81+
cpus_as_int.push_back(cpu);
82+
}
83+
return cpus_as_int;
8784
}
8885

8986
// Return a vector of strings describing the CPU masks for cpufreq Policy 0.
9087
vector<string> Policy0CpuMasks() {
91-
vector<int> cpus = Policy0AffectedCpus();
92-
vector<string> cpu_masks;
93-
for (int i = 0; i < cpus.size(); ++i)
94-
cpu_masks.push_back(fmt::format("{0:02x}", 1 << cpus[i]));
95-
return cpu_masks;
88+
vector<int> cpus = Policy0AffectedCpus();
89+
vector<string> cpu_masks;
90+
for (int i = 0; i < cpus.size(); ++i) cpu_masks.push_back(fmt::format("{0:02x}", 1 << cpus[i]));
91+
return cpu_masks;
9692
}
9793

9894
// Read the actions for the given irq# from sysfs, and add it to action_to_irq
99-
bool AddEntryToIrqmap(const char* irq,
100-
map<string, list<string>>& action_to_irqs) {
101-
const string irq_base(SYSFS_IRQDIR "/");
102-
string irq_actions_path = irq_base + irq + "/actions";
95+
bool AddEntryToIrqmap(const char* irq, map<string, list<string>>& action_to_irqs) {
96+
const string irq_base(SYSFS_IRQDIR "/");
97+
string irq_actions_path = irq_base + irq + "/actions";
10398

104-
string irq_actions;
105-
if (!ReadFileToString(irq_actions_path, &irq_actions))
106-
return false;
99+
string irq_actions;
100+
if (!ReadFileToString(irq_actions_path, &irq_actions)) return false;
107101

108-
irq_actions = Trim(irq_actions);
102+
irq_actions = Trim(irq_actions);
109103

110-
if (irq_actions == "(null)")
111-
irq_actions = "";
104+
if (irq_actions == "(null)") irq_actions = "";
112105

113-
action_to_irqs[irq_actions].push_back(irq);
106+
action_to_irqs[irq_actions].push_back(irq);
114107

115-
return true;
108+
return true;
116109
}
117110

118111
// Get a mapping of driver "action" to IRQ#s for each IRQ# in
119112
// SYSFS_IRQDIR.
120113
bool GetIrqmap(map<string, list<string>>& action_to_irqs) {
121-
bool some_success = false;
122-
std::unique_ptr<DIR, decltype(&closedir)> irq_dir(opendir(SYSFS_IRQDIR), closedir);
123-
if (!irq_dir) {
124-
PLOG(ERROR) << "opening dir " SYSFS_IRQDIR;
125-
return false;
126-
}
127-
128-
struct dirent* entry;
129-
while ((entry = readdir(irq_dir.get()))) {
130-
131-
// If the directory entry isn't a parsable number, skip it.
132-
// . and .. get skipped here.
133-
unsigned throwaway;
134-
if (!ParseUint(entry->d_name, &throwaway))
135-
continue;
136-
137-
some_success |= AddEntryToIrqmap(entry->d_name, action_to_irqs);
138-
}
139-
return some_success;
114+
bool some_success = false;
115+
std::unique_ptr<DIR, decltype(&closedir)> irq_dir(opendir(SYSFS_IRQDIR), closedir);
116+
if (!irq_dir) {
117+
PLOG(ERROR) << "opening dir " SYSFS_IRQDIR;
118+
return false;
119+
}
120+
121+
struct dirent* entry;
122+
while ((entry = readdir(irq_dir.get()))) {
123+
// If the directory entry isn't a parsable number, skip it.
124+
// . and .. get skipped here.
125+
unsigned throwaway;
126+
if (!ParseUint(entry->d_name, &throwaway)) continue;
127+
128+
some_success |= AddEntryToIrqmap(entry->d_name, action_to_irqs);
129+
}
130+
return some_success;
140131
}
141132

142133
// Given a map of irq actions -> IRQs,
143134
// find out which ones haven't been assigned and add those to
144135
// rebalance_actions.
145136
void FindUnassignedIrqs(const map<string, list<string>>& action_to_irqs,
146137
list<pair<string, list<string>>>& rebalance_actions) {
147-
for (const auto &action_to_irqs_entry: action_to_irqs) {
148-
bool rebalance = true;
149-
for (const auto& irq: action_to_irqs_entry.second) {
150-
string smp_affinity;
151-
string proc_path(PROC_IRQDIR "/");
152-
proc_path += irq + "/smp_affinity";
153-
ReadFileToString(proc_path, &smp_affinity);
154-
smp_affinity = Trim(smp_affinity);
155-
156-
// Try to respect previoulsy set IRQ affinities.
157-
// On ARM interrupt controllers under Linux, if an IRQ is assigned
158-
// to more than one core it will only be assigned to the lowest core.
159-
// Assume any IRQ which is set to more than one core in the lowest four
160-
// CPUs hasn't been assigned and needs to be rebalanced.
161-
if (smp_affinity.back() == '0' ||
162-
smp_affinity.back() == '1' ||
163-
smp_affinity.back() == '2' ||
164-
smp_affinity.back() == '4' ||
165-
smp_affinity.back() == '8') {
166-
rebalance = false;
167-
}
168-
169-
// Treat each unnamed action IRQ as independent.
170-
if (action_to_irqs_entry.first.empty()) {
171-
if (rebalance) {
172-
pair<string, list<string>> empty_action_irq;
173-
empty_action_irq.first = "";
174-
empty_action_irq.second.push_back(irq);
175-
rebalance_actions.push_back(empty_action_irq);
138+
for (const auto& action_to_irqs_entry : action_to_irqs) {
139+
bool rebalance = true;
140+
for (const auto& irq : action_to_irqs_entry.second) {
141+
string smp_affinity;
142+
string proc_path(PROC_IRQDIR "/");
143+
proc_path += irq + "/smp_affinity";
144+
ReadFileToString(proc_path, &smp_affinity);
145+
smp_affinity = Trim(smp_affinity);
146+
147+
// Try to respect previoulsy set IRQ affinities.
148+
// On ARM interrupt controllers under Linux, if an IRQ is assigned
149+
// to more than one core it will only be assigned to the lowest core.
150+
// Assume any IRQ which is set to more than one core in the lowest four
151+
// CPUs hasn't been assigned and needs to be rebalanced.
152+
if (smp_affinity.back() == '0' || smp_affinity.back() == '1' ||
153+
smp_affinity.back() == '2' || smp_affinity.back() == '4' ||
154+
smp_affinity.back() == '8') {
155+
rebalance = false;
156+
}
157+
158+
// Treat each unnamed action IRQ as independent.
159+
if (action_to_irqs_entry.first.empty()) {
160+
if (rebalance) {
161+
pair<string, list<string>> empty_action_irq;
162+
empty_action_irq.first = "";
163+
empty_action_irq.second.push_back(irq);
164+
rebalance_actions.push_back(empty_action_irq);
165+
}
166+
rebalance = true;
167+
}
168+
}
169+
if (rebalance && !action_to_irqs_entry.first.empty()) {
170+
rebalance_actions.push_back(
171+
std::make_pair(action_to_irqs_entry.first, action_to_irqs_entry.second));
176172
}
177-
rebalance = true;
178-
}
179-
}
180-
if (rebalance && !action_to_irqs_entry.first.empty()) {
181-
rebalance_actions.push_back(std::make_pair(action_to_irqs_entry.first,
182-
action_to_irqs_entry.second));
183173
}
184-
}
185174
}
186175

187176
// Read the file at `path`, Trim whitespace, see if it matches `expected_value`.
188177
// Print the results to stdout.
189-
void ReportIfAffinityUpdated(const std::string expected_value,
190-
const std::string path) {
191-
std::string readback, report;
192-
ReadFileToString(path, &readback);
193-
readback = Trim(readback);
194-
if (readback != expected_value) {
195-
report += "Unable to set ";
196-
} else {
197-
report += "Success setting ";
198-
}
199-
report += path;
200-
report += ": found " + readback + " vs " + expected_value + "\n";
201-
LOG(DEBUG) << report;
178+
void ReportIfAffinityUpdated(const std::string expected_value, const std::string path) {
179+
std::string readback, report;
180+
ReadFileToString(path, &readback);
181+
readback = Trim(readback);
182+
if (readback != expected_value) {
183+
report += "Unable to set ";
184+
} else {
185+
report += "Success setting ";
186+
}
187+
report += path;
188+
report += ": found " + readback + " vs " + expected_value + "\n";
189+
LOG(DEBUG) << report;
202190
}
203191

204192
// Evenly distribute the IRQ actions across all the Policy0 CPUs.
205193
// Assign all the IRQs of an action to a single CPU core.
206194
bool RebalanceIrqs(const list<pair<string, list<string>>>& action_to_irqs) {
207-
int mask_index = 0;
208-
std::vector<std::string> affinity_masks = Policy0CpuMasks();
209-
210-
if (affinity_masks.empty()) {
211-
LOG(ERROR) << "Unable to find Policy0 CPUs for IRQ assignment.";
212-
return false;
213-
}
214-
215-
for (const auto &action_to_irq: action_to_irqs) {
216-
for (const auto& irq: action_to_irq.second) {
217-
std::string affinity_path(PROC_IRQDIR "/");
218-
affinity_path += irq + "/smp_affinity";
219-
WriteStringToFile(affinity_masks[mask_index], affinity_path);
220-
ReportIfAffinityUpdated(affinity_masks[mask_index], affinity_path);
195+
int mask_index = 0;
196+
std::vector<std::string> affinity_masks = Policy0CpuMasks();
197+
198+
if (affinity_masks.empty()) {
199+
LOG(ERROR) << "Unable to find Policy0 CPUs for IRQ assignment.";
200+
return false;
201+
}
202+
203+
for (const auto& action_to_irq : action_to_irqs) {
204+
for (const auto& irq : action_to_irq.second) {
205+
std::string affinity_path(PROC_IRQDIR "/");
206+
affinity_path += irq + "/smp_affinity";
207+
WriteStringToFile(affinity_masks[mask_index], affinity_path);
208+
ReportIfAffinityUpdated(affinity_masks[mask_index], affinity_path);
209+
}
210+
mask_index = (mask_index + 1) % affinity_masks.size();
221211
}
222-
mask_index = (mask_index + 1) % affinity_masks.size();
223-
}
224-
return true;
212+
return true;
225213
}
226214

227215
void ChownIrqAffinity() {
@@ -231,13 +219,12 @@ void ChownIrqAffinity() {
231219
return;
232220
}
233221

234-
struct dirent *entry;
222+
struct dirent* entry;
235223
while ((entry = readdir(irq_dir.get()))) {
236224
// If the directory entry isn't a parsable number, skip it.
237225
// . and .. get skipped here.
238226
unsigned throwaway;
239-
if (!ParseUint(entry->d_name, &throwaway))
240-
continue;
227+
if (!ParseUint(entry->d_name, &throwaway)) continue;
241228

242229
string affinity_path(PROC_IRQDIR "/");
243230
affinity_path += entry->d_name;
@@ -252,29 +239,29 @@ void ChownIrqAffinity() {
252239
}
253240

254241
int main(int /* argc */, char* /* argv */[]) {
255-
map<string, list<string>> irq_mapping;
256-
list<pair<string, list<string>>> action_to_irqs;
257-
258-
// Find the mapping of "irq actions" to IRQs.
259-
// Each IRQ has an assocatied irq_actions field, showing the actions
260-
// associated with it. Multiple IRQs have the same actions.
261-
// Generate the mapping of actions to IRQs with that action,
262-
// as these IRQs should all be mapped to the same cores.
263-
if (!GetIrqmap(irq_mapping)) {
264-
LOG(ERROR) << "Unable to read IRQ mappings. Are you root?";
265-
return 1;
266-
}
267-
268-
// Change ownership of smp_affinity and smp_affinity_list handles
269-
// from root to system.
270-
ChownIrqAffinity();
271-
272-
// Some IRQs are already assigned to a subset of cores, usually for
273-
// good reason (like some drivers have an IRQ per core, for per-core
274-
// queues.) Find the set of IRQs that haven't been mapped to specific
275-
// cores.
276-
FindUnassignedIrqs(irq_mapping, action_to_irqs);
277-
278-
// Distribute the rebalancable IRQs across all cores.
279-
return RebalanceIrqs(action_to_irqs) ? 0 : 1;
242+
map<string, list<string>> irq_mapping;
243+
list<pair<string, list<string>>> action_to_irqs;
244+
245+
// Find the mapping of "irq actions" to IRQs.
246+
// Each IRQ has an assocatied irq_actions field, showing the actions
247+
// associated with it. Multiple IRQs have the same actions.
248+
// Generate the mapping of actions to IRQs with that action,
249+
// as these IRQs should all be mapped to the same cores.
250+
if (!GetIrqmap(irq_mapping)) {
251+
LOG(ERROR) << "Unable to read IRQ mappings. Are you root?";
252+
return 1;
253+
}
254+
255+
// Change ownership of smp_affinity and smp_affinity_list handles
256+
// from root to system.
257+
ChownIrqAffinity();
258+
259+
// Some IRQs are already assigned to a subset of cores, usually for
260+
// good reason (like some drivers have an IRQ per core, for per-core
261+
// queues.) Find the set of IRQs that haven't been mapped to specific
262+
// cores.
263+
FindUnassignedIrqs(irq_mapping, action_to_irqs);
264+
265+
// Distribute the rebalancable IRQs across all cores.
266+
return RebalanceIrqs(action_to_irqs) ? 0 : 1;
280267
}

0 commit comments

Comments
 (0)