Blame SOURCES/0033-pause-add-support-for-dumping-statistics.patch

6975f2
From dd5f8a5e8a13ce389269d6be24ba17a903dc6fd9 Mon Sep 17 00:00:00 2001
6975f2
From: Jakub Kicinski <kuba@kernel.org>
6975f2
Date: Sun, 18 Oct 2020 14:31:51 -0700
6975f2
Subject: [PATCH 33/37] pause: add support for dumping statistics
6975f2
6975f2
Add support for requesting pause frame stats from the kernel.
6975f2
6975f2
 # ./ethtool -I -a eth0
6975f2
Pause parameters for eth0:
6975f2
Autonegotiate:	on
6975f2
RX:		on
6975f2
TX:		on
6975f2
Statistics:
6975f2
  tx_pause_frames: 1
6975f2
  rx_pause_frames: 1
6975f2
6975f2
 # ./ethtool -I --json -a eth0
6975f2
[ {
6975f2
        "ifname": "eth0",
6975f2
        "autonegotiate": true,
6975f2
        "rx": true,
6975f2
        "tx": true,
6975f2
        "statistics": {
6975f2
            "tx_pause_frames": 1,
6975f2
            "rx_pause_frames": 1
6975f2
        }
6975f2
    } ]
6975f2
6975f2
v2: - correct print format for u64
6975f2
6975f2
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
6975f2
Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
6975f2
(cherry picked from commit 1166ed2fbc603e739759961a77c7ecb5cf2d5443)
6975f2
---
6975f2
 netlink/pause.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++-
6975f2
 1 file changed, 66 insertions(+), 1 deletion(-)
6975f2
6975f2
diff --git a/netlink/pause.c b/netlink/pause.c
6975f2
index c54488d71fce..867d0da71f72 100644
6975f2
--- a/netlink/pause.c
6975f2
+++ b/netlink/pause.c
6975f2
@@ -5,6 +5,7 @@
6975f2
  */
6975f2
 
6975f2
 #include <errno.h>
6975f2
+#include <inttypes.h>
6975f2
 #include <string.h>
6975f2
 #include <stdio.h>
6975f2
 
6975f2
@@ -105,6 +106,62 @@ out:
6975f2
 	return ret;
6975f2
 }
6975f2
 
6975f2
+static int show_pause_stats(const struct nlattr *nest)
6975f2
+{
6975f2
+	const struct nlattr *tb[ETHTOOL_A_PAUSE_STAT_MAX + 1] = {};
6975f2
+	DECLARE_ATTR_TB_INFO(tb);
6975f2
+	static const struct {
6975f2
+		unsigned int attr;
6975f2
+		char *name;
6975f2
+	} stats[] = {
6975f2
+		{ ETHTOOL_A_PAUSE_STAT_TX_FRAMES, "tx_pause_frames" },
6975f2
+		{ ETHTOOL_A_PAUSE_STAT_RX_FRAMES, "rx_pause_frames" },
6975f2
+	};
6975f2
+	bool header = false;
6975f2
+	unsigned int i;
6975f2
+	size_t n;
6975f2
+	int ret;
6975f2
+
6975f2
+	ret = mnl_attr_parse_nested(nest, attr_cb, &tb_info);
6975f2
+	if (ret < 0)
6975f2
+		return ret;
6975f2
+
6975f2
+	open_json_object("statistics");
6975f2
+	for (i = 0; i < ARRAY_SIZE(stats); i++) {
6975f2
+		char fmt[32];
6975f2
+
6975f2
+		if (!tb[stats[i].attr])
6975f2
+			continue;
6975f2
+
6975f2
+		if (!header && !is_json_context()) {
6975f2
+			printf("Statistics:\n");
6975f2
+			header = true;
6975f2
+		}
6975f2
+
6975f2
+		if (mnl_attr_validate(tb[stats[i].attr], MNL_TYPE_U64)) {
6975f2
+			fprintf(stderr, "malformed netlink message (statistic)\n");
6975f2
+			goto err_close_stats;
6975f2
+		}
6975f2
+
6975f2
+		n = snprintf(fmt, sizeof(fmt), "  %s: %%" PRIu64 "\n",
6975f2
+			     stats[i].name);
6975f2
+		if (n >= sizeof(fmt)) {
6975f2
+			fprintf(stderr, "internal error - malformed label\n");
6975f2
+			goto err_close_stats;
6975f2
+		}
6975f2
+
6975f2
+		print_u64(PRINT_ANY, stats[i].name, fmt,
6975f2
+			  mnl_attr_get_u64(tb[stats[i].attr]));
6975f2
+	}
6975f2
+	close_json_object();
6975f2
+
6975f2
+	return 0;
6975f2
+
6975f2
+err_close_stats:
6975f2
+	close_json_object();
6975f2
+	return -1;
6975f2
+}
6975f2
+
6975f2
 int pause_reply_cb(const struct nlmsghdr *nlhdr, void *data)
6975f2
 {
6975f2
 	const struct nlattr *tb[ETHTOOL_A_PAUSE_MAX + 1] = {};
6975f2
@@ -142,6 +199,11 @@ int pause_reply_cb(const struct nlmsghdr *nlhdr, void *data)
6975f2
 		if (ret < 0)
6975f2
 			goto err_close_dev;
6975f2
 	}
6975f2
+	if (tb[ETHTOOL_A_PAUSE_STATS]) {
6975f2
+		ret = show_pause_stats(tb[ETHTOOL_A_PAUSE_STATS]);
6975f2
+		if (ret < 0)
6975f2
+			goto err_close_dev;
6975f2
+	}
6975f2
 	if (!silent)
6975f2
 		print_nl();
6975f2
 
6975f2
@@ -158,6 +220,7 @@ int nl_gpause(struct cmd_context *ctx)
6975f2
 {
6975f2
 	struct nl_context *nlctx = ctx->nlctx;
6975f2
 	struct nl_socket *nlsk = nlctx->ethnl_socket;
6975f2
+	u32 flags;
6975f2
 	int ret;
6975f2
 
6975f2
 	if (netlink_cmd_check(ctx, ETHTOOL_MSG_PAUSE_GET, true))
6975f2
@@ -168,8 +231,10 @@ int nl_gpause(struct cmd_context *ctx)
6975f2
 		return 1;
6975f2
 	}
6975f2
 
6975f2
+	flags = get_stats_flag(nlctx, ETHTOOL_MSG_PAUSE_GET,
6975f2
+			       ETHTOOL_A_PAUSE_HEADER);
6975f2
 	ret = nlsock_prep_get_request(nlsk, ETHTOOL_MSG_PAUSE_GET,
6975f2
-				      ETHTOOL_A_PAUSE_HEADER, 0);
6975f2
+				      ETHTOOL_A_PAUSE_HEADER, flags);
6975f2
 	if (ret < 0)
6975f2
 		return ret;
6975f2
 
6975f2
-- 
6975f2
2.26.2
6975f2