@@ -512,6 +512,83 @@ ovs_numa_dump_cores_on_numa(int numa_id)
return dump;
}
+struct ovs_numa_dump *
+ovs_numa_dump_cores_with_cmask(const char *cmask)
+{
+ struct ovs_numa_dump *dump = xmalloc(sizeof *dump);
+ 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)) {
+ end_idx = 2;
+ }
+
+ for (int i = strlen(cmask) - 1; i >= end_idx; i--) {
+ char hex = toupper((unsigned char) cmask[i]);
+ int bin, j;
+
+ if (hex >= '0' && hex <= '9') {
+ bin = hex - '0';
+ } else if (hex >= 'A' && hex <= 'F') {
+ bin = hex - 'A' + 10;
+ } else {
+ VLOG_WARN("Invalid cpu mask: %c", cmask[i]);
+ bin = 0;
+ }
+
+ for (j = 0; j < 4; j++) {
+ if ((bin >> j) & 0x1) {
+ 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));
+ }
+ }
+
+ core_id++;
+ }
+ }
+
+ return dump;
+}
+
+struct ovs_numa_dump *
+ovs_numa_dump_n_cores_per_numa(int cores_per_numa)
+{
+ struct ovs_numa_dump *dump = xmalloc(sizeof *dump);
+ 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;
+
+ LIST_FOR_EACH(core, list_node, &n->cores) {
+ if (i++ >= cores_per_numa) {
+ 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));
+ }
+ }
+
+ return dump;
+}
bool
ovs_numa_dump_contains_core(const struct ovs_numa_dump *dump,
@@ -54,12 +54,14 @@ unsigned ovs_numa_get_unpinned_core_any(void);
unsigned ovs_numa_get_unpinned_core_on_numa(int numa_id);
void ovs_numa_unpin_core(unsigned core_id);
struct ovs_numa_dump *ovs_numa_dump_cores_on_numa(int numa_id);
+struct ovs_numa_dump *ovs_numa_dump_cores_with_cmask(const char *cmask);
+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);
void ovs_numa_dump_destroy(struct ovs_numa_dump *);
int ovs_numa_thread_setaffinity_core(unsigned core_id);
-#define FOR_EACH_CORE_ON_NUMA(ITER, DUMP) \
+#define FOR_EACH_CORE_ON_DUMP(ITER, DUMP) \
HMAP_FOR_EACH((ITER), hmap_node, &(DUMP)->dump)
#endif /* ovs-numa.h */
They will be used by a future commit. This patch introduces some code duplication which will be removed in a future commit. Signed-off-by: Daniele Di Proietto <diproiettod@vmware.com> --- lib/ovs-numa.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/ovs-numa.h | 4 ++- 2 files changed, 80 insertions(+), 1 deletion(-)