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:
Neil Horman 2011-10-11 14:19:21 -04:00
parent 5ebd1b24a9
commit 34ac21b1a7
5 changed files with 23 additions and 15 deletions

View file

@ -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);
} }

View file

@ -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
View file

@ -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)))

View file

@ -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);

View file

@ -35,6 +35,7 @@ enum obj_type_e {
struct topo_obj { struct topo_obj {
uint64_t load; uint64_t load;
uint64_t last_load;
enum obj_type_e obj_type; enum obj_type_e obj_type;
int number; int number;
int powersave_mode; int powersave_mode;