diff mbox series

[ovs-dev,v7,1/9] netdev-offload: Add meter offload API

Message ID 20220708030630.9437-2-jianbol@nvidia.com
State Superseded
Headers show
Series Add support for ovs metering with tc offload | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test success github build: passed
ovsrobot/intel-ovs-compilation success test: success

Commit Message

Jianbo Liu July 8, 2022, 3:06 a.m. UTC
Add API to offload meter to HW, and the corresponding functions to call
the meter callbacks from all the registered flow API providers.
The interfaces are like those related to meter in dpif_class, in order
to pass necessary info to HW.

Signed-off-by: Jianbo Liu <jianbol@nvidia.com>
Acked-by: Eelco Chaudron <echaudro@redhat.com>
---
 lib/netdev-offload-provider.h | 27 ++++++++++++++++
 lib/netdev-offload.c          | 59 +++++++++++++++++++++++++++++++++++
 lib/netdev-offload.h          |  5 +++
 3 files changed, 91 insertions(+)
diff mbox series

Patch

diff --git a/lib/netdev-offload-provider.h b/lib/netdev-offload-provider.h
index 8ff2de983..9108856d1 100644
--- a/lib/netdev-offload-provider.h
+++ b/lib/netdev-offload-provider.h
@@ -94,6 +94,33 @@  struct netdev_flow_api {
      * takes ownership of a packet if errno != EOPNOTSUPP. */
     int (*hw_miss_packet_recover)(struct netdev *, struct dp_packet *);
 
+    /* Offloads or modifies the offloaded meter in HW with the given 'meter_id'
+     * and the configuration in 'config'. On failure, a non-zero error code is
+     * returned.
+     *
+     * The meter id specified through 'config->meter_id' is ignored. */
+    int (*meter_set)(ofproto_meter_id meter_id,
+                     struct ofputil_meter_config *config);
+
+    /* Queries HW for meter stats with the given 'meter_id'. Store the stats
+     * of dropped packets to band 0. On failure, a non-zero error code is
+     * returned.
+     *
+     * Note that the 'stats' structure is already initialized, and only the
+     * 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,
+                     struct ofputil_meter_stats *stats);
+
+    /* Removes meter 'meter_id' from HW. Store the stats of dropped packets to
+     * band 0. On failure, a non-zero error code is returned.
+     *
+     * '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,
+                     struct ofputil_meter_stats *stats);
+
     /* Initializies the netdev flow api.
      * Return 0 if successful, otherwise returns a positive errno value. */
     int (*init_flow_api)(struct netdev *);
diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c
index fb108c0d5..9fde5f7a9 100644
--- a/lib/netdev-offload.c
+++ b/lib/netdev-offload.c
@@ -58,6 +58,7 @@ 
 VLOG_DEFINE_THIS_MODULE(netdev_offload);
 
 
+static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
 static bool netdev_flow_api_enabled = false;
 
 #define DEFAULT_OFFLOAD_THREAD_NB 1
@@ -195,6 +196,64 @@  netdev_assign_flow_api(struct netdev *netdev)
     return -1;
 }
 
+void
+meter_offload_set(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);
+            if (ret) {
+                VLOG_DBG_RL(&rl, "Failed setting meter %u for flow api %s, "
+                            "error %d", meter_id.uint32, rfa->flow_api->type,
+                            ret);
+           }
+        }
+    }
+    /* Offload APIs could fail, for example, because the offload is not
+     * supported. This is fine, as the offload API should take care of this. */
+}
+
+int
+meter_offload_get(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);
+            if (ret) {
+                VLOG_DBG_RL(&rl, "Failed getting meter %u for flow api %s, "
+                            "error %d", meter_id.uint32, rfa->flow_api->type,
+                            ret);
+           }
+        }
+    }
+
+    return 0;
+}
+
+int
+meter_offload_del(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);
+            if (ret) {
+                VLOG_DBG_RL(&rl, "Failed deleting meter %u for flow api %s, "
+                            "error %d", meter_id.uint32, rfa->flow_api->type,
+                            ret);
+            }
+        }
+    }
+
+    return 0;
+}
+
 int
 netdev_flow_flush(struct netdev *netdev)
 {
diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h
index 8237a85dd..249a3102a 100644
--- a/lib/netdev-offload.h
+++ b/lib/netdev-offload.h
@@ -22,6 +22,7 @@ 
 #include "openvswitch/types.h"
 #include "ovs-rcu.h"
 #include "ovs-thread.h"
+#include "openvswitch/ofp-meter.h"
 #include "packets.h"
 #include "flow.h"
 
@@ -158,6 +159,10 @@  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 *);
+
 #ifdef  __cplusplus
 }
 #endif