diff mbox series

[ovs-dev,v1,04/23] dpctl: Add function to read hardware offload statistics

Message ID fd1aa5278232dad5b9bda793a649ddb07479ab03.1612968146.git.grive@u256.net
State New
Headers show
Series dpif-netdev: Parallel offload processing | expand

Commit Message

Gaƫtan Rivet Feb. 10, 2021, 2:57 p.m. UTC
Expose a function to query datapath offload statistics.
This function is separate from the current one in netdev-offload
as it exposes more detailed statistics from the datapath, instead of
only from the netdev-offload provider.

Each datapath is meant to use the custom counters as it sees fit for its
handling of hardware offloads.

Call the new API from dpctl.

Signed-off-by: Gaetan Rivet <grive@u256.net>
Reviewed-by: Eli Britstein <elibr@nvidia.com>
---
 lib/dpctl.c         | 36 ++++++++++++++++++++++++++++++++++++
 lib/dpif-netdev.c   |  1 +
 lib/dpif-netlink.c  |  1 +
 lib/dpif-provider.h |  7 +++++++
 lib/dpif.c          |  8 ++++++++
 lib/dpif.h          |  9 +++++++++
 6 files changed, 62 insertions(+)
diff mbox series

Patch

diff --git a/lib/dpctl.c b/lib/dpctl.c
index ef8ae7402..6ff73e2d9 100644
--- a/lib/dpctl.c
+++ b/lib/dpctl.c
@@ -1541,6 +1541,40 @@  dpctl_del_flows(int argc, const char *argv[], struct dpctl_params *dpctl_p)
     return error;
 }
 
+static int
+dpctl_offload_stats_show(int argc, const char *argv[],
+                         struct dpctl_params *dpctl_p)
+{
+    struct netdev_custom_stats stats;
+    struct dpif *dpif;
+    int error;
+    size_t i;
+
+    error = opt_dpif_open(argc, argv, dpctl_p, 2, &dpif);
+    if (error) {
+        return error;
+    }
+
+    memset(&stats, 0, sizeof(stats));
+    error = dpif_offload_stats_get(dpif, &stats);
+    if (error) {
+        dpctl_error(dpctl_p, error, "retrieving offload statistics");
+        goto close_dpif;
+    }
+
+    dpctl_print(dpctl_p, "HW Offload stats:\n");
+    for (i = 0; i < stats.size; i++) {
+        dpctl_print(dpctl_p, "   %s: %6" PRIu64 "\n",
+                    stats.counters[i].name, stats.counters[i].value);
+    }
+
+    netdev_free_custom_stats_counters(&stats);
+
+close_dpif:
+    dpif_close(dpif);
+    return error;
+}
+
 static int
 dpctl_help(int argc OVS_UNUSED, const char *argv[] OVS_UNUSED,
            struct dpctl_params *dpctl_p)
@@ -2697,6 +2731,8 @@  static const struct dpctl_command all_commands[] = {
     { "add-flows", "[dp] file", 1, 2, dpctl_process_flows, DP_RW },
     { "mod-flows", "[dp] file", 1, 2, dpctl_process_flows, DP_RW },
     { "del-flows", "[dp] [file]", 0, 2, dpctl_del_flows, DP_RW },
+    { "offload-stats-show", "[dp]",
+      0, 1, dpctl_offload_stats_show, DP_RO },
     { "dump-conntrack", "[-m] [-s] [dp] [zone=N]",
       0, 4, dpctl_dump_conntrack, DP_RO },
     { "flush-conntrack", "[dp] [zone=N] [ct-tuple]", 0, 3,
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index e3fd0a07f..ef347d3b9 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -8458,6 +8458,7 @@  const struct dpif_class dpif_netdev_class = {
     dpif_netdev_flow_dump_thread_destroy,
     dpif_netdev_flow_dump_next,
     dpif_netdev_operate,
+    NULL,                       /* offload_stats_get */
     NULL,                       /* recv_set */
     NULL,                       /* handlers_set */
     dpif_netdev_set_config,
diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
index ceb56c685..924b0bd12 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -3972,6 +3972,7 @@  const struct dpif_class dpif_netlink_class = {
     dpif_netlink_flow_dump_thread_destroy,
     dpif_netlink_flow_dump_next,
     dpif_netlink_operate,
+    NULL,                       /* offload_stats_get */
     dpif_netlink_recv_set,
     dpif_netlink_handlers_set,
     NULL,                       /* set_config */
diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h
index b817fceac..36dfa8e71 100644
--- a/lib/dpif-provider.h
+++ b/lib/dpif-provider.h
@@ -330,6 +330,13 @@  struct dpif_class {
     void (*operate)(struct dpif *dpif, struct dpif_op **ops, size_t n_ops,
                     enum dpif_offload_type offload_type);
 
+    /* Get hardware-offloads activity counters from a dataplane.
+     * Those counters are not offload statistics (which are accessible through
+     * netdev statistics), but a status of hardware offload management:
+     * how many offloads are currently waiting, inserted, etc. */
+    int (*offload_stats_get)(struct dpif *dpif,
+                             struct netdev_custom_stats *stats);
+
     /* Enables or disables receiving packets with dpif_recv() for 'dpif'.
      * Turning packet receive off and then back on is allowed to change Netlink
      * PID assignments (see ->port_get_pid()).  The client is responsible for
diff --git a/lib/dpif.c b/lib/dpif.c
index 56d0b4a65..30fc2db51 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -1426,6 +1426,14 @@  dpif_operate(struct dpif *dpif, struct dpif_op **ops, size_t n_ops,
     }
 }
 
+int dpif_offload_stats_get(struct dpif *dpif,
+                           struct netdev_custom_stats *stats)
+{
+    return (dpif->dpif_class->offload_stats_get
+            ? dpif->dpif_class->offload_stats_get(dpif, stats)
+            : EOPNOTSUPP);
+}
+
 /* Returns a string that represents 'type', for use in log messages. */
 const char *
 dpif_upcall_type_to_string(enum dpif_upcall_type type)
diff --git a/lib/dpif.h b/lib/dpif.h
index ecda896c7..89af01a5b 100644
--- a/lib/dpif.h
+++ b/lib/dpif.h
@@ -787,6 +787,15 @@  struct dpif_op {
 
 void dpif_operate(struct dpif *, struct dpif_op **ops, size_t n_ops,
                   enum dpif_offload_type);
+
+/* Queries the datapath for hardware offloads stats.
+ *
+ * Statistics are written in 'stats' following the 'netdev_custom_stats'
+ * format. They are allocated on the heap and must be freed by the caller,
+ * using 'netdev_free_custom_stats_counters'.
+ */
+int dpif_offload_stats_get(struct dpif *dpif,
+                           struct netdev_custom_stats *stats);
 
 /* Upcalls. */