diff options
author | Gaetan Rivet <grive@u256.net> | 2021-09-08 11:47:31 +0200 |
---|---|---|
committer | Ilya Maximets <i.maximets@ovn.org> | 2022-01-18 15:12:01 +0100 |
commit | 9ab104718bcb00b0ac6fd33e4434763a5e00013d (patch) | |
tree | fd8a82daa7d2374aec0d3b114f9b3bf1182d7a88 | |
parent | 0e6366c2399d970def5bdc7f489f4f9e0f32aa47 (diff) | |
download | openvswitch-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.c | 36 | ||||
-rw-r--r-- | lib/dpif-netdev.c | 1 | ||||
-rw-r--r-- | lib/dpif-netlink.c | 1 | ||||
-rw-r--r-- | lib/dpif-provider.h | 7 | ||||
-rw-r--r-- | lib/dpif.c | 8 | ||||
-rw-r--r-- | lib/dpif.h | 9 |
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. */ |