Commit 34ac21b1 authored by Neil Horman's avatar Neil Horman

Fix up load estimator

Found a few bugs in the load estimator - we're were attributing load to multiple
irqs errneously, and in the process of fixing that I found that we had a bogus
topology map - the same package was getting added multiple times to a given numa
node, since we didn't already detect that was part of that nodes child list.
parent 5ebd1b24
......@@ -308,7 +308,6 @@ static void clear_irq_stats(struct irq_info *info, void *data __attribute__((unu
static void clear_obj_stats(struct topo_obj *d, void *data __attribute__((unused)))
{
d->load = 0;
for_each_object(d->children, clear_obj_stats, NULL);
for_each_irq(d->interrupts, clear_irq_stats, NULL);
}
......@@ -318,7 +317,7 @@ static void clear_obj_stats(struct topo_obj *d, void *data __attribute__((unused
* which level does how much work and the actual lists of interrupts
* assigned to each component
*/
void clear_work_stats(void)
void clear_work_stats()
{
for_each_object(numa_nodes, clear_obj_stats, NULL);
}
......
......@@ -220,12 +220,16 @@ int main(int argc, char** argv)
for_each_irq(NULL, force_rebalance_irq, NULL);
parse_proc_interrupts();
parse_proc_stat();
while (1) {
sleep_approx(SLEEP_INTERVAL);
if (debug_mode)
printf("\n\n\n-----------------------------------------------------------------------------\n");
clear_work_stats();
parse_proc_interrupts();
parse_proc_stat();
......@@ -242,6 +246,12 @@ int main(int argc, char** argv)
free_object_tree();
build_object_tree();
for_each_irq(NULL, force_rebalance_irq, NULL);
parse_proc_interrupts();
parse_proc_stat();
sleep_approx(SLEEP_INTERVAL);
clear_work_stats();
parse_proc_interrupts();
parse_proc_stat();
cycle_count=0;
}
......@@ -255,7 +265,6 @@ int main(int argc, char** argv)
dump_tree();
if (one_shot_mode)
break;
clear_work_stats();
cycle_count++;
}
......
......@@ -130,8 +130,10 @@ void add_package_to_node(struct topo_obj *p, int nodeid)
node = entry->data;
node->children = g_list_append(node->children, p);
p->parent = node;
if (!p->parent) {
node->children = g_list_append(node->children, p);
p->parent = node;
}
}
void dump_numa_node_info(struct topo_obj *d, void *unused __attribute__((unused)))
......
......@@ -154,24 +154,19 @@ static uint64_t get_parent_branch_irq_count_share(struct topo_obj *d)
static void compute_irq_branch_load_share(struct topo_obj *d, void *data __attribute__((unused)))
{
uint64_t total_irq_counts = 0;
uint64_t local_irq_counts = 0;
uint64_t load_slice;
total_irq_counts = get_parent_branch_irq_count_share(d);
load_slice = local_irq_counts ? (d->load / local_irq_counts) : 1;
if (g_list_length(d->interrupts) > 0) {
for_each_irq(d->interrupts, accumulate_irq_count, &local_irq_counts);
local_irq_counts = get_parent_branch_irq_count_share(d);
load_slice = local_irq_counts ? (d->load / local_irq_counts) : 1;
for_each_irq(d->interrupts, assign_load_slice, &load_slice);
}
if (d->parent) {
load_slice = total_irq_counts ? (d->load / total_irq_counts) : 1;
d->parent->load += (total_irq_counts - local_irq_counts) * load_slice;
}
if (d->parent)
d->parent->load += d->load;
}
void parse_proc_stat()
......@@ -222,7 +217,9 @@ void parse_proc_stat()
* For each cpu add the irq and softirq load and propagate that
* all the way up the device tree
*/
cpu->load = irq_load + softirq_load;
if (cycle_count)
cpu->load = (irq_load + softirq_load) - (cpu->last_load);
cpu->last_load = (irq_load + softirq_load);
}
fclose(file);
......
......@@ -35,6 +35,7 @@ enum obj_type_e {
struct topo_obj {
uint64_t load;
uint64_t last_load;
enum obj_type_e obj_type;
int number;
int powersave_mode;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment