Commit decce934 authored by Neil Horman's avatar Neil Horman

Merge all topology objects to a common structure

Theres no need to treat topology objects differently.  We can merge them all
down to a common structure.  This will make balancing code a great deal more
concise.
parent c10d9540
This diff is collapsed.
......@@ -59,30 +59,30 @@ extern void build_numa_node_list(void);
extern void free_numa_node_list(void);
extern void dump_numa_node_info(struct common_obj_data *node, void *data);
extern void for_each_numa_node(GList *list, void (*cb)(struct common_obj_data *node, void *data), void *data);
extern void add_package_to_node(struct package *p, int nodeid);
extern struct numa_node *get_numa_node(int nodeid);
extern void add_package_to_node(struct common_obj_data *p, int nodeid);
extern struct common_obj_data *get_numa_node(int nodeid);
/*
* Package functions
*/
#define package_numa_node(p) ((p)->numa_node)
#define package_numa_node(p) ((p)->parent)
extern void for_each_package(GList *list, void (*cb)(struct common_obj_data *p, void *data), void *data);
/*
* cache_domain functions
*/
#define cache_domain_package(c) ((c)->package)
#define cache_domain_package(c) ((c)->parent)
#define cache_domain_numa_node(c) (package_numa_node(cache_domain_package((c))))
extern void for_each_cache_domain(GList *list, void (*cb)(struct common_obj_data *c, void *data), void *data);
/*
* cpu core functions
*/
#define cpu_cache_domain(cpu) ((cpu)->cache_domain)
#define cpu_cache_domain(cpu) ((cpu)->parent)
#define cpu_package(cpu) (cache_domain_package(cpu_cache_domain((cpu))))
#define cpu_numa_node(cpu) (package_numa_node(cache_domain_package(cpu_cache_domain((cpu)))))
extern void for_each_cpu_core(GList *list, void (*cb)(struct common_obj_data *c, void *data), void *data);
extern struct cpu_core *find_cpu_core(int cpunr);
extern struct common_obj_data *find_cpu_core(int cpunr);
extern int get_cpu_count(void);
/*
......
......@@ -165,7 +165,7 @@ void reset_counts(void)
static void dump_workload(struct irq_info *info, void *unused __attribute__((unused)))
{
printf("Interrupt %i node_num %d (class %s) has workload %lu \n", info->irq, irq_numa_node(info)->common.number, classes[info->class], (unsigned long)info->load);
printf("Interrupt %i node_num %d (class %s) has workload %lu \n", info->irq, irq_numa_node(info)->number, classes[info->class], (unsigned long)info->load);
}
void dump_workloads(void)
......
......@@ -37,43 +37,42 @@
GList *numa_nodes = NULL;
struct numa_node unspecified_node = {
.common = {
.load = 0,
.number = -1,
.mask = CPU_MASK_ALL,
.interrupts = NULL,
},
.packages = NULL,
struct common_obj_data unspecified_node = {
.load = 0,
.number = -1,
.mask = CPU_MASK_ALL,
.interrupts = NULL,
.children = NULL,
.parent = NULL,
};
static void add_one_node(const char *nodename)
{
char *path = alloca(strlen(SYSFS_NODE_PATH) + strlen(nodename) + 1);
struct numa_node *new;
struct common_obj_data *new;
char *cpustr;
FILE *f;
if (!path)
return;
new = calloc(1, sizeof(struct numa_node));
new = calloc(1, sizeof(struct common_obj_data));
if (!new)
return;
sprintf(path, "%s/%s/cpumap", SYSFS_NODE_PATH, nodename);
f = fopen(path, "r");
if (ferror(f)) {
cpus_clear(new->common.mask);
cpus_clear(new->mask);
} else {
fscanf(f, "%as", &cpustr);
if (!cpustr) {
cpus_clear(new->common.mask);
cpus_clear(new->mask);
} else {
cpumask_parse_user(cpustr, strlen(cpustr), new->common.mask);
cpumask_parse_user(cpustr, strlen(cpustr), new->mask);
free(cpustr);
}
}
new->common.number = strtoul(&nodename[4], NULL, 10);
new->number = strtoul(&nodename[4], NULL, 10);
numa_nodes = g_list_append(numa_nodes, new);
}
......@@ -105,19 +104,19 @@ void free_numa_node_list(void)
static gint compare_node(gconstpointer a, gconstpointer b)
{
const struct numa_node *ai = a;
const struct numa_node *bi = b;
const struct common_obj_data *ai = a;
const struct common_obj_data *bi = b;
return (ai->common.number == bi->common.number) ? 0 : 1;
return (ai->number == bi->number) ? 0 : 1;
}
void add_package_to_node(struct package *p, int nodeid)
void add_package_to_node(struct common_obj_data *p, int nodeid)
{
struct numa_node find, *node;
find.common.number = nodeid;
struct common_obj_data find, *node;
find.number = nodeid;
GList *entry;
find.common.number = nodeid;
find.number = nodeid;
entry = g_list_find_custom(numa_nodes, &find, compare_node);
if (!entry) {
......@@ -128,17 +127,16 @@ void add_package_to_node(struct package *p, int nodeid)
node = entry->data;
node->packages = g_list_append(node->packages, p);
p->numa_node = node;
node->children = g_list_append(node->children, p);
p->parent = node;
}
void dump_numa_node_info(struct common_obj_data *d, void *unused __attribute__((unused)))
{
struct numa_node *node = (struct numa_node *)d;
char buffer[4096];
printf("NUMA NODE NUMBER: %d\n", node->common.number);
cpumask_scnprintf(buffer, 4096, node->common.mask);
printf("NUMA NODE NUMBER: %d\n", d->number);
cpumask_scnprintf(buffer, 4096, d->mask);
printf("LOCAL CPU MASK: %s\n", buffer);
printf("\n");
}
......@@ -156,15 +154,15 @@ void for_each_numa_node(GList *list, void(*cb)(struct common_obj_data *node, voi
}
}
struct numa_node *get_numa_node(int nodeid)
struct common_obj_data *get_numa_node(int nodeid)
{
struct numa_node find;
struct common_obj_data find;
GList *entry;
if (nodeid == -1)
return &unspecified_node;
find.common.number = nodeid;
find.number = nodeid;
entry = g_list_find_custom(numa_nodes, &find, compare_node);
return entry ? entry->data : NULL;
......
......@@ -73,7 +73,7 @@ static void find_best_object(struct common_obj_data *d, void *data)
static void place_irq_in_cache_domain(struct irq_info *info, void *data)
{
struct package *p = data;
struct common_obj_data *p = data;
struct obj_placement place;
struct common_obj_data *asign;
......@@ -89,12 +89,12 @@ static void place_irq_in_cache_domain(struct irq_info *info, void *data)
place.least_irqs = NULL;
place.best_cost = INT_MAX;
for_each_cache_domain(p->cache_domains, find_best_object, &place);
for_each_cache_domain(p->children, find_best_object, &place);
asign = place.least_irqs ? place.least_irqs : place.best;
if (asign) {
migrate_irq(&p->common.interrupts, &asign->interrupts, info);
migrate_irq(&p->interrupts, &asign->interrupts, info);
info->assigned_obj = asign;
}
......@@ -102,14 +102,13 @@ static void place_irq_in_cache_domain(struct irq_info *info, void *data)
static void place_cache_domain(struct common_obj_data *d, void *data __attribute__((unused)))
{
struct package *package = (struct package *)d;
if (package->common.interrupts)
for_each_irq(package->common.interrupts, place_irq_in_cache_domain, package);
if (d->interrupts)
for_each_irq(d->interrupts, place_irq_in_cache_domain, d);
}
static void place_core(struct irq_info *info, void *data)
{
struct cache_domain *c = data;
struct common_obj_data *c = data;
struct obj_placement place;
struct common_obj_data *asign;
......@@ -125,12 +124,12 @@ static void place_core(struct irq_info *info, void *data)
place.least_irqs = NULL;
place.best_cost = INT_MAX;
for_each_cpu_core(c->cpu_cores, find_best_object, &place);
for_each_cpu_core(c->children, find_best_object, &place);
asign = place.least_irqs ? place.least_irqs : place.best;
if (asign) {
migrate_irq(&c->common.interrupts, &asign->interrupts, info);
migrate_irq(&c->interrupts, &asign->interrupts, info);
info->assigned_obj = asign;
asign->load += info->load;
}
......@@ -139,15 +138,14 @@ static void place_core(struct irq_info *info, void *data)
static void place_cores(struct common_obj_data *d, void *data __attribute__((unused)))
{
struct cache_domain *cache_domain = (struct cache_domain *)d;
if (cache_domain->common.interrupts)
for_each_irq(cache_domain->common.interrupts, place_core, cache_domain);
if (d->interrupts)
for_each_irq(d->interrupts, place_core, d);
}
static void place_irq_in_package(struct irq_info *info, void *data)
{
struct obj_placement place;
struct numa_node *n = data;
struct common_obj_data *n = data;
struct common_obj_data *asign;
if (!info->moved)
......@@ -161,12 +159,12 @@ static void place_irq_in_package(struct irq_info *info, void *data)
place.least_irqs = NULL;
place.best_cost = INT_MAX;
for_each_package(n->packages, find_best_object, &place);
for_each_package(n->children, find_best_object, &place);
asign = place.least_irqs ? place.least_irqs : place.best;
if (asign) {
migrate_irq(&n->common.interrupts, &asign->interrupts, info);
migrate_irq(&n->interrupts, &asign->interrupts, info);
info->assigned_obj = asign;
asign->load += info->load;
}
......@@ -174,9 +172,8 @@ static void place_irq_in_package(struct irq_info *info, void *data)
static void place_packages(struct common_obj_data *d, void *data __attribute__((unused)))
{
struct numa_node *n = (struct numa_node *)d;
if (n->common.interrupts)
for_each_irq(n->common.interrupts, place_irq_in_package, n);
if (d->interrupts)
for_each_irq(d->interrupts, place_irq_in_package, d);
}
static void place_irq_in_node(struct irq_info *info, void *data __attribute__((unused)))
......@@ -187,14 +184,14 @@ static void place_irq_in_node(struct irq_info *info, void *data __attribute__((u
if( info->level == BALANCE_NONE)
return;
if (irq_numa_node(info)->common.number != -1) {
if (irq_numa_node(info)->number != -1) {
/*
* This irq belongs to a device with a preferred numa node
* put it on that node
*/
migrate_irq(&rebalance_irq_list, &irq_numa_node(info)->common.interrupts, info);
migrate_irq(&rebalance_irq_list, &irq_numa_node(info)->interrupts, info);
info->assigned_obj = (struct common_obj_data *)irq_numa_node(info);
irq_numa_node(info)->common.load += info->load + 1;
irq_numa_node(info)->load += info->load + 1;
return;
}
......
......@@ -130,15 +130,14 @@ static void assign_load_slice(struct irq_info *info, void *data)
static void compute_irq_load_share(struct common_obj_data *d, void *data __attribute__((unused)))
{
struct cpu_core *cpu = (struct cpu_core *)d;
uint64_t total_irq_counts = 0;
uint64_t load_slice;
for_each_irq(cpu->common.interrupts, accumulate_irq_count, &total_irq_counts);
for_each_irq(d->interrupts, accumulate_irq_count, &total_irq_counts);
load_slice = total_irq_counts ? (cpu->common.load / total_irq_counts) : 1;
load_slice = total_irq_counts ? (d->load / total_irq_counts) : 1;
for_each_irq(cpu->common.interrupts, assign_load_slice, &load_slice);
for_each_irq(d->interrupts, assign_load_slice, &load_slice);
}
void parse_proc_stat()
......@@ -147,7 +146,7 @@ void parse_proc_stat()
char *line = NULL;
size_t size = 0;
int cpunr, rc, cpucount;
struct cpu_core *cpu;
struct common_obj_data *cpu;
int irq_load, softirq_load;
file = fopen("/proc/stat", "r");
......@@ -189,12 +188,10 @@ void parse_proc_stat()
* For each cpu add the irq and softirq load and propagate that
* all the way up the device tree
*/
cpu->irq_load = irq_load;
cpu->softirq_load = softirq_load;
cpu->common.load = irq_load + softirq_load;
cpu->cache_domain->common.load += cpu->common.load;
cpu->cache_domain->package->common.load += cpu->common.load;
cpu->cache_domain->package->numa_node->common.load += cpu->common.load;
cpu->load = irq_load + softirq_load;
cpu_cache_domain(cpu)->load += cpu->load;
cpu_package(cpu)->load += cpu->load;
cpu_numa_node(cpu)->load += cpu->load;
}
fclose(file);
......
......@@ -31,31 +31,8 @@ struct common_obj_data {
int number;
cpumask_t mask;
GList *interrupts;
};
struct numa_node {
struct common_obj_data common;
GList *packages;
};
struct package {
struct common_obj_data common;
struct numa_node *numa_node;
GList *cache_domains;
};
struct cache_domain {
struct common_obj_data common;
struct package *package;
GList *cpu_cores;
};
struct cpu_core {
struct common_obj_data common;
struct cache_domain *cache_domain;
uint64_t irq_load;
uint64_t softirq_load;
struct common_obj_data *parent;
GList *children;
};
struct irq_info {
......@@ -63,7 +40,7 @@ struct irq_info {
int class;
int type;
int level;
struct numa_node *numa_node;
struct common_obj_data *numa_node;
cpumask_t cpumask;
cpumask_t affinity_hint;
uint64_t irq_count;
......
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