summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGaetan Rivet <grive@u256.net>2021-09-08 11:47:31 +0200
committerIlya Maximets <i.maximets@ovn.org>2022-01-18 15:12:01 +0100
commit9ab104718bcb00b0ac6fd33e4434763a5e00013d (patch)
treefd8a82daa7d2374aec0d3b114f9b3bf1182d7a88
parent0e6366c2399d970def5bdc7f489f4f9e0f32aa47 (diff)
downloadopenvswitch-9ab104718bcb00b0ac6fd33e4434763a5e00013d.tar.gz
dpctl: Add function to read hardware offload statistics.
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> Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
-rw-r--r--lib/dpctl.c36
-rw-r--r--lib/dpif-netdev.c1
-rw-r--r--lib/dpif-netlink.c1
-rw-r--r--lib/dpif-provider.h7
-rw-r--r--lib/dpif.c8
-rw-r--r--lib/dpif.h9
6 files changed, 62 insertions, 0 deletions
diff --git a/lib/dpctl.c b/lib/dpctl.c
index 1ba1a9632..29041fa3e 100644
--- a/lib/dpctl.c
+++ b/lib/dpctl.c
@@ -1583,6 +1583,40 @@ dpctl_del_flows(int argc, const char *argv[], struct dpctl_params *dpctl_p)
}
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)
{
@@ -2824,6 +2858,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 5673407e6..bcd52f8c1 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -9142,6 +9142,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 */
NULL, /* number_handlers_required */
diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
index 08b6d7b0c..71e35ccdd 100644
--- a/lib/dpif-netlink.c
+++ b/lib/dpif-netlink.c
@@ -4444,6 +4444,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,
dpif_netlink_number_handlers_required,
diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h
index 27e3a7658..12477a24f 100644
--- a/lib/dpif-provider.h
+++ b/lib/dpif-provider.h
@@ -331,6 +331,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 e6125533f..40f5fe446 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -1432,6 +1432,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 8febfb9f6..6cb4dae6d 100644
--- a/lib/dpif.h
+++ b/lib/dpif.h
@@ -789,6 +789,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. */