- Missing proper handling of the testpmd syntax logging. It changes the used port according to "transfer", but the log still uses netdev_dpdk_get_port_id(). - The usage of the "proxy" port for rte-flow implies that this proxy port is attached to OVS, otherwise it is not "started" and creation of flows will fail.
>-----Original Message----- >From: Ivan Malov <[email protected]> >Sent: Monday, May 30, 2022 5:16 PM >To: [email protected] >Cc: Andrew Rybchenko <[email protected]>; Ilya Maximets ><[email protected]>; Ori Kam <[email protected]>; Eli Britstein ><[email protected]>; NBU-Contact-Thomas Monjalon (EXTERNAL) ><[email protected]>; Stephen Hemminger ><[email protected]>; David Marchand ><[email protected]>; Gaetan Rivet <[email protected]>; Maxime >Coquelin <[email protected]> >Subject: [PATCH 3/3] netdev-offload-dpdk: use flow transfer proxy >mechanism > >External email: Use caution opening links or attachments > > >Manage "transfer" flows via the corresponding mechanism. >Doing so requires that the traffic source be specified explicitly, via the >corresponding pattern item. > >Signed-off-by: Ivan Malov <[email protected]> >Acked-by: Andrew Rybchenko <[email protected]> >--- > lib/netdev-dpdk.c | 73 ++++++++++++++++++++++++++++++++------- > lib/netdev-dpdk.h | 2 +- > lib/netdev-offload-dpdk.c | 43 ++++++++++++++++++++++- > 3 files changed, 103 insertions(+), 15 deletions(-) > >diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index >45e5d26d2..d0bf4613a 100644 >--- a/lib/netdev-dpdk.c >+++ b/lib/netdev-dpdk.c >@@ -420,6 +420,7 @@ enum dpdk_hw_ol_features { > > struct netdev_dpdk { > PADDED_MEMBERS_CACHELINE_MARKER(CACHE_LINE_SIZE, cacheline0, >+ dpdk_port_t flow_transfer_proxy_port_id; > dpdk_port_t port_id; > > /* If true, device was attached by rte_eth_dev_attach(). */ @@ -1115,6 >+1116,23 @@ dpdk_eth_dev_init_rx_metadata(struct netdev_dpdk *dev) > DPDK_PORT_ID_FMT, dev->port_id); > } > } >+ >+static void >+dpdk_eth_dev_init_flow_transfer_proxy(struct netdev_dpdk *dev) { >+ int ret; >+ >+ ret = rte_flow_pick_transfer_proxy(dev->port_id, >+ &dev->flow_transfer_proxy_port_id, >NULL); >+ if (ret == 0) >+ return; >+ >+ /* >+ * The PMD does not indicate the proxy port. >+ * It is OK to assume the proxy is unneeded. >+ */ >+ dev->flow_transfer_proxy_port_id = dev->port_id; } > #endif /* ALLOW_EXPERIMENTAL_API */ > > static int >@@ -1141,6 +1159,19 @@ dpdk_eth_dev_init(struct netdev_dpdk *dev) > * Request delivery of such metadata. > */ > dpdk_eth_dev_init_rx_metadata(dev); >+ >+ /* >+ * Managing "transfer" flows requires that the user communicate them >+ * via a port which has the privilege to control the embedded switch. >+ * For some vendors, all ports in a given switching domain have >+ * this privilege. For other vendors, it's only one port. >+ * >+ * Get the proxy port ID and remember it for later use. >+ */ >+ dpdk_eth_dev_init_flow_transfer_proxy(dev); >+#else /* ! ALLOW_EXPERIMENTAL_API */ >+ /* It is OK to assume the proxy is unneeded. */ >+ dev->flow_transfer_proxy_port_id = dev->port_id; > #endif /* ALLOW_EXPERIMENTAL_API */ > > rte_eth_dev_info_get(dev->port_id, &info); >@@ -5214,13 +5245,15 @@ out: > > int > netdev_dpdk_rte_flow_destroy(struct netdev *netdev, >- struct rte_flow *rte_flow, >+ bool transfer, struct rte_flow *rte_flow, > struct rte_flow_error *error) > { > struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); > int ret; > >- ret = rte_flow_destroy(dev->port_id, rte_flow, error); >+ ret = rte_flow_destroy(transfer ? >+ dev->flow_transfer_proxy_port_id : dev->port_id, >+ rte_flow, error); > return ret; > } > >@@ -5234,7 +5267,19 @@ netdev_dpdk_rte_flow_create(struct netdev >*netdev, > struct rte_flow *flow; > struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); > >- flow = rte_flow_create(dev->port_id, attr, items, actions, error); >+#ifdef ALLOW_EXPERIMENTAL_API >+ if (!attr->transfer) { >+ /* >+ * The 1st item in any pattern is a traffic source one. >+ * It is unnecessary in the case of non-transfer rules. >+ */ >+ ++(items); >+ } >+#endif /* ALLOW_EXPERIMENTAL_API */ >+ >+ flow = rte_flow_create(attr->transfer ? >+ dev->flow_transfer_proxy_port_id : dev->port_id, >+ attr, items, actions, error); > return flow; > } > >@@ -5262,7 +5307,8 @@ netdev_dpdk_rte_flow_query_count(struct netdev >*netdev, > } > > dev = netdev_dpdk_cast(netdev); >- ret = rte_flow_query(dev->port_id, rte_flow, actions, query, error); >+ ret = rte_flow_query(dev->flow_transfer_proxy_port_id, rte_flow, >+ actions, query, error); > return ret; > } > >@@ -5284,8 +5330,8 @@ netdev_dpdk_rte_flow_tunnel_decap_set(struct >netdev *netdev, > > dev = netdev_dpdk_cast(netdev); > ovs_mutex_lock(&dev->mutex); >- ret = rte_flow_tunnel_decap_set(dev->port_id, tunnel, actions, >- num_of_actions, error); >+ ret = rte_flow_tunnel_decap_set(dev->flow_transfer_proxy_port_id, >tunnel, >+ actions, num_of_actions, error); > ovs_mutex_unlock(&dev->mutex); > return ret; > } >@@ -5306,8 +5352,8 @@ netdev_dpdk_rte_flow_tunnel_match(struct >netdev *netdev, > > dev = netdev_dpdk_cast(netdev); > ovs_mutex_lock(&dev->mutex); >- ret = rte_flow_tunnel_match(dev->port_id, tunnel, items, num_of_items, >- error); >+ ret = rte_flow_tunnel_match(dev->flow_transfer_proxy_port_id, tunnel, >+ items, num_of_items, error); > ovs_mutex_unlock(&dev->mutex); > return ret; > } >@@ -5328,7 +5374,8 @@ netdev_dpdk_rte_flow_get_restore_info(struct >netdev *netdev, > > dev = netdev_dpdk_cast(netdev); > ovs_mutex_lock(&dev->mutex); >- ret = rte_flow_get_restore_info(dev->port_id, m, info, error); >+ ret = rte_flow_get_restore_info(dev->flow_transfer_proxy_port_id, >+ m, info, error); > ovs_mutex_unlock(&dev->mutex); > return ret; > } >@@ -5349,8 +5396,8 @@ >netdev_dpdk_rte_flow_tunnel_action_decap_release( > > dev = netdev_dpdk_cast(netdev); > ovs_mutex_lock(&dev->mutex); >- ret = rte_flow_tunnel_action_decap_release(dev->port_id, actions, >- num_of_actions, error); >+ ret = rte_flow_tunnel_action_decap_release(dev- >>flow_transfer_proxy_port_id, >+ actions, num_of_actions, >error); > ovs_mutex_unlock(&dev->mutex); > return ret; > } >@@ -5370,8 +5417,8 @@ netdev_dpdk_rte_flow_tunnel_item_release(struct >netdev *netdev, > > dev = netdev_dpdk_cast(netdev); > ovs_mutex_lock(&dev->mutex); >- ret = rte_flow_tunnel_item_release(dev->port_id, items, num_of_items, >- error); >+ ret = rte_flow_tunnel_item_release(dev->flow_transfer_proxy_port_id, >+ items, num_of_items, error); > ovs_mutex_unlock(&dev->mutex); > return ret; > } >diff --git a/lib/netdev-dpdk.h b/lib/netdev-dpdk.h >index 699be3fb4..1dd5953a4 100644 >--- a/lib/netdev-dpdk.h >+++ b/lib/netdev-dpdk.h >@@ -35,7 +35,7 @@ bool netdev_dpdk_flow_api_supported(struct netdev *); > > int > netdev_dpdk_rte_flow_destroy(struct netdev *netdev, >- struct rte_flow *rte_flow, >+ bool transfer, struct rte_flow *rte_flow, > struct rte_flow_error *error); > struct rte_flow * > netdev_dpdk_rte_flow_create(struct netdev *netdev, >diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c >index 9cd5a0159..f8b90cbf7 100644 >--- a/lib/netdev-offload-dpdk.c >+++ b/lib/netdev-offload-dpdk.c >@@ -353,8 +353,23 @@ dump_flow_pattern(struct ds *s, > > if (item->type == RTE_FLOW_ITEM_TYPE_END) { > ds_put_cstr(s, "end "); >+#ifdef ALLOW_EXPERIMENTAL_API >+ } else if (item->type == RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT) { >+ const struct rte_flow_item_ethdev *ethdev_spec = item->spec; >+ const struct rte_flow_item_ethdev *ethdev_mask = item->mask; >+ >+ ds_put_cstr(s, "represented_port "); >+ >+ DUMP_PATTERN_ITEM(ethdev_mask->port_id, false, "ethdev_port_id", >+ "%"PRIu16, ethdev_spec->port_id, >+ ethdev_mask->port_id, 0); >+ } else if (flow_patterns->tnl_pmd_items_cnt && >+ pattern_index < 1 /* REPRESENTED_PORT */ + >+ flow_patterns->tnl_pmd_items_cnt) { >+#else /* ! ALLOW_EXPERIMENTAL_API */ > } else if (flow_patterns->tnl_pmd_items_cnt && > pattern_index < flow_patterns->tnl_pmd_items_cnt) { >+#endif /* ALLOW_EXPERIMENTAL_API */ > return; > } else if (item->type == RTE_FLOW_ITEM_TYPE_ETH) { > const struct rte_flow_item_eth *eth_spec = item->spec; >@@ -1035,6 +1050,12 @@ free_flow_patterns(struct flow_patterns >*patterns) > struct rte_flow_error error; > int i; > >+#ifdef ALLOW_EXPERIMENTAL_API >+ /* REPRESENTED_PORT */ >+ free(CONST_CAST(void *, patterns->items[0].spec)); >+ free(CONST_CAST(void *, patterns->items[0].mask)); >+#endif /* ALLOW_EXPERIMENTAL_API */ >+ > if (patterns->tnl_pmd_items) { > struct rte_flow_item *tnl_pmd_items = patterns->tnl_pmd_items; > uint32_t tnl_pmd_items_cnt = patterns->tnl_pmd_items_cnt; >@@ -1049,7 +1070,12 @@ free_flow_patterns(struct flow_patterns >*patterns) > } > } > >+#ifdef ALLOW_EXPERIMENTAL_API >+ for (i = 1 /* REPRESENTED_PORT */ + patterns->tnl_pmd_items_cnt; >+ i < patterns->cnt; i++) { >+#else /* ! ALLOW_EXPERIMENTAL_API */ > for (i = patterns->tnl_pmd_items_cnt; i < patterns->cnt; i++) { >+#endif /* ALLOW_EXPERIMENTAL_API */ > if (patterns->items[i].spec) { > free(CONST_CAST(void *, patterns->items[i].spec)); > } >@@ -1383,10 +1409,23 @@ parse_flow_match(struct netdev *netdev, > struct flow_patterns *patterns, > struct match *match) > { >+#ifdef ALLOW_EXPERIMENTAL_API >+ struct netdev *physdev = netdev_ports_get(orig_in_port, netdev- >>dpif_type); >+ struct rte_flow_item_ethdev *ethdev_spec = xzalloc(sizeof *ethdev_spec); >+ struct rte_flow_item_ethdev *ethdev_mask = xzalloc(sizeof >*ethdev_mask); >+#endif /* ALLOW_EXPERIMENTAL_API */ > struct rte_flow_item_eth *eth_spec = NULL, *eth_mask = NULL; > struct flow *consumed_masks; > uint8_t proto = 0; > >+#ifdef ALLOW_EXPERIMENTAL_API >+ /* Add an explicit traffic source item to the beginning of the pattern. */ >+ ethdev_spec->port_id = netdev_dpdk_get_port_id(physdev); >+ *ethdev_mask = rte_flow_item_ethdev_mask; >+ add_flow_pattern(patterns, >RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT, >+ ethdev_spec, ethdev_mask, NULL); >+#endif /* ALLOW_EXPERIMENTAL_API */ >+ > consumed_masks = &match->wc.masks; > > if (!flow_tnl_dst_is_set(&match->flow.tunnel)) { >@@ -2333,6 +2372,7 @@ netdev_offload_dpdk_flow_destroy(struct >ufid_to_rte_flow_data *rte_flow_data) > struct netdev *physdev; > struct netdev *netdev; > ovs_u128 *ufid; >+ bool transfer; > int ret; > > ovs_mutex_lock(&rte_flow_data->lock); >@@ -2344,12 +2384,13 @@ netdev_offload_dpdk_flow_destroy(struct >ufid_to_rte_flow_data *rte_flow_data) > > rte_flow_data->dead = true; > >+ transfer = rte_flow_data->actions_offloaded; > rte_flow = rte_flow_data->rte_flow; > physdev = rte_flow_data->physdev; > netdev = rte_flow_data->netdev; > ufid = &rte_flow_data->ufid; > >- ret = netdev_dpdk_rte_flow_destroy(physdev, rte_flow, &error); >+ ret = netdev_dpdk_rte_flow_destroy(physdev, transfer, rte_flow, &error); > > if (ret == 0) { > struct netdev_offload_dpdk_data *data; >-- >2.30.2 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
