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.
This commit is contained in:
parent
5ebd1b24a9
commit
34ac21b1a7
|
@ -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)))
|
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_object(d->children, clear_obj_stats, NULL);
|
||||||
for_each_irq(d->interrupts, clear_irq_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
|
* which level does how much work and the actual lists of interrupts
|
||||||
* assigned to each component
|
* assigned to each component
|
||||||
*/
|
*/
|
||||||
void clear_work_stats(void)
|
void clear_work_stats()
|
||||||
{
|
{
|
||||||
for_each_object(numa_nodes, clear_obj_stats, NULL);
|
for_each_object(numa_nodes, clear_obj_stats, NULL);
|
||||||
}
|
}
|
||||||
|
|
11
irqbalance.c
11
irqbalance.c
|
@ -220,12 +220,16 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
for_each_irq(NULL, force_rebalance_irq, NULL);
|
for_each_irq(NULL, force_rebalance_irq, NULL);
|
||||||
|
|
||||||
|
parse_proc_interrupts();
|
||||||
|
parse_proc_stat();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
sleep_approx(SLEEP_INTERVAL);
|
sleep_approx(SLEEP_INTERVAL);
|
||||||
if (debug_mode)
|
if (debug_mode)
|
||||||
printf("\n\n\n-----------------------------------------------------------------------------\n");
|
printf("\n\n\n-----------------------------------------------------------------------------\n");
|
||||||
|
|
||||||
|
|
||||||
|
clear_work_stats();
|
||||||
parse_proc_interrupts();
|
parse_proc_interrupts();
|
||||||
parse_proc_stat();
|
parse_proc_stat();
|
||||||
|
|
||||||
|
@ -242,6 +246,12 @@ int main(int argc, char** argv)
|
||||||
free_object_tree();
|
free_object_tree();
|
||||||
build_object_tree();
|
build_object_tree();
|
||||||
for_each_irq(NULL, force_rebalance_irq, NULL);
|
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;
|
cycle_count=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,7 +265,6 @@ int main(int argc, char** argv)
|
||||||
dump_tree();
|
dump_tree();
|
||||||
if (one_shot_mode)
|
if (one_shot_mode)
|
||||||
break;
|
break;
|
||||||
clear_work_stats();
|
|
||||||
cycle_count++;
|
cycle_count++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
6
numa.c
6
numa.c
|
@ -130,8 +130,10 @@ void add_package_to_node(struct topo_obj *p, int nodeid)
|
||||||
|
|
||||||
node = entry->data;
|
node = entry->data;
|
||||||
|
|
||||||
node->children = g_list_append(node->children, p);
|
if (!p->parent) {
|
||||||
p->parent = node;
|
node->children = g_list_append(node->children, p);
|
||||||
|
p->parent = node;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_numa_node_info(struct topo_obj *d, void *unused __attribute__((unused)))
|
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)))
|
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 local_irq_counts = 0;
|
||||||
|
|
||||||
uint64_t load_slice;
|
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) {
|
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);
|
for_each_irq(d->interrupts, assign_load_slice, &load_slice);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->parent) {
|
if (d->parent)
|
||||||
load_slice = total_irq_counts ? (d->load / total_irq_counts) : 1;
|
d->parent->load += d->load;
|
||||||
d->parent->load += (total_irq_counts - local_irq_counts) * load_slice;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_proc_stat()
|
void parse_proc_stat()
|
||||||
|
@ -222,7 +217,9 @@ void parse_proc_stat()
|
||||||
* For each cpu add the irq and softirq load and propagate that
|
* For each cpu add the irq and softirq load and propagate that
|
||||||
* all the way up the device tree
|
* 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);
|
fclose(file);
|
||||||
|
|
Loading…
Reference in a new issue