diff mbox series

[ovs-dev,dpdk-latest,v3,2/6] netdev-offload: Let meter offload API can be used with DPDK

Message ID 20230330112057.14242-3-simon.horman@corigine.com
State Changes Requested
Headers show
Series Add support for DPDK meter HW offload | expand

Checks

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

Commit Message

Simon Horman March 30, 2023, 11:20 a.m. UTC
From: Peng Zhang <peng.zhang@corigine.com>

Changing meter API so it can offload meter to HW in different
datapath. And the corresponding functions to call the DPDK
meter callbacks from all the registered flow API providers.
The interfaces are like those related to DPDK meter in dpif_class,
in order to pass necessary info to HW.

Signed-off-by: Peng Zhang <peng.zhang@corigine.com>
Signed-off-by: Jin Liu <jin.liu@corigine.com>
Co-authored-by: Jin Liu <jin.liu@corigine.com>
Signed-off-by: Simon Horman <simon.horman@corigine.com>
---
 Documentation/howto/dpdk.rst  |   5 +-
 lib/netdev-offload-provider.h |  21 +++++-
 lib/netdev-offload-tc.c       |   9 ++-
 lib/netdev-offload.c          | 135 +++++++++++++++++++++++++++++++++-
 lib/netdev-offload.h          |   9 +++
 5 files changed, 168 insertions(+), 11 deletions(-)

Comments

0-day Robot March 30, 2023, 11:41 a.m. UTC | #1
References:  <20230330112057.14242-3-simon.horman@corigine.com>
 

Bleep bloop.  Greetings Simon Horman, I am a robot and I have tried out your patch.
Thanks for your contribution.

I encountered some error that I wasn't expecting.  See the details below.


checkpatch:
WARNING: Unexpected sign-offs from developers who are not authors or co-authors or committers: Simon Horman <simon.horman@corigine.com>
Lines checked: 313, Warnings: 1, Errors: 0


Please check this out.  If you feel there has been an error, please email aconole@redhat.com

Thanks,
0-day Robot
diff mbox series

Patch

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/netdev-offload-provider.h b/lib/netdev-offload-provider.h
index 9108856d18d1..b02531a0f813 100644
--- a/lib/netdev-offload-provider.h
+++ b/lib/netdev-offload-provider.h
@@ -98,27 +98,42 @@  struct netdev_flow_api {
      * and the configuration in 'config'. On failure, a non-zero error code is
      * returned.
      *
+     * If the datapath is netdev, the api needs the param struct netdev *,
+     * If the datapath is system, the param struct netdev* is unused and
+     * should be NULL.
+     *
      * The meter id specified through 'config->meter_id' is ignored. */
-    int (*meter_set)(ofproto_meter_id meter_id,
+    int (*meter_set)(struct netdev *,
+                     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.
      *
+     * If the datapath is netdev, the api needs the param struct netdev *,
+     * If the datapath is system, the param struct netdev* is unused and
+     * should be NULL.
+     *
      * 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,
+    int (*meter_get)(struct netdev *,
+                     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.
      *
+     * If the datapath is netdev, the api needs the param struct netdev *,
+     * If the datapath is system, the param struct netdev* is unused and
+     * should be NULL.
+     *
      * '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)(struct netdev *,
+                     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..6a965f4d366b 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(struct netdev *netdev OVS_UNUSED,
+                     ofproto_meter_id meter_id,
                      struct ofputil_meter_config *config)
 {
     uint32_t police_index;
@@ -2946,7 +2947,8 @@  meter_tc_set_policer(ofproto_meter_id meter_id,
 }
 
 static int
-meter_tc_get_policer(ofproto_meter_id meter_id,
+meter_tc_get_policer(struct netdev *netdev OVS_UNUSED,
+                     ofproto_meter_id meter_id,
                      struct ofputil_meter_stats *stats)
 {
     uint32_t police_index;
@@ -2965,7 +2967,8 @@  meter_tc_get_policer(ofproto_meter_id meter_id,
 }
 
 static int
-meter_tc_del_policer(ofproto_meter_id meter_id,
+meter_tc_del_policer(struct netdev *netdev OVS_UNUSED,
+                     ofproto_meter_id meter_id,
                      struct ofputil_meter_stats *stats)
 {
     uint32_t police_index;
diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c
index 4592262bd34e..ae38fb7b2fec 100644
--- a/lib/netdev-offload.c
+++ b/lib/netdev-offload.c
@@ -206,7 +206,7 @@  meter_offload_set(ofproto_meter_id meter_id,
 
     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(NULL, 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,
@@ -225,7 +225,7 @@  meter_offload_get(ofproto_meter_id meter_id, struct ofputil_meter_stats *stats)
 
     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(NULL, 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,
@@ -244,7 +244,7 @@  meter_offload_del(ofproto_meter_id meter_id, struct ofputil_meter_stats *stats)
 
     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(NULL, 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,
@@ -895,3 +895,132 @@  netdev_set_flow_api_enabled(const struct smap *ovs_other_config)
         }
     }
 }
+struct dpdk_meter_aux {
+    struct ofputil_meter_config *config;
+    struct ofputil_meter_stats *stats;
+    ofproto_meter_id meter_id;
+    odp_port_t odp_port;
+};
+
+static bool
+dpdk_meter_set_cb(struct netdev *netdev,
+               odp_port_t odp_port,
+               void *aux_)
+{
+    struct netdev_registered_flow_api *rfa;
+    struct dpdk_meter_aux *aux = aux_;
+    ofproto_meter_id meter_id;
+    int ret;
+
+    meter_id = aux->meter_id;
+    CMAP_FOR_EACH (rfa, cmap_node, &netdev_flow_apis) {
+        if (rfa->flow_api->meter_set) {
+            ret = rfa->flow_api->meter_set(netdev, meter_id, aux->config);
+            if (ret) {
+                VLOG_DBG_RL(&rl, "Failed setting meter %u for flow api %s with"
+                            " port number %u, error %d", meter_id.uint32,
+                            rfa->flow_api->type, odp_port, ret);
+            }
+        }
+    }
+
+    return 0;
+}
+
+void
+dpdk_meter_offload_set(const char *dpif_type,
+                       ofproto_meter_id meter_id,
+                       struct ofputil_meter_config *config)
+{
+    struct dpdk_meter_aux aux = {
+        .meter_id = meter_id,
+        .config = config,
+    };
+    netdev_ports_traverse(dpif_type, dpdk_meter_set_cb, &aux);
+}
+
+static bool
+dpdk_meter_get_cb(struct netdev *netdev,
+               odp_port_t odp_port,
+               void *aux_)
+{
+    struct ofputil_meter_stats *stats, offload_stats;
+    struct netdev_registered_flow_api *rfa;
+    struct dpdk_meter_aux *aux = aux_;
+    ofproto_meter_id meter_id;
+    int ret;
+
+    memset(&offload_stats, 0, sizeof(struct ofputil_meter_stats));
+    meter_id = aux->meter_id;
+    stats = aux->stats;
+    CMAP_FOR_EACH (rfa, cmap_node, &netdev_flow_apis) {
+        if (rfa->flow_api->meter_get) {
+            ret = rfa->flow_api->meter_get(netdev, meter_id, &offload_stats);
+            if (ret) {
+                VLOG_DBG_RL(&rl, "Failed getting meter %u for flow api %s with"
+                            " port number %u, error %d", meter_id.uint32,
+                            rfa->flow_api->type, odp_port, ret);
+            }
+        }
+    }
+
+    if (!offload_stats.byte_in_count && !offload_stats.packet_in_count) {
+           return 0;
+    }
+    stats->byte_in_count += offload_stats.byte_in_count;
+    stats->packet_in_count += offload_stats.packet_in_count;
+
+    return 0;
+}
+
+void
+dpdk_meter_offload_get(const char *dpif_type,
+                       ofproto_meter_id meter_id,
+                       struct ofputil_meter_stats *stats)
+{
+    struct dpdk_meter_aux aux = {
+        .meter_id = meter_id,
+        .stats = stats,
+    };
+    netdev_ports_traverse(dpif_type, dpdk_meter_get_cb, &aux);
+}
+
+static bool
+dpdk_meter_del_cb(struct netdev *netdev,
+               odp_port_t odp_port,
+               void *aux_)
+{
+    struct netdev_registered_flow_api *rfa;
+    struct ofputil_meter_stats *stats;
+    struct dpdk_meter_aux *aux = aux_;
+    ofproto_meter_id meter_id;
+    int ret;
+
+    meter_id = aux->meter_id;
+    stats = aux->stats;
+    CMAP_FOR_EACH (rfa, cmap_node, &netdev_flow_apis) {
+        if (rfa->flow_api->meter_del) {
+            ret = rfa->flow_api->meter_del(netdev, meter_id, stats);
+            if (ret) {
+                VLOG_DBG_RL(&rl, "Failed deleting meter %u for flow api %s"
+                            " with port number %u, error %d", meter_id.uint32,
+                            rfa->flow_api->type, odp_port, ret);
+            }
+        }
+    }
+
+    return 0;
+}
+
+void
+dpdk_meter_offload_del(const char *dpif_type,
+                       ofproto_meter_id meter_id,
+                       struct ofputil_meter_stats *stats)
+{
+    struct dpdk_meter_aux aux = {
+        .meter_id = meter_id,
+        .stats = stats,
+    };
+
+    netdev_ports_traverse(dpif_type, dpdk_meter_del_cb, &aux);
+}
diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h
index edc843cd99a3..e53f70a277b3 100644
--- a/lib/netdev-offload.h
+++ b/lib/netdev-offload.h
@@ -161,6 +161,15 @@  int netdev_ports_get_n_flows(const char *dpif_type,
 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 dpdk_meter_offload_set(const char *dpif_type,
+                            ofproto_meter_id meter_id,
+                            struct ofputil_meter_config *config);
+void dpdk_meter_offload_del(const char *dpif_type,
+                            ofproto_meter_id meter_id_,
+                            struct ofputil_meter_stats *stats);
+void dpdk_meter_offload_get(const char *dpif_type,
+                            ofproto_meter_id meter_id_,
+                            struct ofputil_meter_stats *stats);
 
 #ifdef  __cplusplus
 }