From 42db85f3441e3cfb774b49f0ac87b41d43834f2b Mon Sep 17 00:00:00 2001 From: Ilya Maximets Date: Tue, 13 Aug 2019 14:15:05 +0300 Subject: [PATCH] ovs-numa: Add dump based thread affinity functions. New functions to get and set CPU affinity using CPU dumps. This will abstract OS specific implementation details from the cross-platform code. Signed-off-by: Ilya Maximets Reviewed-by: David Marchand --- lib/ovs-numa.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++---- lib/ovs-numa.h | 2 ++ 2 files changed, 69 insertions(+), 5 deletions(-) diff --git a/lib/ovs-numa.c b/lib/ovs-numa.c index 24edeab2a..6d0a68522 100644 --- a/lib/ovs-numa.c +++ b/lib/ovs-numa.c @@ -532,22 +532,69 @@ ovs_numa_dump_destroy(struct ovs_numa_dump *dump) free(dump); } -int ovs_numa_thread_setaffinity_core(unsigned core_id OVS_UNUSED) +struct ovs_numa_dump * +ovs_numa_thread_getaffinity_dump(void) { if (dummy_numa) { - /* Nothing to do */ + /* Nothing to do. */ + return NULL; + } + +#ifndef __linux__ + return NULL; +#else + struct ovs_numa_dump *dump; + const struct numa_node *n; + cpu_set_t cpuset; + int err; + + CPU_ZERO(&cpuset); + err = pthread_getaffinity_np(pthread_self(), sizeof cpuset, &cpuset); + if (err) { + VLOG_ERR("Thread getaffinity error: %s", ovs_strerror(err)); + return NULL; + } + + dump = ovs_numa_dump_create(); + + HMAP_FOR_EACH (n, hmap_node, &all_numa_nodes) { + const struct cpu_core *core; + + LIST_FOR_EACH (core, list_node, &n->cores) { + if (CPU_ISSET(core->core_id, &cpuset)) { + ovs_numa_dump_add(dump, core->numa->numa_id, core->core_id); + } + } + } + + if (!ovs_numa_dump_count(dump)) { + ovs_numa_dump_destroy(dump); + return NULL; + } + return dump; +#endif /* __linux__ */ +} + +int +ovs_numa_thread_setaffinity_dump(const struct ovs_numa_dump *dump) +{ + if (!dump || dummy_numa) { + /* Nothing to do. */ return 0; } #ifdef __linux__ + const struct ovs_numa_info_core *core; cpu_set_t cpuset; int err; CPU_ZERO(&cpuset); - CPU_SET(core_id, &cpuset); - err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + FOR_EACH_CORE_ON_DUMP (core, dump) { + CPU_SET(core->core_id, &cpuset); + } + err = pthread_setaffinity_np(pthread_self(), sizeof cpuset, &cpuset); if (err) { - VLOG_ERR("Thread affinity error %d",err); + VLOG_ERR("Thread setaffinity error: %s", ovs_strerror(err)); return err; } @@ -556,3 +603,18 @@ int ovs_numa_thread_setaffinity_core(unsigned core_id OVS_UNUSED) return EOPNOTSUPP; #endif /* __linux__ */ } + +int ovs_numa_thread_setaffinity_core(unsigned core_id) +{ + const struct cpu_core *core = get_core_by_core_id(core_id); + struct ovs_numa_dump *affinity = ovs_numa_dump_create(); + int ret = EINVAL; + + if (core) { + ovs_numa_dump_add(affinity, core->numa->numa_id, core->core_id); + ret = ovs_numa_thread_setaffinity_dump(affinity); + } + + ovs_numa_dump_destroy(affinity); + return ret; +} diff --git a/lib/ovs-numa.h b/lib/ovs-numa.h index 088fcb8c3..8f2ea3430 100644 --- a/lib/ovs-numa.h +++ b/lib/ovs-numa.h @@ -60,6 +60,8 @@ 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 *); +struct ovs_numa_dump * ovs_numa_thread_getaffinity_dump(void); +int ovs_numa_thread_setaffinity_dump(const struct ovs_numa_dump *); void ovs_numa_dump_destroy(struct ovs_numa_dump *); int ovs_numa_thread_setaffinity_core(unsigned core_id); -- 2.39.5