[ovs-dev] [PATCH 08/20] netdev-offload-dpdk: Framework for actions offload

Eli Britstein elibr at mellanox.com
Wed Nov 20 15:28:14 UTC 2019


Currently HW offload is only accelerating the rule matching sequence.
Introduce a framework for offloading rule actions as a pre-step for
processing the rule actions in HW.

Note: a flow will be fully offloaded only if it can process all its
actions in HW.

Signed-off-by: Eli Britstein <elibr at mellanox.com>
Reviewed-by: Oz Shlomo <ozsh at mellanox.com>
---
 lib/netdev-offload-dpdk-flow.c    | 22 ++++++++++++++++++++++
 lib/netdev-offload-dpdk-private.h |  5 +++++
 lib/netdev-offload-dpdk.c         | 24 ++++++++++++++++++------
 lib/netdev-offload.h              |  1 +
 4 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/lib/netdev-offload-dpdk-flow.c b/lib/netdev-offload-dpdk-flow.c
index 19c933932..dbbc45e99 100644
--- a/lib/netdev-offload-dpdk-flow.c
+++ b/lib/netdev-offload-dpdk-flow.c
@@ -18,6 +18,7 @@
 #include <rte_flow.h>
 
 #include "dpif-netdev.h"
+#include "netdev-offload-provider.h"
 #include "netdev-offload-dpdk-private.h"
 #include "openvswitch/match.h"
 #include "openvswitch/vlog.h"
@@ -25,6 +26,8 @@
 
 VLOG_DEFINE_THIS_MODULE(netdev_offload_dpdk_flow);
 
+static struct vlog_rate_limit error_rl = VLOG_RATE_LIMIT_INIT(100, 5);
+
 void
 netdev_dpdk_flow_patterns_free(struct flow_patterns *patterns)
 {
@@ -528,3 +531,22 @@ netdev_dpdk_flow_patterns_add(struct flow_patterns *patterns,
     return 0;
 }
 
+int
+netdev_dpdk_flow_actions_add(struct flow_actions *actions,
+                             struct nlattr *nl_actions,
+                             size_t nl_actions_len,
+                             struct offload_info *info OVS_UNUSED)
+{
+    struct nlattr *nla;
+    size_t left;
+
+    NL_ATTR_FOR_EACH_UNSAFE (nla, left, nl_actions, nl_actions_len) {
+        VLOG_DBG_RL(&error_rl,
+                    "Unsupported action type %d", nl_attr_type(nla));
+        return -1;
+    }
+
+    add_flow_action(actions, RTE_FLOW_ACTION_TYPE_END, NULL);
+    return 0;
+}
+
diff --git a/lib/netdev-offload-dpdk-private.h b/lib/netdev-offload-dpdk-private.h
index 68caa7144..b69b76dff 100644
--- a/lib/netdev-offload-dpdk-private.h
+++ b/lib/netdev-offload-dpdk-private.h
@@ -51,6 +51,11 @@ void
 netdev_dpdk_flow_actions_add_mark_rss(struct flow_actions *actions,
                                       struct netdev *netdev,
                                       uint32_t mark_id);
+int
+netdev_dpdk_flow_actions_add(struct flow_actions *actions,
+                             struct nlattr *nl_actions,
+                             size_t nl_actions_len,
+                             struct offload_info *info);
 struct ds *
 netdev_dpdk_flow_ds_put_flow(struct ds *s,
                              const struct rte_flow_attr *attr,
diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c
index 64873759d..9a166970f 100644
--- a/lib/netdev-offload-dpdk.c
+++ b/lib/netdev-offload-dpdk.c
@@ -118,16 +118,17 @@ ufid_to_rte_flow_disassociate(const ovs_u128 *ufid)
 static int
 netdev_offload_dpdk_add_flow(struct netdev *netdev,
                              const struct match *match,
-                             struct nlattr *nl_actions OVS_UNUSED,
-                             size_t actions_len OVS_UNUSED,
+                             struct nlattr *nl_actions,
+                             size_t actions_len,
                              const ovs_u128 *ufid,
                              struct offload_info *info)
 {
-    const struct rte_flow_attr flow_attr = {
+    struct rte_flow_attr flow_attr = {
         .group = 0,
         .priority = 0,
         .ingress = 1,
-        .egress = 0
+        .egress = 0,
+        .transfer = 1
     };
     struct flow_patterns patterns = { .items = NULL, .cnt = 0 };
     struct flow_actions actions = { .actions = NULL, .cnt = 0 };
@@ -142,14 +143,25 @@ netdev_offload_dpdk_add_flow(struct netdev *netdev,
         goto out;
     }
 
-    netdev_dpdk_flow_actions_add_mark_rss(&actions, netdev,
-                                          info->flow_mark);
+    info->actions_offloaded = !netdev_dpdk_flow_actions_add(&actions,
+                                                            nl_actions,
+                                                            actions_len, info);
+    if (!info->actions_offloaded) {
+        /* if we failed to offload the rule actions fallback to mark rss
+         * actions.
+         */
+        netdev_dpdk_flow_actions_free(&actions);
+        netdev_dpdk_flow_actions_add_mark_rss(&actions, netdev,
+                                              info->flow_mark);
+        flow_attr.transfer = 0;
+    }
 
     flow = netdev_dpdk_rte_flow_create(netdev, &flow_attr,
                                        patterns.items,
                                        actions.actions, &error);
 
     if (!flow) {
+        info->actions_offloaded = 0;
         VLOG_ERR("%s: rte flow create error: %u : message : %s\n",
                  netdev_get_name(netdev), error.type, error.message);
         ret = -1;
diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h
index 97a500647..e27b8782e 100644
--- a/lib/netdev-offload.h
+++ b/lib/netdev-offload.h
@@ -71,6 +71,7 @@ struct offload_info {
      * it will be in the pkt meta data.
      */
     uint32_t flow_mark;
+    bool actions_offloaded; /* true if flow is fully actions_offloaded */
 };
 
 int netdev_flow_flush(struct netdev *);
-- 
2.14.5



More information about the dev mailing list