From: Peng Zhang <[email protected]> By calling meter API, so it can offload meter to HW in netdev datapath. Add the check for datapath in the meter API to avoid the unnecessary error.
Signed-off-by: Peng Zhang <[email protected]> Signed-off-by: Jin Liu <[email protected]> Co-authored-by: Jin Liu <[email protected]> Signed-off-by: Simon Horman <[email protected]> --- Documentation/howto/dpdk.rst | 5 +++-- lib/dpif-netdev.c | 27 +++++++++++++++++++++++++-- lib/dpif-netlink.c | 9 ++++++--- lib/netdev-offload-provider.h | 9 ++++++--- lib/netdev-offload-tc.c | 24 +++++++++++++++++++++--- lib/netdev-offload.c | 17 +++++++++++------ lib/netdev-offload.h | 9 ++++++--- 7 files changed, 78 insertions(+), 22 deletions(-) diff --git a/Documentation/howto/dpdk.rst b/Documentation/howto/dpdk.rst index 04609b20bd21..02fc568770ee 100644 --- a/Documentation/howto/dpdk.rst +++ b/Documentation/howto/dpdk.rst @@ -401,10 +401,11 @@ Supported actions for hardware offload are: - Modification of IPv6 (set_field:<ADDR>->ipv6_src/ipv6_dst/mod_nw_ttl). - Clone/output (tnl_push and output) for encapsulating over a tunnel. - Tunnel pop, for packets received on physical ports. +- Meter. .. note:: - Tunnel offloads are experimental APIs in DPDK. In order to enable it, - compile with -DALLOW_EXPERIMENTAL_API. + Tunnel offloads and Meter offloads are experimental APIs in DPDK. To enable + these features, compile with -DALLOW_EXPERIMENTAL_API. Multiprocess ------------ diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 2c08a71c8db2..e3e0346c30dd 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -7277,6 +7277,11 @@ dpif_netdev_meter_set(struct dpif *dpif, ofproto_meter_id meter_id, ovs_mutex_unlock(&dp->meters_lock); + if (netdev_is_flow_api_enabled()) { + meter_offload_set(dpif_normalize_type(dpif_type(dpif)), + meter_id, config); + } + return 0; } @@ -7287,7 +7292,7 @@ dpif_netdev_meter_get(const struct dpif *dpif, { struct dp_netdev *dp = get_dp_netdev(dpif); uint32_t meter_id = meter_id_.uint32; - const struct dp_meter *meter; + struct dp_meter *meter; if (meter_id >= MAX_METERS) { return EFBIG; @@ -7313,8 +7318,21 @@ dpif_netdev_meter_get(const struct dpif *dpif, ovs_mutex_unlock(&meter->lock); stats->n_bands = i; - } + if (netdev_is_flow_api_enabled()) { + meter_offload_get(dpif_normalize_type(dpif_type(dpif)), + meter_id_, stats); + + meter->packet_count = stats->packet_in_count; + meter->byte_count = stats->byte_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; + } + } + } return 0; } @@ -7330,6 +7348,11 @@ dpif_netdev_meter_del(struct dpif *dpif, if (!error) { uint32_t meter_id = meter_id_.uint32; + if (netdev_is_flow_api_enabled()) { + meter_offload_del(dpif_normalize_type(dpif_type(dpif)), + meter_id_, stats); + } + ovs_mutex_lock(&dp->meters_lock); dp_meter_detach_free(&dp->meters, meter_id); ovs_mutex_unlock(&dp->meters_lock); diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index 026b0daa8d83..c90b5c3fb776 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -4249,7 +4249,8 @@ dpif_netlink_meter_set(struct dpif *dpif_, ofproto_meter_id meter_id, err = dpif_netlink_meter_set__(dpif_, meter_id, config); if (!err && netdev_is_flow_api_enabled()) { - meter_offload_set(meter_id, config); + meter_offload_set(dpif_normalize_type(dpif_type(dpif_)), + meter_id, config); } return err; @@ -4348,7 +4349,8 @@ dpif_netlink_meter_get(const struct dpif *dpif, ofproto_meter_id meter_id, err = dpif_netlink_meter_get_stats(dpif, meter_id, stats, max_bands, OVS_METER_CMD_GET); if (!err && netdev_is_flow_api_enabled()) { - meter_offload_get(meter_id, stats); + meter_offload_get(dpif_normalize_type(dpif_type(dpif)), + meter_id, stats); } return err; @@ -4363,7 +4365,8 @@ dpif_netlink_meter_del(struct dpif *dpif, ofproto_meter_id meter_id, err = dpif_netlink_meter_get_stats(dpif, meter_id, stats, max_bands, OVS_METER_CMD_DEL); if (!err && netdev_is_flow_api_enabled()) { - meter_offload_del(meter_id, stats); + meter_offload_del(dpif_normalize_type(dpif_type(dpif)), + meter_id, stats); } return err; diff --git a/lib/netdev-offload-provider.h b/lib/netdev-offload-provider.h index 9108856d18d1..23d94b1b24ae 100644 --- a/lib/netdev-offload-provider.h +++ b/lib/netdev-offload-provider.h @@ -99,7 +99,8 @@ struct netdev_flow_api { * returned. * * The meter id specified through 'config->meter_id' is ignored. */ - int (*meter_set)(ofproto_meter_id meter_id, + int (*meter_set)(const char *type, + ofproto_meter_id meter_id, struct ofputil_meter_config *config); /* Queries HW for meter stats with the given 'meter_id'. Store the stats @@ -110,7 +111,8 @@ struct netdev_flow_api { * available statistics should be incremented, not replaced. Those fields * are packet_in_count, byte_in_count and band[]->byte_count and * band[]->packet_count. */ - int (*meter_get)(ofproto_meter_id meter_id, + int (*meter_get)(const char *type, + ofproto_meter_id meter_id, struct ofputil_meter_stats *stats); /* Removes meter 'meter_id' from HW. Store the stats of dropped packets to @@ -118,7 +120,8 @@ struct netdev_flow_api { * * 'stats' may be passed in as NULL if no stats are needed, See the above * function for additional details on the 'stats' usage. */ - int (*meter_del)(ofproto_meter_id meter_id, + int (*meter_del)(const char *type, + ofproto_meter_id meter_id, struct ofputil_meter_stats *stats); /* Initializies the netdev flow api. diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index ce7f8ad97306..2e708df036d4 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -2892,7 +2892,8 @@ meter_free_police_index(uint32_t police_index) } static int -meter_tc_set_policer(ofproto_meter_id meter_id, +meter_tc_set_policer(const char *dpif_type, + ofproto_meter_id meter_id, struct ofputil_meter_config *config) { uint32_t police_index; @@ -2900,6 +2901,11 @@ meter_tc_set_policer(ofproto_meter_id meter_id, bool add_policer; int err; + if (strcmp(dpif_type, "system")) { + VLOG_DBG("meter doesn't belongs to the system datapath. Skipping."); + return EOPNOTSUPP; + } + if (!config->bands || config->n_bands < 1 || config->bands[0].type != OFPMBT13_DROP) { return 0; @@ -2946,12 +2952,18 @@ meter_tc_set_policer(ofproto_meter_id meter_id, } static int -meter_tc_get_policer(ofproto_meter_id meter_id, +meter_tc_get_policer(const char *dpif_type, + ofproto_meter_id meter_id, struct ofputil_meter_stats *stats) { uint32_t police_index; int err = ENOENT; + if (strcmp(dpif_type, "system")) { + VLOG_DBG("meter doesn't belongs to the system datapath. Skipping."); + return EOPNOTSUPP; + } + if (!meter_id_lookup(meter_id.uint32, &police_index)) { err = tc_get_policer_action(police_index, stats); if (err) { @@ -2965,12 +2977,18 @@ meter_tc_get_policer(ofproto_meter_id meter_id, } static int -meter_tc_del_policer(ofproto_meter_id meter_id, +meter_tc_del_policer(const char *dpif_type, + ofproto_meter_id meter_id, struct ofputil_meter_stats *stats) { uint32_t police_index; int err = ENOENT; + if (strcmp(dpif_type, "system")) { + VLOG_DBG("meter doesn't belongs to the system datapath. Skipping."); + return EOPNOTSUPP; + } + if (!meter_id_lookup(meter_id.uint32, &police_index)) { err = tc_del_policer_action(police_index, stats); if (err && err != ENOENT) { diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c index 4592262bd34e..52dc74c216a3 100644 --- a/lib/netdev-offload.c +++ b/lib/netdev-offload.c @@ -199,14 +199,15 @@ netdev_assign_flow_api(struct netdev *netdev) } void -meter_offload_set(ofproto_meter_id meter_id, +meter_offload_set(const char *dpif_type, + ofproto_meter_id meter_id, struct ofputil_meter_config *config) { struct netdev_registered_flow_api *rfa; CMAP_FOR_EACH (rfa, cmap_node, &netdev_flow_apis) { if (rfa->flow_api->meter_set) { - int ret = rfa->flow_api->meter_set(meter_id, config); + int ret = rfa->flow_api->meter_set(dpif_type, meter_id, config); if (ret) { VLOG_DBG_RL(&rl, "Failed setting meter %u for flow api %s, " "error %d", meter_id.uint32, rfa->flow_api->type, @@ -219,13 +220,15 @@ meter_offload_set(ofproto_meter_id meter_id, } int -meter_offload_get(ofproto_meter_id meter_id, struct ofputil_meter_stats *stats) +meter_offload_get(const char *dpif_type, + ofproto_meter_id meter_id, + struct ofputil_meter_stats *stats) { struct netdev_registered_flow_api *rfa; CMAP_FOR_EACH (rfa, cmap_node, &netdev_flow_apis) { if (rfa->flow_api->meter_get) { - int ret = rfa->flow_api->meter_get(meter_id, stats); + int ret = rfa->flow_api->meter_get(dpif_type, meter_id, stats); if (ret) { VLOG_DBG_RL(&rl, "Failed getting meter %u for flow api %s, " "error %d", meter_id.uint32, rfa->flow_api->type, @@ -238,13 +241,15 @@ meter_offload_get(ofproto_meter_id meter_id, struct ofputil_meter_stats *stats) } int -meter_offload_del(ofproto_meter_id meter_id, struct ofputil_meter_stats *stats) +meter_offload_del(const char *dpif_type, + ofproto_meter_id meter_id, + struct ofputil_meter_stats *stats) { struct netdev_registered_flow_api *rfa; CMAP_FOR_EACH (rfa, cmap_node, &netdev_flow_apis) { if (rfa->flow_api->meter_del) { - int ret = rfa->flow_api->meter_del(meter_id, stats); + int ret = rfa->flow_api->meter_del(dpif_type, meter_id, stats); if (ret) { VLOG_DBG_RL(&rl, "Failed deleting meter %u for flow api %s, " "error %d", meter_id.uint32, rfa->flow_api->type, diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h index edc843cd99a3..b52d642bf8ab 100644 --- a/lib/netdev-offload.h +++ b/lib/netdev-offload.h @@ -158,9 +158,12 @@ int netdev_ports_flow_get(const char *dpif_type, struct match *match, int netdev_ports_get_n_flows(const char *dpif_type, odp_port_t port_no, uint64_t *n_flows); -void meter_offload_set(ofproto_meter_id, struct ofputil_meter_config *); -int meter_offload_get(ofproto_meter_id, struct ofputil_meter_stats *); -int meter_offload_del(ofproto_meter_id, struct ofputil_meter_stats *); +void meter_offload_set(const char *dpif_type, ofproto_meter_id, + struct ofputil_meter_config *); +int meter_offload_get(const char *dpif_type, ofproto_meter_id, + struct ofputil_meter_stats *); +int meter_offload_del(const char *dpif_type, ofproto_meter_id, + struct ofputil_meter_stats *); #ifdef __cplusplus } -- 2.30.2 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
