[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