aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Machata <petrm@nvidia.com>2024-03-14 15:52:14 +0100
committerDavid Ahern <dsahern@kernel.org>2024-03-15 15:03:34 +0000
commita50655e730ff28102e4e28bd54e2f12c381e5f1d (patch)
treeff8ed72a3498aea63afb4a2c3d5de17c2b0e862a
parent529ada74c401f0f80adcba12dfc023bf84eedc82 (diff)
downloadiproute2-next-a50655e730ff28102e4e28bd54e2f12c381e5f1d.tar.gz
ip: ipnexthop: Support dumping next hop group HW stats
Besides SW datapath stats, the kernel also support collecting statistics from HW datapath, for nexthop groups offloaded to HW. Request that these be collected when ip is given "-s -s", similarly to how "ip link" shows more statistics in that case. Besides the statistics themselves, also show whether the collection of HW statistics was in fact requested, and whether any driver actually implemented the request. Signed-off-by: Petr Machata <petrm@nvidia.com> Signed-off-by: David Ahern <dsahern@kernel.org>
-rw-r--r--ip/ipnexthop.c28
-rw-r--r--ip/nh_common.h5
2 files changed, 33 insertions, 0 deletions
diff --git a/ip/ipnexthop.c b/ip/ipnexthop.c
index cba3d934e..6c5d524b1 100644
--- a/ip/ipnexthop.c
+++ b/ip/ipnexthop.c
@@ -327,6 +327,11 @@ static void parse_nh_group_stats_rta(const struct rtattr *grp_stats_attr,
rta = tb[NHA_GROUP_STATS_ENTRY_PACKETS];
nh_grp_stats->packets = rta_getattr_uint(rta);
}
+
+ if (tb[NHA_GROUP_STATS_ENTRY_PACKETS_HW]) {
+ rta = tb[NHA_GROUP_STATS_ENTRY_PACKETS_HW];
+ nh_grp_stats->packets_hw = rta_getattr_uint(rta);
+ }
}
}
@@ -395,6 +400,9 @@ static void print_nh_grp_stats(const struct nh_entry *nhe)
nhe->nh_grp_stats[i].nh_id);
print_u64(PRINT_ANY, "packets", " packets %llu",
nhe->nh_grp_stats[i].packets);
+ if (show_stats > 1)
+ print_u64(PRINT_ANY, "packets_hw", " packets_hw %llu",
+ nhe->nh_grp_stats[i].packets_hw);
if (i != nhe->nh_groups_cnt - 1)
print_nl();
@@ -479,6 +487,15 @@ static int ipnh_parse_nhmsg(FILE *fp, const struct nhmsg *nhm, int len,
nhe->nh_has_res_grp = true;
}
+ if (tb[NHA_HW_STATS_ENABLE]) {
+ nhe->nh_hw_stats_supported = true;
+ nhe->nh_hw_stats_enabled =
+ !!rta_getattr_u32(tb[NHA_HW_STATS_ENABLE]);
+ }
+
+ if (tb[NHA_HW_STATS_USED])
+ nhe->nh_hw_stats_used = !!rta_getattr_u32(tb[NHA_HW_STATS_USED]);
+
if (tb[NHA_GROUP_STATS]) {
nhe->nh_grp_stats = calloc(nhe->nh_groups_cnt,
sizeof(*nhe->nh_grp_stats));
@@ -555,6 +572,15 @@ static void __print_nexthop_entry(FILE *fp, const char *jsobj,
if (nhe->nh_fdb)
print_null(PRINT_ANY, "fdb", "fdb", NULL);
+ if ((show_details > 0 || show_stats) && nhe->nh_hw_stats_supported) {
+ open_json_object("hw_stats");
+ print_on_off(PRINT_ANY, "enabled", "hw_stats %s ",
+ nhe->nh_hw_stats_enabled);
+ print_on_off(PRINT_ANY, "used", "used %s ",
+ nhe->nh_hw_stats_used);
+ close_json_object();
+ }
+
if (nhe->nh_grp_stats)
print_nh_grp_stats(nhe);
@@ -567,6 +593,8 @@ static __u32 ipnh_get_op_flags(void)
if (show_stats) {
op_flags |= NHA_OP_FLAG_DUMP_STATS;
+ if (show_stats > 1)
+ op_flags |= NHA_OP_FLAG_DUMP_HW_STATS;
}
return op_flags;
diff --git a/ip/nh_common.h b/ip/nh_common.h
index e2f74ec5a..33b1d8474 100644
--- a/ip/nh_common.h
+++ b/ip/nh_common.h
@@ -16,6 +16,7 @@ struct nha_res_grp {
struct nh_grp_stats {
__u32 nh_id;
__u64 packets;
+ __u64 packets_hw;
};
struct nh_entry {
@@ -32,6 +33,10 @@ struct nh_entry {
bool nh_blackhole;
bool nh_fdb;
+ bool nh_hw_stats_supported;
+ bool nh_hw_stats_enabled;
+ bool nh_hw_stats_used;
+
int nh_gateway_len;
union {
__be32 ipv4;