diff mbox series

[RFC,12/14] net: hstats: add markers for partial groups

Message ID 20190128234507.32028-13-jakub.kicinski@netronome.com
State RFC
Delegated to: David Miller
Headers show
Series netlink/hierarchical stats | expand

Commit Message

Jakub Kicinski Jan. 28, 2019, 11:45 p.m. UTC
Hstats try to be hierarchy-neutral to the consumer, i.e. if users
only care about total statistics they should be able to add given
statistic throughout the hierarchy.  Events can't be counted
multiple times (inside one root group, that's why multiple are
allowed), and they can't be missing.

Sometimes, however, HW doesn't give use enough information, or
software may not see all events it wants to count.  Add an attribute
to indicate to user space that given statistic group does not report
all events reliably.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
 include/net/hstats.h         |  2 ++
 include/uapi/linux/if_link.h |  9 +++++++++
 net/core/hstats.c            | 17 +++++++++++++++++
 3 files changed, 28 insertions(+)
diff mbox series

Patch

diff --git a/include/net/hstats.h b/include/net/hstats.h
index dd6d5dc567cb..3e10694d3d66 100644
--- a/include/net/hstats.h
+++ b/include/net/hstats.h
@@ -45,6 +45,7 @@  struct rtnl_hstat_qualifier {
  * struct rtnl_hstat_group - node in the hstat hierarchy
  * @qualifiers:	attributes describing this group
  * @has_children: @children array is present and NULL-terminated
+ * @partial_flags: partial flags
  * @stats_cnt:	number of stats in the bitmask
  * @stats:	bitmask of stats present
  * @get_stats:	driver callback for dumping the stats
@@ -54,6 +55,7 @@  struct rtnl_hstat_qualifier {
 struct rtnl_hstat_group {
 	/* Note: this is *not* indexed with IFLA_* attributes! */
 	struct rtnl_hstat_qualifier qualifiers[RTNL_HSTATS_QUAL_CNT];
+	u8 partial_flags;
 	bool has_children;
 	/* Can't use bitmaps - words are variable length */
 	unsigned int stats_cnt;
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index c58468100a06..28ac4574bb0e 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -946,6 +946,7 @@  enum {
 	IFLA_HSTATS_UNSPEC,
 	IFLA_HSTATS_GROUP,
 	IFLA_HSTATS_STATS,
+	IFLA_HSTATS_PARTIAL,
 	IFLA_HSTATS_QUAL_TYPE,
 	IFLA_HSTATS_QUAL_DIRECTION,
 	IFLA_HSTATS_QUAL_QUEUE,
@@ -955,6 +956,14 @@  enum {
 };
 #define IFLA_HSTATS_MAX (__IFLA_HSTATS_MAX - 1)
 
+enum {
+	IFLA_HSTATS_PARTIAL_UNSPEC,
+	IFLA_HSTATS_PARTIAL_CLASSIFIER = 1,
+	IFLA_HSTATS_PARTIAL_SLOWPATH = 2,
+	__IFLA_HSTATS_PARTIAL_MAX,
+};
+#define IFLA_HSTATS_PARTIAL_MAX (__IFLA_HSTATS_PARTIAL_MAX - 1)
+
 enum {
 	IFLA_HSTATS_QUAL_TYPE_UNSPEC,
 	IFLA_HSTATS_QUAL_TYPE_DEV,
diff --git a/net/core/hstats.c b/net/core/hstats.c
index c689ebfdaeaa..c9b7264d98dc 100644
--- a/net/core/hstats.c
+++ b/net/core/hstats.c
@@ -358,6 +358,17 @@  hstat_dumper_put_qual(struct hstat_dumper *dumper, int i, u32 val)
 	return nla_put_u32(dumper->skb, rtnl_qual2ifla[i], val);
 }
 
+static int
+hstat_dumper_put_partials(struct hstat_dumper *dumper, u32 val)
+{
+	if (dumper->sizing) {
+		dumper->size += nla_total_size(sizeof(u32));
+		return 0;
+	}
+
+	return nla_put_u32(dumper->skb, IFLA_HSTATS_PARTIAL, val);
+}
+
 /* Dumper handlers */
 static int hstat_dumper_grp_load(struct hstat_dumper *dumper)
 {
@@ -378,6 +389,12 @@  static int hstat_dumper_grp_load(struct hstat_dumper *dumper)
 	if (err)
 		return err;
 
+	if (cmd.grp->partial_flags) {
+		err = hstat_dumper_put_partials(dumper, cmd.grp->partial_flags);
+		if (err)
+			return err;
+	}
+
 	for (i = 0; i < RTNL_HSTATS_QUAL_CNT; i++) {
 		const struct rtnl_hstat_qualifier *q;