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