[ovs-dev] [PATCH v2 07/11] dpif-netdev: Change pmd thread configuration in dpif_netdev_run().

Daniele Di Proietto diproiettod at vmware.com
Thu Mar 3 01:33:18 UTC 2016


Signed-off-by: Daniele Di Proietto <diproiettod at vmware.com>
---
 lib/dpif-netdev.c   | 140 ++++++++++++++++++++++++++++++----------------------
 lib/dpif-provider.h |   3 +-
 2 files changed, 83 insertions(+), 60 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index cbd8d56..6850cfa 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -223,7 +223,9 @@ struct dp_netdev {
     ovsthread_key_t per_pmd_key;
 
     /* Cpu mask for pin of pmd threads. */
+    char *requested_pmd_cmask;
     char *pmd_cmask;
+
     uint64_t last_tnl_conf_seq;
 };
 
@@ -2447,82 +2449,44 @@ dpif_netdev_operate(struct dpif *dpif, struct dpif_op **ops, size_t n_ops)
     }
 }
 
-/* Returns true if the configuration for rx queues or cpu mask
- * is changed. */
+/* Returns true if the configuration for rx queues is changed. */
 static bool
-pmd_config_changed(const struct dp_netdev *dp, const char *cmask)
+pmd_n_rxq_changed(const struct dp_netdev *dp)
 {
     struct dp_netdev_port *port;
 
     CMAP_FOR_EACH (port, node, &dp->ports) {
-        struct netdev *netdev = port->netdev;
-        int requested_n_rxq = netdev_requested_n_rxq(netdev);
-        if (netdev_is_pmd(netdev)
+        int requested_n_rxq = netdev_requested_n_rxq(port->netdev);
+
+        if (netdev_is_pmd(port->netdev)
             && port->latest_requested_n_rxq != requested_n_rxq) {
             return true;
         }
     }
 
-    if (dp->pmd_cmask != NULL && cmask != NULL) {
-        return strcmp(dp->pmd_cmask, cmask);
-    } else {
-        return (dp->pmd_cmask != NULL || cmask != NULL);
+    return false;
+}
+
+static bool
+cmask_equals(const char *a, const char *b)
+{
+    if (a && b) {
+        return !strcmp(a, b);
     }
+
+    return a == NULL && b == NULL;
 }
 
-/* Resets pmd threads if the configuration for 'rxq's or cpu mask changes. */
+/* Changes the number or the affinity of pmd threads.  The changes are actually
+ * applied in dpif_netdev_run(). */
 static int
 dpif_netdev_pmd_set(struct dpif *dpif, const char *cmask)
 {
     struct dp_netdev *dp = get_dp_netdev(dpif);
 
-    if (pmd_config_changed(dp, cmask)) {
-        struct dp_netdev_port *port;
-
-        dp_netdev_destroy_all_pmds(dp);
-
-        CMAP_FOR_EACH (port, node, &dp->ports) {
-            struct netdev *netdev = port->netdev;
-            int requested_n_rxq = netdev_requested_n_rxq(netdev);
-            if (netdev_is_pmd(port->netdev)
-                && port->latest_requested_n_rxq != requested_n_rxq) {
-                int i, err;
-
-                /* Closes the existing 'rxq's. */
-                for (i = 0; i < netdev_n_rxq(port->netdev); i++) {
-                    netdev_rxq_close(port->rxq[i]);
-                    port->rxq[i] = NULL;
-                }
-                port->n_rxq = 0;
-
-                /* Sets the new rx queue config.  */
-                err = netdev_set_multiq(port->netdev,
-                                        ovs_numa_get_n_cores() + 1,
-                                        requested_n_rxq);
-                if (err && (err != EOPNOTSUPP)) {
-                    VLOG_ERR("Failed to set dpdk interface %s rx_queue to:"
-                             " %u", netdev_get_name(port->netdev),
-                             requested_n_rxq);
-                    return err;
-                }
-                port->latest_requested_n_rxq = requested_n_rxq;
-                /* If the set_multiq() above succeeds, reopens the 'rxq's. */
-                port->n_rxq = netdev_n_rxq(port->netdev);
-                port->rxq = xrealloc(port->rxq, sizeof *port->rxq * port->n_rxq);
-                for (i = 0; i < port->n_rxq; i++) {
-                    netdev_rxq_open(port->netdev, &port->rxq[i], i);
-                }
-            }
-        }
-        /* Reconfigures the cpu mask. */
-        ovs_numa_set_cpu_mask(cmask);
-        free(dp->pmd_cmask);
-        dp->pmd_cmask = cmask ? xstrdup(cmask) : NULL;
-
-        /* Restores the non-pmd. */
-        dp_netdev_set_nonpmd(dp);
-        /* Restores all pmd threads. */
-        dp_netdev_reset_pmd_threads(dp);
+    if (!cmask_equals(dp->requested_pmd_cmask, cmask)) {
+        free(dp->requested_pmd_cmask);
+        dp->requested_pmd_cmask = cmask ? xstrdup(cmask) : NULL;
     }
 
     return 0;
@@ -2622,6 +2586,58 @@ dp_netdev_process_rxq_port(struct dp_netdev_pmd_thread *pmd,
     }
 }
 
+static void
+reconfigure_pmd_threads(struct dp_netdev *dp)
+{
+    struct dp_netdev_port *port;
+
+    dp_netdev_destroy_all_pmds(dp);
+
+    CMAP_FOR_EACH (port, node, &dp->ports) {
+        struct netdev *netdev = port->netdev;
+        int requested_n_rxq = netdev_requested_n_rxq(netdev);
+        if (netdev_is_pmd(port->netdev)
+            && port->latest_requested_n_rxq != requested_n_rxq) {
+            int i, err;
+
+            /* Closes the existing 'rxq's. */
+            for (i = 0; i < port->n_rxq; i++) {
+                netdev_rxq_close(port->rxq[i]);
+                port->rxq[i] = NULL;
+            }
+            port->n_rxq = 0;
+
+            /* Sets the new rx queue config. */
+            err = netdev_set_multiq(port->netdev, ovs_numa_get_n_cores() + 1,
+                                    requested_n_rxq);
+            if (err && (err != EOPNOTSUPP)) {
+                VLOG_ERR("Failed to set dpdk interface %s rx_queue to: %u",
+                         netdev_get_name(port->netdev),
+                         requested_n_rxq);
+                return;
+            }
+            port->latest_requested_n_rxq = requested_n_rxq;
+            /* If the set_multiq() above succeeds, reopens the 'rxq's. */
+            port->n_rxq = netdev_n_rxq(port->netdev);
+            port->rxq = xrealloc(port->rxq, sizeof *port->rxq * port->n_rxq);
+            for (i = 0; i < port->n_rxq; i++) {
+                netdev_rxq_open(port->netdev, &port->rxq[i], i);
+            }
+        }
+    }
+    /* Reconfigures the cpu mask. */
+    ovs_numa_set_cpu_mask(dp->requested_pmd_cmask);
+    free(dp->pmd_cmask);
+    dp->pmd_cmask = dp->requested_pmd_cmask
+                    ? xstrdup(dp->requested_pmd_cmask)
+                    : NULL;
+
+    /* Restores the non-pmd. */
+    dp_netdev_set_nonpmd(dp);
+    /* Restores all pmd threads. */
+    dp_netdev_reset_pmd_threads(dp);
+}
+
 /* Return true if needs to revalidate datapath flows. */
 static bool
 dpif_netdev_run(struct dpif *dpif)
@@ -2642,8 +2658,14 @@ dpif_netdev_run(struct dpif *dpif)
             }
         }
     }
-    ovs_mutex_unlock(&dp->non_pmd_mutex);
+
     dp_netdev_pmd_unref(non_pmd);
+    ovs_mutex_unlock(&dp->non_pmd_mutex);
+
+    if (!cmask_equals(dp->pmd_cmask, dp->requested_pmd_cmask)
+        || pmd_n_rxq_changed(dp)) {
+        reconfigure_pmd_threads(dp);
+    }
 
     tnl_neigh_cache_run();
     tnl_port_map_run();
diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h
index fbd370f..25f4280 100644
--- a/lib/dpif-provider.h
+++ b/lib/dpif-provider.h
@@ -319,7 +319,8 @@ struct dpif_class {
 
     /* If 'dpif' creates its own I/O polling threads, refreshes poll threads
      * configuration.  'cmask' configures the cpu mask for setting the polling
-     * threads' cpu affinity. */
+     * threads' cpu affinity.  The implementation might postpone applying the
+     * changes until run() is called. */
     int (*poll_threads_set)(struct dpif *dpif, const char *cmask);
 
     /* Translates OpenFlow queue ID 'queue_id' (in host byte order) into a
-- 
2.1.4




More information about the dev mailing list