Later patch will use this patch to configure the pmd thread
cpu affinity.
Signed-off-by: Alex Wang <[email protected]>
---
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
[email protected]
http://openvswitch.org/mailman/listinfo/dev