Later patch will use this patch to configure the pmd thread cpu affinity. Signed-off-by: Alex Wang <al...@nicira.com> --- lib/ovs-numa.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++-------- lib/ovs-numa.h | 7 +++++ 2 files changed, 82 insertions(+), 12 deletions(-)
diff --git a/lib/ovs-numa.c b/lib/ovs-numa.c index acedd30..ec8c81a 100644 --- a/lib/ovs-numa.c +++ b/lib/ovs-numa.c @@ -50,6 +50,7 @@ struct cpu_core { struct list list_node; /* In 'cpu_socket->cores' list. */ struct cpu_socket *socket; /* Socket containing the core. */ int core_id; /* Core id. */ + bool pinnable; /* If the core can be pinned. */ bool pinned; /* If a thread has been pinned to the core. */ }; @@ -110,6 +111,7 @@ discover_sockets_and_cores(void) hash_int(core_id, 0)); list_insert(&s->cores, &c->list_node); c->core_id = core_id; + c->pinnable = true; n_cpus++; } } @@ -185,7 +187,8 @@ ovs_numa_get_n_cores_on_socket(int socket_id) return OVS_CORE_UNSPEC; } -/* Returns the number of unpinned cpu cores on socket. */ +/* Returns the number of cpu cores on socket that are unpinned and + * pinnable. */ int ovs_numa_get_n_unpinned_cores_on_socket(int socket_id) { @@ -199,7 +202,7 @@ ovs_numa_get_n_unpinned_cores_on_socket(int socket_id) hash_int(socket_id, 0)), struct cpu_socket, hmap_node); LIST_FOR_EACH(core, list_node, &socket->cores) { - if (!core->pinned) { + if (core->pinnable && !core->pinned) { count++; } } @@ -211,7 +214,7 @@ ovs_numa_get_n_unpinned_cores_on_socket(int socket_id) } /* Given 'core_id', tries to pin that core. Returns true, if succeeds. - * False, if the core has already been pinned. */ + * False, if the core has already been pinned or is un-pinnable. */ bool ovs_numa_try_pin_core_specific(int core_id) { @@ -222,7 +225,7 @@ ovs_numa_try_pin_core_specific(int core_id) core = CONTAINER_OF(hmap_first_with_hash(&all_cpu_cores, hash_int(core_id, 0)), struct cpu_core, hmap_node); - if (!core->pinned) { + if (core->pinnable && !core->pinned) { core->pinned = true; return true; } @@ -230,15 +233,15 @@ ovs_numa_try_pin_core_specific(int core_id) return false; } -/* Searches through all cores for an unpinned core. Returns the core_id - * if found and set the 'core->pinned' to true. Otherwise, returns -1. */ +/* Searches through all cores for an unpinned and pinnable core. Returns + * the core_id if found. Otherwise, returns -1. */ int ovs_numa_get_unpinned_core_any(void) { struct cpu_core *core; HMAP_FOR_EACH(core, hmap_node, &all_cpu_cores) { - if (!core->pinned) { + if (core->pinnable && !core->pinned) { core->pinned = true; return core->core_id; } @@ -247,9 +250,8 @@ ovs_numa_get_unpinned_core_any(void) return OVS_CORE_UNSPEC; } -/* Searches through all cores on socket with 'socket_id' for an unpinned core. - * Returns the core_id if found and sets the 'core->pinned' to true. - * Otherwise, returns -1. */ +/* Searches through all cores on socket with 'socket_id' for an unpinned and + * pinnable core. Returns the core_id if found. Otherwise, returns -1. */ int ovs_numa_get_unpinned_core_on_socket(int socket_id) { @@ -262,7 +264,7 @@ ovs_numa_get_unpinned_core_on_socket(int socket_id) hash_int(socket_id, 0)), struct cpu_socket, hmap_node); LIST_FOR_EACH(core, list_node, &socket->cores) { - if (!core->pinned) { + if (core->pinnable && !core->pinned) { core->pinned = true; return core->core_id; } @@ -271,7 +273,7 @@ ovs_numa_get_unpinned_core_on_socket(int socket_id) return OVS_CORE_UNSPEC; } -/* Resets the 'core->pinned' for the core with 'core_id'. */ +/* Unpins the core with 'core_id'. */ void ovs_numa_unpin_core(int core_id) { @@ -285,4 +287,65 @@ ovs_numa_unpin_core(int core_id) core->pinned = false; } +/* Reads the cpu mask configuration from 'cmask' and sets the + * 'pinnable' of corresponding cores. For unspecified cores, + * sets 'pinnable' to true. */ +void +ovs_numa_set_cpu_mask(const char *cmask) +{ + int core_id = 0; + int i; + + if (!found_sockets_and_cores) { + return; + } + + /* If no mask specified, resets the pinnable to true for all cores. */ + if (!cmask) { + struct cpu_core *core; + + HMAP_FOR_EACH(core, hmap_node, &all_cpu_cores) { + core->pinnable = true; + } + + return; + } + + for (i = 0; i < strlen(cmask); i--) { + char hex = cmask[i]; + int bin, j; + + if (hex >= '0' && hex <= '9') { + bin = hex - '0'; + } else if (hex >= 'A' && hex <= 'F') { + bin = hex - 'A' + 10; + } else { + bin = 0; + } + + for (j = 3; j >= 0; j--) { + struct cpu_core *core; + + core = CONTAINER_OF(hmap_first_with_hash(&all_cpu_cores, + hash_int(core_id++, 0)), + struct cpu_core, hmap_node); + core->pinnable = (bin >> j) & 0x1; + } + + if (core_id >= hmap_count(&all_cpu_cores)) { + return; + } + } + + /* For unspecified cores, sets 'pinnable' to false. */ + while (core_id < hmap_count(&all_cpu_cores)) { + struct cpu_core *core; + + core = CONTAINER_OF(hmap_first_with_hash(&all_cpu_cores, + hash_int(core_id++, 0)), + struct cpu_core, hmap_node); + core->pinnable = false; + } +} + #endif /* __linux__ */ diff --git a/lib/ovs-numa.h b/lib/ovs-numa.h index 95884c5..939878b 100644 --- a/lib/ovs-numa.h +++ b/lib/ovs-numa.h @@ -30,6 +30,7 @@ void ovs_numa_init(void); bool ovs_numa_cpu_socket_id_is_valid(int sid); bool ovs_numa_cpu_core_id_is_valid(int cid); +void ovs_numa_set_cpu_mask(const char *cmask); int ovs_numa_get_n_sockets(void); int ovs_numa_get_n_cores(void); int ovs_numa_get_n_cores_on_socket(int socket_id); @@ -59,6 +60,12 @@ ovs_numa_cpu_core_id_is_valid(int cid OVS_UNUSED) return false; } +static inline void +ovs_numa_set_cpu_mask(const char *cmask OVS_UNUSED) +{ + /* Nothing */ +} + static inline int ovs_numa_get_n_sockets(void) { -- 1.7.9.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev