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

Reply via email to