diff mbox

[ovs-dev,03/10] dpctl: Implement dpctl/flow-get for dpif-netdev.

Message ID 1457968700-23125-4-git-send-email-i.maximets@samsung.com
State Superseded
Headers show

Commit Message

Ilya Maximets March 14, 2016, 3:18 p.m. UTC
Currently 'dpctl/flow-get' doesn't work for flows installed by
PMD threads.

Fix that by implementing search across all PMD threads. Will be returned
flow from first PMD thread with match.

Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
---
 lib/dpctl.c       |  3 +--
 lib/dpif-netdev.c | 49 +++++++++++++++++++++++++++++++++++--------------
 2 files changed, 36 insertions(+), 16 deletions(-)
diff mbox

Patch

diff --git a/lib/dpctl.c b/lib/dpctl.c
index d58df0d..b031a66 100644
--- a/lib/dpctl.c
+++ b/lib/dpctl.c
@@ -1055,8 +1055,7 @@  dpctl_get_flow(int argc, const char *argv[], struct dpctl_params *dpctl_p)
         goto out;
     }
 
-    /* Does not work for DPDK, since do not know which 'pmd' to apply the
-     * operation.  So, just uses PMD_ID_NULL. */
+    /* In case of PMD will be returned flow from first PMD thread with match. */
     error = dpif_flow_get(dpif, NULL, 0, &ufid, PMD_ID_NULL, &buf, &flow);
     if (error) {
         dpctl_error(dpctl_p, error, "getting flow");
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index cf574ad..840f413 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -1985,26 +1985,47 @@  dpif_netdev_flow_get(const struct dpif *dpif, const struct dpif_flow_get *get)
     struct dp_netdev *dp = get_dp_netdev(dpif);
     struct dp_netdev_flow *netdev_flow;
     struct dp_netdev_pmd_thread *pmd;
-    unsigned pmd_id = get->pmd_id == PMD_ID_NULL
-                      ? NON_PMD_CORE_ID : get->pmd_id;
-    int error = 0;
+    struct hmapx to_find;
+    struct hmapx_node *node;
+    int error = EINVAL;
 
-    pmd = dp_netdev_get_pmd(dp, pmd_id);
-    if (!pmd) {
-        return EINVAL;
+    hmapx_init(&to_find);
+    if (get->pmd_id == PMD_ID_NULL) {
+        CMAP_FOR_EACH (pmd, node, &dp->poll_threads) {
+            if (dp_netdev_pmd_try_ref(pmd) && !hmapx_add(&to_find, pmd)) {
+                dp_netdev_pmd_unref(pmd);
+            }
+        }
+    } else {
+        pmd = dp_netdev_get_pmd(dp, get->pmd_id);
+        if (!pmd) {
+            goto out;
+        }
+        hmapx_add(&to_find, pmd);
     }
 
-    netdev_flow = dp_netdev_pmd_find_flow(pmd, get->ufid, get->key,
-                                          get->key_len);
-    if (netdev_flow) {
-        dp_netdev_flow_to_dpif_flow(netdev_flow, get->buffer, get->buffer,
-                                    get->flow, false);
-    } else {
-        error = ENOENT;
+    if (!hmapx_count(&to_find)) {
+        goto out;
     }
-    dp_netdev_pmd_unref(pmd);
 
+    HMAPX_FOR_EACH (node, &to_find) {
+        pmd = (struct dp_netdev_pmd_thread *) node->data;
+        netdev_flow = dp_netdev_pmd_find_flow(pmd, get->ufid, get->key,
+                                              get->key_len);
+        if (netdev_flow) {
+            dp_netdev_flow_to_dpif_flow(netdev_flow, get->buffer, get->buffer,
+                                        get->flow, false);
+            error = 0;
+            break;
+        }
+    }
 
+    HMAPX_FOR_EACH (node, &to_find) {
+        pmd = (struct dp_netdev_pmd_thread *) node->data;
+        dp_netdev_pmd_unref(pmd);
+    }
+out:
+    hmapx_destroy(&to_find);
     return error;
 }