[ovs-dev] [PATCH v5 6/7] dpif-netdev: Support partial offload of PUSH_VLAN action
Sriharsha Basavapatna
sriharsha.basavapatna at broadcom.com
Thu Jul 9 06:47:31 UTC 2020
If the input-port is a vhost-user port and the action is PUSH_VLAN,
offload the action on the egress device if it is offload capable.
Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna at broadcom.com>
---
lib/dpif-netdev.c | 59 ++++++++++++++++++++++++++++++++---------------
lib/odp-execute.c | 11 +--------
2 files changed, 42 insertions(+), 28 deletions(-)
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index ed1b009c2..bfb016059 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -114,6 +114,7 @@ COVERAGE_DEFINE(datapath_drop_invalid_bond);
COVERAGE_DEFINE(datapath_drop_invalid_tnl_port);
COVERAGE_DEFINE(datapath_drop_rx_invalid_packet);
COVERAGE_DEFINE(datapath_skip_tunnel_push);
+COVERAGE_DEFINE(datapath_skip_vlan_push);
/* Protects against changes to 'dp_netdevs'. */
static struct ovs_mutex dp_netdev_mutex = OVS_MUTEX_INITIALIZER;
@@ -2551,15 +2552,18 @@ struct action_attr {
};
/*
- * Maxium number of actions to be parsed while selecting a flow for partial
- * action offload. This number is currently based on the minimum number of
- * attributes seen with the tunnel encap action (clone, tunnel_push, output).
- * This number includes output action to a single egress device (uplink) and
- * supports neither multiple clone() actions nor multiple output actions.
- * This number could change if and when we support other actions or
- * combinations of actions for partial offload.
+ * Maxium number of actions to be parsed while selecting a flow for egress
+ * partial action offload. This number is currently based on the minimum
+ * number of attributes seen with the tunnel encap action (clone, tunnel_push,
+ * output). This number includes output action to a single egress device
+ * (uplink) and supports neither multiple clone() actions nor multiple output
+ * actions.
*/
-#define MAX_ACTION_ATTRS 3 /* Max # action attributes supported */
+enum num_action_attr_egress {
+ VLAN_PUSH_ATTRS = 2, /* vlan_push, output */
+ TUNNEL_PUSH_ATTRS = 3, /* clone, tunnel_push, output */
+ MAX_ACTION_ATTRS_EGRESS = TUNNEL_PUSH_ATTRS
+};
/*
* This function parses the list of OVS "actions" of length "actions_len",
@@ -2620,7 +2624,7 @@ should_partial_offload_egress(struct netdev *in_netdev,
{
const char *dpif_type_str =
dpif_normalize_type(offload->pmd->dp->class->type);
- struct action_attr attrs[MAX_ACTION_ATTRS];
+ struct action_attr attrs[MAX_ACTION_ATTRS_EGRESS];
odp_port_t out_port = ODPP_NONE;
struct netdev *out_netdev;
int num_attrs = 0;
@@ -2633,26 +2637,31 @@ should_partial_offload_egress(struct netdev *in_netdev,
}
rc = parse_nlattr_actions(offload->actions, offload->actions_len, attrs,
- MAX_ACTION_ATTRS, &num_attrs);
+ MAX_ACTION_ATTRS_EGRESS, &num_attrs);
if (rc == E2BIG) {
/* Action list too big; decline partial offload */
return false;
}
- /* Number of attrs expected with tunnel encap action */
- if (num_attrs < MAX_ACTION_ATTRS) {
+ /* Minimum number of attrs expected (push_vlan) */
+ if (num_attrs < VLAN_PUSH_ATTRS) {
return false;
}
- /* Only support clone sub-actions for now, tnl-push specifically. */
- if (attrs[0].type != OVS_ACTION_ATTR_CLONE ||
- attrs[1].type != OVS_ACTION_ATTR_TUNNEL_PUSH ||
- attrs[2].type != OVS_ACTION_ATTR_OUTPUT) {
+ /* Only support clone(tnl-push) or push_vlan actions for now. */
+ if (num_attrs == TUNNEL_PUSH_ATTRS &&
+ (attrs[0].type != OVS_ACTION_ATTR_CLONE ||
+ attrs[1].type != OVS_ACTION_ATTR_TUNNEL_PUSH ||
+ attrs[2].type != OVS_ACTION_ATTR_OUTPUT)) {
+ return false;
+ } else if (num_attrs == VLAN_PUSH_ATTRS &&
+ (attrs[0].type != OVS_ACTION_ATTR_PUSH_VLAN ||
+ attrs[1].type != OVS_ACTION_ATTR_OUTPUT)) {
return false;
}
/* Egress partial-offload needs an output action at the end. */
- out_port = nl_attr_get_odp_port(attrs[2].action);
+ out_port = nl_attr_get_odp_port(attrs[num_attrs - 1].action);
if (out_port == ODPP_NONE) {
return false;
}
@@ -7985,7 +7994,21 @@ dp_execute_cb(void *aux_, struct dp_packet_batch *packets_,
pmd->ctx.now);
break;
- case OVS_ACTION_ATTR_PUSH_VLAN:
+ case OVS_ACTION_ATTR_PUSH_VLAN: {
+ const struct ovs_action_push_vlan *vlan = nl_attr_get(a);
+ struct dp_packet *packet;
+
+ if (!dp_flow || !dp_flow->partial_actions_offloaded) {
+ DP_PACKET_BATCH_FOR_EACH (i, packet, packets_) {
+ eth_push_vlan(packet, vlan->vlan_tpid, vlan->vlan_tci);
+ }
+ } else {
+ packet_count = dp_packet_batch_size(packets_);
+ COVERAGE_ADD(datapath_skip_vlan_push, packet_count);
+ }
+ break;
+ }
+
case OVS_ACTION_ATTR_POP_VLAN:
case OVS_ACTION_ATTR_PUSH_MPLS:
case OVS_ACTION_ATTR_POP_MPLS:
diff --git a/lib/odp-execute.c b/lib/odp-execute.c
index 6eeda2a61..412e96b82 100644
--- a/lib/odp-execute.c
+++ b/lib/odp-execute.c
@@ -801,11 +801,11 @@ requires_datapath_assistance(const struct nlattr *a)
case OVS_ACTION_ATTR_RECIRC:
case OVS_ACTION_ATTR_CT:
case OVS_ACTION_ATTR_METER:
+ case OVS_ACTION_ATTR_PUSH_VLAN:
return true;
case OVS_ACTION_ATTR_SET:
case OVS_ACTION_ATTR_SET_MASKED:
- case OVS_ACTION_ATTR_PUSH_VLAN:
case OVS_ACTION_ATTR_POP_VLAN:
case OVS_ACTION_ATTR_SAMPLE:
case OVS_ACTION_ATTR_HASH:
@@ -924,15 +924,6 @@ odp_execute_actions(void *dp, struct dp_packet_batch *batch, bool steal,
break;
}
- case OVS_ACTION_ATTR_PUSH_VLAN: {
- const struct ovs_action_push_vlan *vlan = nl_attr_get(a);
-
- DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
- eth_push_vlan(packet, vlan->vlan_tpid, vlan->vlan_tci);
- }
- break;
- }
-
case OVS_ACTION_ATTR_POP_VLAN:
DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
eth_pop_vlan(packet);
--
2.25.0.rc2
More information about the dev
mailing list