diff mbox series

[RFC,net-next,3/7] net: ethtool: stats: make stats_put_stats() take input from multiple sources

Message ID 20220816222920.1952936-4-vladimir.oltean@nxp.com (mailing list archive)
State RFC
Delegated to: Netdev Maintainers
Headers show
Series 802.1Q Frame Preemption and 802.3 MAC Merge support via ethtool | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 342 this patch: 342
netdev/cc_maintainers warning 1 maintainers not CCed: keescook@chromium.org
netdev/build_clang success Errors and warnings before: 5 this patch: 5
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 342 this patch: 342
netdev/checkpatch warning WARNING: 'preemptable' may be misspelled - perhaps 'preemptible'? WARNING: line length of 83 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Vladimir Oltean Aug. 16, 2022, 10:29 p.m. UTC
IEEE 802.3 defines a MAC merge layer, for supporting the 802.1Q Frame
Preemption capability. Beyond the MAC merge layer there are 2 distinct
MACs, one is for express traffic (eMAC, aka the good old MAC that the
Linux network stack knows about) and the other is for preemptable
traffic (pMAC).

The pMAC is a MAC in its own right, and has a full set of statistics
that can be exposed through the standardized ethtool counters (RMON,
802.3 etc).

In preparation for extending struct stats_reply_data to store both the
eMAC and the pMAC stats structures, modify stats_put_stats() to not
assume that we only care about the eMAC stats. Instead, we will
introduce separate ops for pMAC stats, and put those stats into separate
netlink attributes, and take them from different instances of the same
structure types as in the case of the eMAC.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 net/ethtool/stats.c | 148 +++++++++++++++++++++++++-------------------
 1 file changed, 86 insertions(+), 62 deletions(-)
diff mbox series

Patch

diff --git a/net/ethtool/stats.c b/net/ethtool/stats.c
index a20e0a24ff61..8d4d3c70c0a4 100644
--- a/net/ethtool/stats.c
+++ b/net/ethtool/stats.c
@@ -9,6 +9,11 @@  struct stats_req_info {
 	DECLARE_BITMAP(stat_mask, __ETHTOOL_STATS_CNT);
 };
 
+struct rmon_stats_put_ctx {
+	const struct ethtool_rmon_stats *rmon_stats;
+	const struct ethtool_rmon_hist_range *rmon_ranges;
+};
+
 #define STATS_REQINFO(__req_base) \
 	container_of(__req_base, struct stats_req_info, base)
 
@@ -110,8 +115,11 @@  static int stats_prepare_data(const struct ethnl_req_info *req_base,
 	const struct stats_req_info *req_info = STATS_REQINFO(req_base);
 	struct stats_reply_data *data = STATS_REPDATA(reply_base);
 	struct net_device *dev = reply_base->dev;
+	const struct ethtool_ops *ops;
 	int ret;
 
+	ops = dev->ethtool_ops;
+
 	ret = ethnl_ops_begin(dev);
 	if (ret < 0)
 		return ret;
@@ -122,18 +130,18 @@  static int stats_prepare_data(const struct ethnl_req_info *req_base,
 	memset(&data->stats, 0xff, sizeof(data->stats));
 
 	if (test_bit(ETHTOOL_STATS_ETH_PHY, req_info->stat_mask) &&
-	    dev->ethtool_ops->get_eth_phy_stats)
-		dev->ethtool_ops->get_eth_phy_stats(dev, &data->phy_stats);
+	    ops->get_eth_phy_stats)
+		ops->get_eth_phy_stats(dev, &data->phy_stats);
 	if (test_bit(ETHTOOL_STATS_ETH_MAC, req_info->stat_mask) &&
-	    dev->ethtool_ops->get_eth_mac_stats)
-		dev->ethtool_ops->get_eth_mac_stats(dev, &data->mac_stats);
+	    ops->get_eth_mac_stats)
+		ops->get_eth_mac_stats(dev, &data->mac_stats);
 	if (test_bit(ETHTOOL_STATS_ETH_CTRL, req_info->stat_mask) &&
-	    dev->ethtool_ops->get_eth_ctrl_stats)
-		dev->ethtool_ops->get_eth_ctrl_stats(dev, &data->ctrl_stats);
+	    ops->get_eth_ctrl_stats)
+		ops->get_eth_ctrl_stats(dev, &data->ctrl_stats);
 	if (test_bit(ETHTOOL_STATS_RMON, req_info->stat_mask) &&
-	    dev->ethtool_ops->get_rmon_stats)
-		dev->ethtool_ops->get_rmon_stats(dev, &data->rmon_stats,
-						 &data->rmon_ranges);
+	    ops->get_rmon_stats)
+		ops->get_rmon_stats(dev, &data->rmon_stats,
+				    &data->rmon_ranges);
 
 	ethnl_ops_complete(dev);
 	return 0;
@@ -212,76 +220,82 @@  static int stat_put(struct sk_buff *skb, u16 attrtype, u64 val)
 	return 0;
 }
 
-static int stats_put_phy_stats(struct sk_buff *skb,
-			       const struct stats_reply_data *data)
+static int stats_put_phy_stats(struct sk_buff *skb, const void *src)
 {
+	const struct ethtool_eth_phy_stats *phy_stats = src;
+
 	if (stat_put(skb, ETHTOOL_A_STATS_ETH_PHY_5_SYM_ERR,
-		     data->phy_stats.SymbolErrorDuringCarrier))
+		     phy_stats->SymbolErrorDuringCarrier))
 		return -EMSGSIZE;
+
 	return 0;
 }
 
-static int stats_put_mac_stats(struct sk_buff *skb,
-			       const struct stats_reply_data *data)
+static int stats_put_mac_stats(struct sk_buff *skb, const void *src)
 {
+	const struct ethtool_eth_mac_stats *mac_stats = src;
+
 	if (stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_2_TX_PKT,
-		     data->mac_stats.FramesTransmittedOK) ||
+		     mac_stats->FramesTransmittedOK) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_3_SINGLE_COL,
-		     data->mac_stats.SingleCollisionFrames) ||
+		     mac_stats->SingleCollisionFrames) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_4_MULTI_COL,
-		     data->mac_stats.MultipleCollisionFrames) ||
+		     mac_stats->MultipleCollisionFrames) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_5_RX_PKT,
-		     data->mac_stats.FramesReceivedOK) ||
+		     mac_stats->FramesReceivedOK) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_6_FCS_ERR,
-		     data->mac_stats.FrameCheckSequenceErrors) ||
+		     mac_stats->FrameCheckSequenceErrors) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_7_ALIGN_ERR,
-		     data->mac_stats.AlignmentErrors) ||
+		     mac_stats->AlignmentErrors) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_8_TX_BYTES,
-		     data->mac_stats.OctetsTransmittedOK) ||
+		     mac_stats->OctetsTransmittedOK) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_9_TX_DEFER,
-		     data->mac_stats.FramesWithDeferredXmissions) ||
+		     mac_stats->FramesWithDeferredXmissions) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_10_LATE_COL,
-		     data->mac_stats.LateCollisions) ||
+		     mac_stats->LateCollisions) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_11_XS_COL,
-		     data->mac_stats.FramesAbortedDueToXSColls) ||
+		     mac_stats->FramesAbortedDueToXSColls) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_12_TX_INT_ERR,
-		     data->mac_stats.FramesLostDueToIntMACXmitError) ||
+		     mac_stats->FramesLostDueToIntMACXmitError) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_13_CS_ERR,
-		     data->mac_stats.CarrierSenseErrors) ||
+		     mac_stats->CarrierSenseErrors) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_14_RX_BYTES,
-		     data->mac_stats.OctetsReceivedOK) ||
+		     mac_stats->OctetsReceivedOK) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_15_RX_INT_ERR,
-		     data->mac_stats.FramesLostDueToIntMACRcvError) ||
+		     mac_stats->FramesLostDueToIntMACRcvError) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_18_TX_MCAST,
-		     data->mac_stats.MulticastFramesXmittedOK) ||
+		     mac_stats->MulticastFramesXmittedOK) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_19_TX_BCAST,
-		     data->mac_stats.BroadcastFramesXmittedOK) ||
+		     mac_stats->BroadcastFramesXmittedOK) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_20_XS_DEFER,
-		     data->mac_stats.FramesWithExcessiveDeferral) ||
+		     mac_stats->FramesWithExcessiveDeferral) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_21_RX_MCAST,
-		     data->mac_stats.MulticastFramesReceivedOK) ||
+		     mac_stats->MulticastFramesReceivedOK) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_22_RX_BCAST,
-		     data->mac_stats.BroadcastFramesReceivedOK) ||
+		     mac_stats->BroadcastFramesReceivedOK) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_23_IR_LEN_ERR,
-		     data->mac_stats.InRangeLengthErrors) ||
+		     mac_stats->InRangeLengthErrors) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_24_OOR_LEN,
-		     data->mac_stats.OutOfRangeLengthField) ||
+		     mac_stats->OutOfRangeLengthField) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_MAC_25_TOO_LONG_ERR,
-		     data->mac_stats.FrameTooLongErrors))
+		     mac_stats->FrameTooLongErrors))
 		return -EMSGSIZE;
+
 	return 0;
 }
 
-static int stats_put_ctrl_stats(struct sk_buff *skb,
-				const struct stats_reply_data *data)
+static int stats_put_ctrl_stats(struct sk_buff *skb, const void *src)
 {
+	const struct ethtool_eth_ctrl_stats *ctrl_stats = src;
+
 	if (stat_put(skb, ETHTOOL_A_STATS_ETH_CTRL_3_TX,
-		     data->ctrl_stats.MACControlFramesTransmitted) ||
+		     ctrl_stats->MACControlFramesTransmitted) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_CTRL_4_RX,
-		     data->ctrl_stats.MACControlFramesReceived) ||
+		     ctrl_stats->MACControlFramesReceived) ||
 	    stat_put(skb, ETHTOOL_A_STATS_ETH_CTRL_5_RX_UNSUP,
-		     data->ctrl_stats.UnsupportedOpcodesReceived))
+		     ctrl_stats->UnsupportedOpcodesReceived))
 		return -EMSGSIZE;
+
 	return 0;
 }
 
@@ -322,33 +336,34 @@  static int stats_put_rmon_hist(struct sk_buff *skb, u32 attr, const u64 *hist,
 	return -EMSGSIZE;
 }
 
-static int stats_put_rmon_stats(struct sk_buff *skb,
-				const struct stats_reply_data *data)
+static int stats_put_rmon_stats(struct sk_buff *skb, const void *src)
 {
+	const struct ethtool_rmon_hist_range *rmon_ranges;
+	const struct ethtool_rmon_stats *rmon_stats;
+	const struct rmon_stats_put_ctx *ctx = src;
+
+	rmon_stats = ctx->rmon_stats;
+	rmon_ranges = ctx->rmon_ranges;
+
 	if (stats_put_rmon_hist(skb, ETHTOOL_A_STATS_GRP_HIST_RX,
-				data->rmon_stats.hist, data->rmon_ranges) ||
+				rmon_stats->hist, rmon_ranges) ||
 	    stats_put_rmon_hist(skb, ETHTOOL_A_STATS_GRP_HIST_TX,
-				data->rmon_stats.hist_tx, data->rmon_ranges))
+				rmon_stats->hist_tx, rmon_ranges))
 		return -EMSGSIZE;
 
 	if (stat_put(skb, ETHTOOL_A_STATS_RMON_UNDERSIZE,
-		     data->rmon_stats.undersize_pkts) ||
+		     rmon_stats->undersize_pkts) ||
 	    stat_put(skb, ETHTOOL_A_STATS_RMON_OVERSIZE,
-		     data->rmon_stats.oversize_pkts) ||
-	    stat_put(skb, ETHTOOL_A_STATS_RMON_FRAG,
-		     data->rmon_stats.fragments) ||
-	    stat_put(skb, ETHTOOL_A_STATS_RMON_JABBER,
-		     data->rmon_stats.jabbers))
+		     rmon_stats->oversize_pkts) ||
+	    stat_put(skb, ETHTOOL_A_STATS_RMON_FRAG, rmon_stats->fragments) ||
+	    stat_put(skb, ETHTOOL_A_STATS_RMON_JABBER, rmon_stats->jabbers))
 		return -EMSGSIZE;
 
 	return 0;
 }
 
-static int stats_put_stats(struct sk_buff *skb,
-			   const struct stats_reply_data *data,
-			   u32 id, u32 ss_id,
-			   int (*cb)(struct sk_buff *skb,
-				     const struct stats_reply_data *data))
+static int stats_put_stats(struct sk_buff *skb, const void *src, u32 id, u32 ss_id,
+			   int (*cb)(struct sk_buff *skb, const void *src))
 {
 	struct nlattr *nest;
 
@@ -360,7 +375,7 @@  static int stats_put_stats(struct sk_buff *skb,
 	    nla_put_u32(skb, ETHTOOL_A_STATS_GRP_SS_ID, ss_id))
 		goto err_cancel;
 
-	if (cb(skb, data))
+	if (cb(skb, src))
 		goto err_cancel;
 
 	nla_nest_end(skb, nest);
@@ -380,20 +395,29 @@  static int stats_fill_reply(struct sk_buff *skb,
 	int ret = 0;
 
 	if (!ret && test_bit(ETHTOOL_STATS_ETH_PHY, req_info->stat_mask))
-		ret = stats_put_stats(skb, data, ETHTOOL_STATS_ETH_PHY,
+		ret = stats_put_stats(skb, &data->phy_stats,
+				      ETHTOOL_STATS_ETH_PHY,
 				      ETH_SS_STATS_ETH_PHY,
 				      stats_put_phy_stats);
 	if (!ret && test_bit(ETHTOOL_STATS_ETH_MAC, req_info->stat_mask))
-		ret = stats_put_stats(skb, data, ETHTOOL_STATS_ETH_MAC,
+		ret = stats_put_stats(skb, &data->mac_stats,
+				      ETHTOOL_STATS_ETH_MAC,
 				      ETH_SS_STATS_ETH_MAC,
 				      stats_put_mac_stats);
 	if (!ret && test_bit(ETHTOOL_STATS_ETH_CTRL, req_info->stat_mask))
-		ret = stats_put_stats(skb, data, ETHTOOL_STATS_ETH_CTRL,
+		ret = stats_put_stats(skb, &data->ctrl_stats,
+				      ETHTOOL_STATS_ETH_CTRL,
 				      ETH_SS_STATS_ETH_CTRL,
 				      stats_put_ctrl_stats);
-	if (!ret && test_bit(ETHTOOL_STATS_RMON, req_info->stat_mask))
-		ret = stats_put_stats(skb, data, ETHTOOL_STATS_RMON,
+	if (!ret && test_bit(ETHTOOL_STATS_RMON, req_info->stat_mask)) {
+		struct rmon_stats_put_ctx ctx = {
+			.rmon_stats = &data->rmon_stats,
+			.rmon_ranges = data->rmon_ranges,
+		};
+
+		ret = stats_put_stats(skb, &ctx, ETHTOOL_STATS_RMON,
 				      ETH_SS_STATS_RMON, stats_put_rmon_stats);
+	}
 
 	return ret;
 }