From: Peng Zhang <[email protected]> OVS-DPDK meters are created in advance and OpenFlow rules refer to them by their unique ID. A new API is used to offload them. By calling the API, meters are created and try to be offload to all ports in the bridge.
Signed-off-by: Peng Zhang <[email protected]> Signed-off-by: Jin Liu <[email protected]> --- lib/dpif-netdev.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 2c08a71c8db2..e1cc20d399a9 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -7206,6 +7206,96 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct dp_packet_batch *packets_, ovs_mutex_unlock(&meter->lock); } +static void +dpif_netdev_offload_meter_set(struct dp_netdev *dp, + ofproto_meter_id meter_id, + struct ofputil_meter_config *config) +{ + struct dp_netdev_port *port; + struct netdev *dev; + + ovs_mutex_lock(&dp_netdev_mutex); + + /* Add the meter with all ports in the datapath */ + HMAP_FOR_EACH (port, node, &dp->ports) { + dev = port->netdev; + if (netdev_is_pmd(dev)) { + dpdk_meter_offload_set(dev, meter_id, config); + } + } + + ovs_mutex_unlock(&dp_netdev_mutex); +} + +static void +dpif_netdev_offload_meter_del(struct dp_netdev *dp, + ofproto_meter_id meter_id_, + struct ofputil_meter_stats *stats) +{ + uint32_t meter_id = meter_id_.uint32; + const struct dp_meter *meter; + struct dp_netdev_port *port; + struct netdev *dev; + + meter = dp_meter_lookup(&dp->meters, meter_id); + if (!meter) { + return; + } + + ovs_mutex_lock(&dp_netdev_mutex); + + HMAP_FOR_EACH (port, node, &dp->ports) { + dev = port->netdev; + if (netdev_is_pmd(dev)) { + dpdk_meter_offload_del(dev, meter_id_, stats); + } + } + + ovs_mutex_unlock(&dp_netdev_mutex); +} + +static void +dpif_netdev_offload_meter_get(struct dp_netdev *dp, + ofproto_meter_id meter_id_, + struct ofputil_meter_stats *stats) +{ + struct ofputil_meter_stats offload_stats; + uint32_t meter_id = meter_id_.uint32; + const struct dp_meter *meter; + struct dp_netdev_port *port; + struct netdev *dev; + + meter = dp_meter_lookup(&dp->meters, meter_id); + if (!meter) { + return; + } + + ovs_mutex_lock(&dp_netdev_mutex); + + HMAP_FOR_EACH (port, node, &dp->ports) { + memset(&offload_stats, 0, sizeof(struct ofputil_meter_stats)); + dev = port->netdev; + if (netdev_is_pmd(dev)) { + dpdk_meter_offload_get(dev, meter_id_, &offload_stats); + if (!offload_stats.byte_in_count && + !offload_stats.packet_in_count) { + continue; + } + ovs_mutex_lock(&meter->lock); + + stats->byte_in_count += offload_stats.byte_in_count; + stats->packet_in_count += offload_stats.packet_in_count; + /* nit: Meter offload currently only supports one band */ + if (meter->n_bands) { + stats->bands[0].packet_count = stats->packet_in_count; + stats->bands[0].byte_count = stats->byte_in_count; + } + ovs_mutex_unlock(&meter->lock); + } + } + ovs_mutex_unlock(&dp_netdev_mutex); +} + /* Meter set/get/del processing is still single-threaded. */ static int dpif_netdev_meter_set(struct dpif *dpif, ofproto_meter_id meter_id, @@ -7277,6 +7367,10 @@ dpif_netdev_meter_set(struct dpif *dpif, ofproto_meter_id meter_id, ovs_mutex_unlock(&dp->meters_lock); + if (netdev_is_flow_api_enabled()) { + dpif_netdev_offload_meter_set(dp, meter_id, config); + } + return 0; } @@ -7315,6 +7409,10 @@ dpif_netdev_meter_get(const struct dpif *dpif, stats->n_bands = i; } + if (netdev_is_flow_api_enabled()) { + dpif_netdev_offload_meter_get(dp, meter_id_, stats); + } + return 0; } @@ -7330,6 +7428,10 @@ dpif_netdev_meter_del(struct dpif *dpif, if (!error) { uint32_t meter_id = meter_id_.uint32; + if (netdev_is_flow_api_enabled()) { + dpif_netdev_offload_meter_del(dp, meter_id_, stats); + } + ovs_mutex_lock(&dp->meters_lock); dp_meter_detach_free(&dp->meters, meter_id); ovs_mutex_unlock(&dp->meters_lock); -- 2.30.2 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
