}
}
+static struct ovs_numa_dump *
+ovs_numa_dump_create(void)
+{
+ struct ovs_numa_dump *dump = xmalloc(sizeof *dump);
+
+ hmap_init(&dump->cores);
+ hmap_init(&dump->numas);
+
+ return dump;
+}
+
+static void
+ovs_numa_dump_add(struct ovs_numa_dump *dump, int numa_id, int core_id)
+{
+ struct ovs_numa_info_core *c = xzalloc(sizeof *c);
+ struct ovs_numa_info_numa *n;
+
+ c->numa_id = numa_id;
+ c->core_id = core_id;
+ hmap_insert(&dump->cores, &c->hmap_node, hash_2words(numa_id, core_id));
+
+ HMAP_FOR_EACH_WITH_HASH (n, hmap_node, hash_int(numa_id, 0),
+ &dump->numas) {
+ if (n->numa_id == numa_id) {
+ n->n_cores++;
+ return;
+ }
+ }
+
+ n = xzalloc(sizeof *n);
+ n->numa_id = numa_id;
+ n->n_cores = 1;
+ hmap_insert(&dump->numas, &n->hmap_node, hash_int(numa_id, 0));
+}
+
/* Given the 'numa_id', returns dump of all cores on the numa node. */
struct ovs_numa_dump *
ovs_numa_dump_cores_on_numa(int numa_id)
{
- struct ovs_numa_dump *dump = xmalloc(sizeof *dump);
+ struct ovs_numa_dump *dump = ovs_numa_dump_create();
struct numa_node *numa = get_numa_by_numa_id(numa_id);
- hmap_init(&dump->dump);
-
if (numa) {
struct cpu_core *core;
- LIST_FOR_EACH(core, list_node, &numa->cores) {
- struct ovs_numa_info *info = xmalloc(sizeof *info);
-
- info->numa_id = numa->numa_id;
- info->core_id = core->core_id;
- hmap_insert(&dump->dump, &info->hmap_node,
- hash_2words(info->numa_id, info->core_id));
+ LIST_FOR_EACH (core, list_node, &numa->cores) {
+ ovs_numa_dump_add(dump, numa->numa_id, core->core_id);
}
}
struct ovs_numa_dump *
ovs_numa_dump_cores_with_cmask(const char *cmask)
{
- struct ovs_numa_dump *dump = xmalloc(sizeof *dump);
+ struct ovs_numa_dump *dump = ovs_numa_dump_create();
int core_id = 0;
int end_idx;
- hmap_init(&dump->dump);
-
/* Ignore leading 0x. */
end_idx = 0;
if (!strncmp(cmask, "0x", 2) || !strncmp(cmask, "0X", 2)) {
struct cpu_core *core = get_core_by_core_id(core_id);
if (core) {
- struct ovs_numa_info *info = xmalloc(sizeof *info);
-
- info->numa_id = core->numa->numa_id;
- info->core_id = core->core_id;
- hmap_insert(&dump->dump, &info->hmap_node,
- hash_2words(info->numa_id, info->core_id));
+ ovs_numa_dump_add(dump,
+ core->numa->numa_id,
+ core->core_id);
}
}
struct ovs_numa_dump *
ovs_numa_dump_n_cores_per_numa(int cores_per_numa)
{
- struct ovs_numa_dump *dump = xmalloc(sizeof *dump);
+ struct ovs_numa_dump *dump = ovs_numa_dump_create();
const struct numa_node *n;
- hmap_init(&dump->dump);
-
HMAP_FOR_EACH (n, hmap_node, &all_numa_nodes) {
const struct cpu_core *core;
int i = 0;
break;
}
- struct ovs_numa_info *info = xmalloc(sizeof *info);
-
- info->numa_id = core->numa->numa_id;
- info->core_id = core->core_id;
- hmap_insert(&dump->dump, &info->hmap_node,
- hash_2words(info->numa_id, info->core_id));
+ ovs_numa_dump_add(dump, core->numa->numa_id, core->core_id);
}
}
ovs_numa_dump_contains_core(const struct ovs_numa_dump *dump,
int numa_id, unsigned core_id)
{
- struct ovs_numa_info *core;
+ struct ovs_numa_info_core *core;
HMAP_FOR_EACH_WITH_HASH (core, hmap_node, hash_2words(numa_id, core_id),
- &dump->dump) {
+ &dump->cores) {
if (core->core_id == core_id && core->numa_id == numa_id) {
return true;
}
return false;
}
+size_t
+ovs_numa_dump_count(const struct ovs_numa_dump *dump)
+{
+ return hmap_count(&dump->cores);
+}
+
void
ovs_numa_dump_destroy(struct ovs_numa_dump *dump)
{
- struct ovs_numa_info *iter;
+ struct ovs_numa_info_core *c;
+ struct ovs_numa_info_numa *n;
if (!dump) {
return;
}
- HMAP_FOR_EACH_POP (iter, hmap_node, &dump->dump) {
- free(iter);
+ HMAP_FOR_EACH_POP (c, hmap_node, &dump->cores) {
+ free(c);
+ }
+
+ HMAP_FOR_EACH_POP (n, hmap_node, &dump->numas) {
+ free(n);
}
- hmap_destroy(&dump->dump);
+ hmap_destroy(&dump->cores);
+ hmap_destroy(&dump->numas);
free(dump);
}
/* Dump of a list of 'struct ovs_numa_info'. */
struct ovs_numa_dump {
- struct hmap dump;
+ struct hmap cores;
+ struct hmap numas;
};
/* A numa_id - core_id pair. */
-struct ovs_numa_info {
+struct ovs_numa_info_core {
struct hmap_node hmap_node;
int numa_id;
unsigned core_id;
};
+/* A numa node. */
+struct ovs_numa_info_numa {
+ struct hmap_node hmap_node;
+ int numa_id;
+ size_t n_cores;
+};
+
void ovs_numa_init(void);
void ovs_numa_set_dummy(const char *dummy_config);
bool ovs_numa_numa_id_is_valid(int numa_id);
struct ovs_numa_dump *ovs_numa_dump_n_cores_per_numa(int n);
bool ovs_numa_dump_contains_core(const struct ovs_numa_dump *,
int numa_id, unsigned core_id);
+size_t ovs_numa_dump_count(const struct ovs_numa_dump *);
void ovs_numa_dump_destroy(struct ovs_numa_dump *);
int ovs_numa_thread_setaffinity_core(unsigned core_id);
#define FOR_EACH_CORE_ON_DUMP(ITER, DUMP) \
- HMAP_FOR_EACH((ITER), hmap_node, &(DUMP)->dump)
+ HMAP_FOR_EACH((ITER), hmap_node, &(DUMP)->cores)
+
+#define FOR_EACH_NUMA_ON_DUMP(ITER, DUMP) \
+ HMAP_FOR_EACH((ITER), hmap_node, &(DUMP)->numas)
#endif /* ovs-numa.h */