lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Mon, 28 Jan 2019 15:45:04 -0800
From:   Jakub Kicinski <jakub.kicinski@...ronome.com>
To:     davem@...emloft.net
Cc:     oss-drivers@...ronome.com, netdev@...r.kernel.org,
        jiri@...nulli.us, f.fainelli@...il.com, andrew@...n.ch,
        mkubecek@...e.cz, dsahern@...il.com, simon.horman@...ronome.com,
        jesse.brandeburg@...el.com, maciejromanfijalkowski@...il.com,
        vasundhara-v.volam@...adcom.com, michael.chan@...adcom.com,
        shalomt@...lanox.com, idosch@...lanox.com,
        Jakub Kicinski <jakub.kicinski@...ronome.com>
Subject: [RFC 11/14] nfp: hstats: add IEEE/RMON ethernet port/MAC stats

Add groups for MAC statistics, NFP's MAC/PHY maintains a mix
of IEEE 802.3 and RMON-compatible statistics.  Use the RMON
stats for driver drops and error counters as well.

Since the MAC stats are quite large initialize the hstat
bitmap when driver is loaded.

Signed-off-by: Jakub Kicinski <jakub.kicinski@...ronome.com>
---
 .../net/ethernet/netronome/nfp/nfp_hstat.c    | 257 +++++++++++++++++-
 drivers/net/ethernet/netronome/nfp/nfp_main.c |   1 +
 drivers/net/ethernet/netronome/nfp/nfp_main.h |   2 +
 3 files changed, 257 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_hstat.c b/drivers/net/ethernet/netronome/nfp/nfp_hstat.c
index 9300996e756c..cd97cd2676f6 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_hstat.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_hstat.c
@@ -4,6 +4,217 @@
 #include <net/hstats.h>
 
 #include "nfp_net.h"
+#include "nfp_port.h"
+
+/* MAC stats */
+static const struct nfp_stat_pair {
+	u32 attr;
+	u32 offset;
+} nfp_mac_stats_rx[] = {
+	{
+		IFLA_HSTATS_STAT_RFC2819_etherStatsOctets,
+		NFP_MAC_STATS_RX_IN_OCTETS
+	}, {
+		IFLA_HSTATS_STAT_IEEE8023_FrameTooLongErrors,
+		NFP_MAC_STATS_RX_FRAME_TOO_LONG_ERRORS
+	}, {
+		IFLA_HSTATS_STAT_IEEE8023_InRangeLengthErrors,
+		NFP_MAC_STATS_RX_RANGE_LENGTH_ERRORS
+	},
+	/* missing NFP_MAC_STATS_RX_VLAN_RECEIVED_OK, no standard counter */
+	{
+		IFLA_HSTATS_STAT_RFC2863_Errors,
+		NFP_MAC_STATS_RX_IN_ERRORS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsBroadcastPkts,
+		NFP_MAC_STATS_RX_IN_BROADCAST_PKTS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsDropEvents,
+		NFP_MAC_STATS_RX_DROP_EVENTS
+	}, {
+		IFLA_HSTATS_STAT_IEEE8023_AlignmentErrors,
+		NFP_MAC_STATS_RX_ALIGNMENT_ERRORS
+	}, {
+		IFLA_HSTATS_STAT_IEEE8023_PAUSEMACCtrlFrames,
+		NFP_MAC_STATS_RX_PAUSE_MAC_CTRL_FRAMES
+	}, {
+		IFLA_HSTATS_STAT_IEEE8023_FramesOK,
+		NFP_MAC_STATS_RX_FRAMES_RECEIVED_OK
+	}, {
+		IFLA_HSTATS_STAT_IEEE8023_FrameCheckSequenceErrors,
+		NFP_MAC_STATS_RX_FRAME_CHECK_SEQUENCE_ERRORS
+	}, {
+		IFLA_HSTATS_STAT_RFC2863_UcastPkts,
+		NFP_MAC_STATS_RX_UNICAST_PKTS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsMulticastPkts,
+		NFP_MAC_STATS_RX_MULTICAST_PKTS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsPkts,
+		NFP_MAC_STATS_RX_PKTS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsUndersizePkts,
+		NFP_MAC_STATS_RX_UNDERSIZE_PKTS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsPkts64Octets,
+		NFP_MAC_STATS_RX_PKTS_64_OCTETS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsPkts65to127Octets,
+		NFP_MAC_STATS_RX_PKTS_65_TO_127_OCTETS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsPkts512to1023Octets,
+		NFP_MAC_STATS_RX_PKTS_512_TO_1023_OCTETS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsPkts1024to1518Octets,
+		NFP_MAC_STATS_RX_PKTS_1024_TO_1518_OCTETS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsJabbers,
+		NFP_MAC_STATS_RX_JABBERS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsFragments,
+		NFP_MAC_STATS_RX_FRAGMENTS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsPkts128to255Octets,
+		NFP_MAC_STATS_RX_PKTS_128_TO_255_OCTETS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsPkts256to511Octets,
+		NFP_MAC_STATS_RX_PKTS_256_TO_511_OCTETS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819EXT_etherStatsPkts1519toMaxOctets,
+		NFP_MAC_STATS_RX_PKTS_1519_TO_MAX_OCTETS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsOversizePkts,
+		NFP_MAC_STATS_RX_OVERSIZE_PKTS
+	}, {
+		IFLA_HSTATS_STAT_IEEE8023_MACControlFrames,
+		NFP_MAC_STATS_RX_MAC_CTRL_FRAMES_RECEIVED
+	}
+}, nfp_mac_stats_tx[] = {
+	{
+		IFLA_HSTATS_STAT_RFC2819_etherStatsOctets,
+		NFP_MAC_STATS_TX_OUT_OCTETS
+	},
+	/* missing NFP_MAC_STATS_TX_VLAN_TRANSMITTED_OK, no standard counter */
+	{
+		IFLA_HSTATS_STAT_RFC2863_Errors,
+		NFP_MAC_STATS_TX_OUT_ERRORS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsBroadcastPkts,
+		NFP_MAC_STATS_TX_BROADCAST_PKTS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsPkts64Octets,
+		NFP_MAC_STATS_TX_PKTS_64_OCTETS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsPkts256to511Octets,
+		NFP_MAC_STATS_TX_PKTS_256_TO_511_OCTETS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsPkts512to1023Octets,
+		NFP_MAC_STATS_TX_PKTS_512_TO_1023_OCTETS
+	}, {
+		IFLA_HSTATS_STAT_IEEE8023_PAUSEMACCtrlFrames,
+		NFP_MAC_STATS_TX_PAUSE_MAC_CTRL_FRAMES
+	}, {
+		IFLA_HSTATS_STAT_IEEE8023_FramesOK,
+		NFP_MAC_STATS_TX_FRAMES_TRANSMITTED_OK
+	}, {
+		IFLA_HSTATS_STAT_RFC2863_UcastPkts,
+		NFP_MAC_STATS_TX_UNICAST_PKTS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsMulticastPkts,
+		NFP_MAC_STATS_TX_MULTICAST_PKTS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsPkts65to127Octets,
+		NFP_MAC_STATS_TX_PKTS_65_TO_127_OCTETS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsPkts128to255Octets,
+		NFP_MAC_STATS_TX_PKTS_128_TO_255_OCTETS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819_etherStatsPkts1024to1518Octets,
+		NFP_MAC_STATS_TX_PKTS_1024_TO_1518_OCTETS
+	}, {
+		IFLA_HSTATS_STAT_RFC2819EXT_etherStatsPkts1519toMaxOctets,
+		NFP_MAC_STATS_TX_PKTS_1519_TO_MAX_OCTETS
+	}
+};
+
+static int
+nfp_hstat_mac_get(struct net_device *netdev, struct rtnl_hstat_req *req,
+		  const struct rtnl_hstat_group *grp)
+{
+	const struct nfp_stat_pair *pairs;
+	struct nfp_port *port;
+	unsigned int dir, i;
+
+	port = nfp_port_from_netdev(netdev);
+	if (!__nfp_port_get_eth_port(port) || !port->eth_stats)
+		return -EINVAL;
+
+	dir = rtnl_hstat_qual_get(req, RTNL_HSTATS_QUAL_DIRECTION);
+	pairs = dir == IFLA_HSTATS_QUAL_DIR_RX ?
+		nfp_mac_stats_rx : nfp_mac_stats_tx;
+
+	for (i = 0; i < grp->stats_cnt; i++)
+		rtnl_hstat_dump(req, pairs[i].attr,
+				readq(port->eth_stats + pairs[i].offset));
+	return 0;
+}
+
+static struct rtnl_hstat_group nfp_hstat_mac_rx __ro_after_init = {
+	.qualifiers = {
+		RTNL_HSTATS_QUALS_BASIC(DEV, RX),
+	},
+
+	.get_stats = nfp_hstat_mac_get,
+};
+
+static struct rtnl_hstat_group nfp_hstat_mac_tx __ro_after_init = {
+	.qualifiers = {
+		RTNL_HSTATS_QUALS_BASIC(DEV, TX),
+	},
+
+	.get_stats = nfp_hstat_mac_get,
+};
+
+static const struct rtnl_hstat_group nfp_hstat_mac = {
+	.has_children = true,
+	.children = {
+		&nfp_hstat_mac_rx,
+		&nfp_hstat_mac_tx,
+		NULL,
+	},
+};
+
+static int
+nfp_hstat_mac_head_drop(struct net_device *netdev, struct rtnl_hstat_req *req,
+			const struct rtnl_hstat_group *grp)
+{
+	struct nfp_port *port;
+	unsigned int off, dir;
+
+	port = nfp_port_from_netdev(netdev);
+	if (!__nfp_port_get_eth_port(port) || !port->eth_stats)
+		return -EINVAL;
+
+	dir = rtnl_hstat_qual_get(req, RTNL_HSTATS_QUAL_DIRECTION);
+	off = dir == IFLA_HSTATS_QUAL_DIR_RX ?
+		NFP_MAC_STATS_RX_MAC_HEAD_DROP : NFP_MAC_STATS_TX_QUEUE_DROP;
+
+	rtnl_hstat_dump(req, IFLA_HSTATS_STAT_RFC2819_etherStatsDropEvents,
+			readq(port->eth_stats + off));
+	return 0;
+}
+
+static const struct rtnl_hstat_group nfp_hstat_tm = {
+	.qualifiers = {
+		RTNL_HSTATS_QUALS_BASIC_BIDIR(DEV),
+	},
+
+	.get_stats = nfp_hstat_mac_head_drop,
+	.stats	= {
+		[1] =	RTNL_HSTATS_STAT_RFC2819_etherStatsDropEvents_BIT,
+	},
+	.stats_cnt = 1,
+};
 
 /* NFD per-vNIC stats */
 static int
@@ -21,6 +232,10 @@ nfp_hstat_vnic_nfd_basic_get(struct net_device *netdev,
 			nn_readq(nn, NFP_NET_CFG_STATS_RX_FRAMES + off));
 	rtnl_hstat_dump(req, IFLA_HSTATS_STAT_LINUX_BYTES,
 			nn_readq(nn, NFP_NET_CFG_STATS_RX_OCTETS + off));
+	rtnl_hstat_dump(req, IFLA_HSTATS_STAT_RFC2863_Errors,
+			nn_readq(nn, NFP_NET_CFG_STATS_RX_ERRORS + off));
+	rtnl_hstat_dump(req, IFLA_HSTATS_STAT_RFC2863_Discards,
+			nn_readq(nn, NFP_NET_CFG_STATS_RX_DISCARDS + off));
 	return 0;
 }
 
@@ -33,8 +248,10 @@ static const struct rtnl_hstat_group nfp_hstat_vnic_nfd = {
 	.stats	= {
 		[0] =	RTNL_HSTATS_STAT_LINUX_PKTS_BIT |
 			RTNL_HSTATS_STAT_LINUX_BYTES_BIT,
+		[2] =	RTNL_HSTATS_STAT_RFC2863_Errors_BIT |
+			RTNL_HSTATS_STAT_RFC2863_Discards_BIT,
 	},
-	.stats_cnt = 2,
+	.stats_cnt = 4,
 };
 
 /* NFD per-Q stats */
@@ -99,6 +316,8 @@ nfp_hstat_vnic_sw_rx_get(struct net_device *dev, struct rtnl_hstat_req *req,
 			r_vec->hw_csum_rx_complete);
 	rtnl_hstat_dump(req, IFLA_HSTATS_STAT_LINUX_CSUM_UNNECESSARY,
 			r_vec->hw_csum_rx_ok + r_vec->hw_csum_rx_inner_ok);
+	rtnl_hstat_dump(req, IFLA_HSTATS_STAT_RFC2819_etherStatsDropEvents,
+			r_vec->rx_drops);
 	return 0;
 }
 
@@ -116,9 +335,10 @@ static const struct rtnl_hstat_group nfp_hstat_vnic_sw_rx = {
 			RTNL_HSTATS_STAT_LINUX_BYTES_BIT |
 			RTNL_HSTATS_STAT_LINUX_CSUM_PARTIAL_BIT |
 			RTNL_HSTATS_STAT_LINUX_CSUM_UNNECESSARY_BIT,
+		[1] =	RTNL_HSTATS_STAT_RFC2819_etherStatsDropEvents_BIT,
 
 	},
-	.stats_cnt = 4,
+	.stats_cnt = 5,
 };
 
 static int
@@ -137,6 +357,7 @@ nfp_hstat_vnic_sw_tx_get(struct net_device *dev, struct rtnl_hstat_req *req,
 			r_vec->hw_csum_tx + r_vec->hw_csum_tx_inner);
 	rtnl_hstat_dump(req, IFLA_HSTATS_STAT_LINUX_SEGMENTATION_OFFLOAD_PKTS,
 			r_vec->tx_lso);
+	rtnl_hstat_dump(req, IFLA_HSTATS_STAT_RFC2863_Errors, r_vec->tx_errors);
 	return 0;
 }
 
@@ -155,8 +376,9 @@ static const struct rtnl_hstat_group nfp_hstat_vnic_sw_tx = {
 			RTNL_HSTATS_STAT_LINUX_BUSY_BIT |
 			RTNL_HSTATS_STAT_LINUX_CSUM_PARTIAL_BIT |
 			RTNL_HSTATS_STAT_LINUX_SEGMENTATION_OFFLOAD_PKTS_BIT,
+		[1] =	RTNL_HSTATS_STAT_RFC2863_Errors_BIT,
 	},
-	.stats_cnt = 5,
+	.stats_cnt = 6,
 };
 
 static const struct rtnl_hstat_group nfp_hstat_vnic_sw = {
@@ -171,9 +393,38 @@ static const struct rtnl_hstat_group nfp_hstat_vnic_sw = {
 int nfp_net_hstat_get_groups(const struct net_device *netdev,
 			     struct rtnl_hstat_req *req)
 {
+	struct nfp_port *port;
+
 	rtnl_hstat_add_grp(req, &nfp_hstat_vnic_sw);
 	rtnl_hstat_add_grp(req, &nfp_hstat_vnic_nfd_pq);
 	rtnl_hstat_add_grp(req, &nfp_hstat_vnic_nfd);
 
+	port = nfp_port_from_netdev(netdev);
+	if (__nfp_port_get_eth_port(port) && port->eth_stats) {
+		rtnl_hstat_add_grp(req, &nfp_hstat_tm);
+		rtnl_hstat_add_grp(req, &nfp_hstat_mac);
+	}
+
 	return 0;
 }
+
+void __init nfp_net_hstat_init(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(nfp_mac_stats_rx); i++) {
+		unsigned int attr;
+
+		attr = nfp_mac_stats_rx[i].attr;
+		nfp_hstat_mac_rx.stats[attr / 64] |= BIT_ULL(attr % 64);
+	}
+	nfp_hstat_mac_rx.stats_cnt = ARRAY_SIZE(nfp_mac_stats_rx);
+
+	for (i = 0; i < ARRAY_SIZE(nfp_mac_stats_tx); i++) {
+		unsigned int attr;
+
+		attr = nfp_mac_stats_tx[i].attr;
+		nfp_hstat_mac_tx.stats[attr / 64] |= BIT_ULL(attr % 64);
+	}
+	nfp_hstat_mac_tx.stats_cnt = ARRAY_SIZE(nfp_mac_stats_tx);
+}
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c
index 6c10e8d119e4..4e366fde3478 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_main.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c
@@ -724,6 +724,7 @@ static int __init nfp_main_init(void)
 		nfp_driver_name);
 
 	nfp_net_debugfs_create();
+	nfp_net_hstat_init();
 
 	err = pci_register_driver(&nfp_pci_driver);
 	if (err < 0)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.h b/drivers/net/ethernet/netronome/nfp/nfp_main.h
index a3613a2e0aa5..367afb869df6 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_main.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_main.h
@@ -145,6 +145,8 @@ extern struct pci_driver nfp_netvf_pci_driver;
 
 extern const struct devlink_ops nfp_devlink_ops;
 
+void nfp_net_hstat_init(void);
+
 int nfp_net_pci_probe(struct nfp_pf *pf);
 void nfp_net_pci_remove(struct nfp_pf *pf);
 
-- 
2.19.2

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ