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 <[email protected]> Reviewed-by: Oz Shlomo <[email protected]> --- 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 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
