DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH v2 00/11] Port XStats
@ 2015-09-30  9:40 Harry van Haaren
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 01/11] doc: add extended statistics notes Harry van Haaren
                   ` (10 more replies)
  0 siblings, 11 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-09-30  9:40 UTC (permalink / raw)
  To: dev

This patchset adds an implementation of the xstats_get() and xstats_reset() API to the following PMDs: virtio, igb, igbvf, ixgbe, ixgbevf, i40e, i40evf and fm10k.

The xstats API allows DPDK apps to gain access to extended statistics from each port on a NIC. These statistics are structured as per a scheme detailed in the patch for the doc/prog_guide.

v2: Send correct patchset.

Harry van Haaren (11):
  doc: add extended statistics notes
  doc: add extended statistics to prog_guide
  ethdev: update xstats_get() strings and Q handling
  virtio: add xstats() implementation
  igb: add xstats() implementation
  igbvf: add xstats() implementation
  ixgbe: update statistic strings to scheme
  ixgbevf: add xstats() functions to VF
  i40e: add xstats() implementation
  i40evf: add xstats() implementation
  fm10k: add xstats() implementation

 doc/guides/prog_guide/poll_mode_drv.rst |  51 ++++-
 doc/guides/rel_notes/release_2_2.rst    |  12 ++
 drivers/net/e1000/igb_ethdev.c          | 195 +++++++++++++++++-
 drivers/net/fm10k/fm10k_ethdev.c        |  69 +++++++
 drivers/net/i40e/i40e_ethdev.c          | 268 ++++++++++++++++++++++++-
 drivers/net/i40e/i40e_ethdev_vf.c       |  89 +++++++-
 drivers/net/ixgbe/ixgbe_ethdev.c        | 346 +++++++++++++++++++++++++++++---
 drivers/net/virtio/virtio_ethdev.c      |  82 +++++++-
 lib/librte_ether/rte_ethdev.c           |  15 +-
 9 files changed, 1075 insertions(+), 52 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v2 01/11] doc: add extended statistics notes
  2015-09-30  9:40 [dpdk-dev] [PATCH v2 00/11] Port XStats Harry van Haaren
@ 2015-09-30  9:40 ` Harry van Haaren
  2015-10-22 15:48   ` [dpdk-dev] [PATCH v3 00/11] Port XStats Harry van Haaren
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 02/11] doc: add extended statistics to prog_guide Harry van Haaren
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 77+ messages in thread
From: Harry van Haaren @ 2015-09-30  9:40 UTC (permalink / raw)
  To: dev

Add release notes for this patchset.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 doc/guides/rel_notes/release_2_2.rst | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/doc/guides/rel_notes/release_2_2.rst b/doc/guides/rel_notes/release_2_2.rst
index 9a70dae..35f26d5 100644
--- a/doc/guides/rel_notes/release_2_2.rst
+++ b/doc/guides/rel_notes/release_2_2.rst
@@ -4,6 +4,18 @@ DPDK Release 2.2
 New Features
 ------------
 
+* **Extended Statistics**
+
+  Define extended statistics naming scheme to store metadata in the name
+  string name of each statistic. Implemented the extended stats API for
+  these PMDs:
+
+  * igb
+  * igbvf
+  * i40e
+  * i40evf
+  * fm10k
+  * virtio
 
 Resolved Issues
 ---------------
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v2 02/11] doc: add extended statistics to prog_guide
  2015-09-30  9:40 [dpdk-dev] [PATCH v2 00/11] Port XStats Harry van Haaren
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 01/11] doc: add extended statistics notes Harry van Haaren
@ 2015-09-30  9:40 ` Harry van Haaren
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 03/11] ethdev: update xstats_get() strings and Q handling Harry van Haaren
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-09-30  9:40 UTC (permalink / raw)
  To: dev

Add extended statistic section to the programmers
guide, poll mode driver section. This section describes
how the strings stats are formatted, and how the client
code can use this to gather information about the stat.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 doc/guides/prog_guide/poll_mode_drv.rst | 51 ++++++++++++++++++++++++++++++++-
 1 file changed, 50 insertions(+), 1 deletion(-)

diff --git a/doc/guides/prog_guide/poll_mode_drv.rst b/doc/guides/prog_guide/poll_mode_drv.rst
index 8780ba3..44cc9ce 100644
--- a/doc/guides/prog_guide/poll_mode_drv.rst
+++ b/doc/guides/prog_guide/poll_mode_drv.rst
@@ -1,5 +1,5 @@
 ..  BSD LICENSE
-    Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+    Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
     All rights reserved.
 
     Redistribution and use in source and binary forms, with or without
@@ -294,3 +294,52 @@ Ethernet Device API
 ~~~~~~~~~~~~~~~~~~~
 
 The Ethernet device API exported by the Ethernet PMDs is described in the *DPDK API Reference*.
+
+Extended Statistics API
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The extended statistics API allows each individual PMD to expose a unique set
+of statistics. The client of the API provides an array of
+``struct rte_eth_xstats`` type. Each ``struct rte_eth_xstats`` contains a
+string and value pair. The amount of xstats exposed, and position of the
+statistic in the array must remain constant during runtime.
+
+A naming scheme exists for the strings exposed to clients of the API. This is
+to allow scraping of the API for statistics of interest. The naming scheme uses
+strings split by a single underscore ``_``. The scheme is as follows:
+
+* direction
+* detail 1
+* detail 2
+* detail n
+* unit
+
+Examples of common statistics xstats strings, formatted to comply to the scheme
+proposed above:
+
+* ``rx_bytes``
+* ``rx_crc_errors``
+* ``tx_multicast_packets``
+
+The scheme, although quite simple, allows flexibility in presenting and reading
+information from the statistic strings. The following example illustrates the
+naming scheme:``rx_packets``. In this example, the string is split into two
+components. The first component ``rx`` indicates that the statistic is
+associated with the receive side of the NIC.  The second component ``packets``
+indicates that the unit of measure is packets.
+
+A more complicated example: ``tx_size_128_to_255_packets``. In this example,
+``tx`` indicates transmission, ``size``  is the first detail, ``128`` etc are
+more details, and ``packets`` indicates that this is a packet counter.
+
+Some additions in the metadata scheme are as follows:
+
+* If the first part does not match ``rx`` or ``tx``, the statistic does not
+  have an affinity with either recieve of transmit.
+
+* If the first letter of the second part is ``q`` and this ``q`` is followed
+  by a number, this statistic is part of a specific queue.
+
+An example where queue numbers are used is as follows: ``tx_q7_bytes`` which
+indicates this statistic applies to queue number 7, and represents the number
+of transmitted bytes on that queue.
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v2 03/11] ethdev: update xstats_get() strings and Q handling
  2015-09-30  9:40 [dpdk-dev] [PATCH v2 00/11] Port XStats Harry van Haaren
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 01/11] doc: add extended statistics notes Harry van Haaren
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 02/11] doc: add extended statistics to prog_guide Harry van Haaren
@ 2015-09-30  9:40 ` Harry van Haaren
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 04/11] virtio: add xstats() implementation Harry van Haaren
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-09-30  9:40 UTC (permalink / raw)
  To: dev

Update the strings used for presenting stats to adhere
to the scheme previously presented. Updated xstats_get()
function to handle Q information only if xstats() is not
implemented in the PMD, providing the PMD with the needed
flexibility to expose its extended Q stats.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 lib/librte_ether/rte_ethdev.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index b309309..4b0184f 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -143,7 +143,7 @@ static const struct rte_eth_xstats_name_off rte_stats_strings[] = {
 	{"tx_bytes", offsetof(struct rte_eth_stats, obytes)},
 	{"tx_errors", offsetof(struct rte_eth_stats, oerrors)},
 	{"rx_errors", offsetof(struct rte_eth_stats, ierrors)},
-	{"alloc_rx_buff_failed", offsetof(struct rte_eth_stats, rx_nombuf)},
+	{"rx_no_mbuf_errors", offsetof(struct rte_eth_stats, rx_nombuf)},
 };
 #define RTE_NB_STATS (sizeof(rte_stats_strings) / sizeof(rte_stats_strings[0]))
 
@@ -1666,8 +1666,6 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 
 	/* Return generic statistics */
 	count = RTE_NB_STATS;
-	count += dev->data->nb_rx_queues * RTE_NB_RXQ_STATS;
-	count += dev->data->nb_tx_queues * RTE_NB_TXQ_STATS;
 
 	/* implemented by the driver */
 	if (dev->dev_ops->xstats_get != NULL) {
@@ -1679,6 +1677,9 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 
 		if (xcount < 0)
 			return xcount;
+	} else {
+		count += dev->data->nb_rx_queues * RTE_NB_RXQ_STATS;
+		count += dev->data->nb_tx_queues * RTE_NB_TXQ_STATS;
 	}
 
 	if (n < count + xcount)
@@ -1698,6 +1699,10 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 		xstats[count++].value = val;
 	}
 
+	/* if xstats_get() is implemented by the PMD, the Q stats are done */
+	if (dev->dev_ops->xstats_get != NULL)
+		return count + xcount;
+
 	/* per-rxq stats */
 	for (q = 0; q < dev->data->nb_rx_queues; q++) {
 		for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
@@ -1706,7 +1711,7 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 					q * sizeof(uint64_t));
 			val = *stats_ptr;
 			snprintf(xstats[count].name, sizeof(xstats[count].name),
-				"rx_queue_%u_%s", q,
+				"rx_q%u_%s", q,
 				rte_rxq_stats_strings[i].name);
 			xstats[count++].value = val;
 		}
@@ -1720,7 +1725,7 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 					q * sizeof(uint64_t));
 			val = *stats_ptr;
 			snprintf(xstats[count].name, sizeof(xstats[count].name),
-				"tx_queue_%u_%s", q,
+				"tx_q%u_%s", q,
 				rte_txq_stats_strings[i].name);
 			xstats[count++].value = val;
 		}
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v2 04/11] virtio: add xstats() implementation
  2015-09-30  9:40 [dpdk-dev] [PATCH v2 00/11] Port XStats Harry van Haaren
                   ` (2 preceding siblings ...)
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 03/11] ethdev: update xstats_get() strings and Q handling Harry van Haaren
@ 2015-09-30  9:40 ` Harry van Haaren
  2015-09-30 17:44   ` Stephen Hemminger
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 05/11] igb: " Harry van Haaren
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 77+ messages in thread
From: Harry van Haaren @ 2015-09-30  9:40 UTC (permalink / raw)
  To: dev

Add xstats() functions and statistic strings to virtio PMD.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 82 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 80 insertions(+), 2 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 465d3cd..c897d1b 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -80,7 +80,10 @@ static int virtio_dev_link_update(struct rte_eth_dev *dev,
 static void virtio_set_hwaddr(struct virtio_hw *hw);
 static void virtio_get_hwaddr(struct virtio_hw *hw);
 
-static void virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats);
+static void virtio_dev_stats_get(struct rte_eth_dev *dev,
+				 struct rte_eth_stats *stats);
+static int virtio_dev_xstats_get(struct rte_eth_dev *dev,
+				 struct rte_eth_xstats *xstats, unsigned n);
 static void virtio_dev_stats_reset(struct rte_eth_dev *dev);
 static void virtio_dev_free_mbufs(struct rte_eth_dev *dev);
 static int virtio_vlan_filter_set(struct rte_eth_dev *dev,
@@ -109,6 +112,21 @@ static const struct rte_pci_id pci_id_virtio_map[] = {
 { .vendor_id = 0, /* sentinel */ },
 };
 
+struct rte_virtio_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	unsigned offset;
+};
+
+/* [rt]x_qX_ is prepended to the name string here */
+static const struct rte_virtio_xstats_name_off rte_virtio_q_stat_strings[] = {
+	{"packets", offsetof(struct virtqueue, packets)},
+	{"bytes", offsetof(struct virtqueue, bytes)},
+	{"errors", offsetof(struct virtqueue, errors)},
+};
+
+#define VIRTIO_NB_Q_XSTATS (sizeof(rte_virtio_q_stat_strings) / \
+			    sizeof(rte_virtio_q_stat_strings[0]))
+
 static int
 virtio_send_command(struct virtqueue *vq, struct virtio_pmd_ctrl *ctrl,
 		int *dlen, int pkt_num)
@@ -568,7 +586,9 @@ static const struct eth_dev_ops virtio_eth_dev_ops = {
 
 	.dev_infos_get           = virtio_dev_info_get,
 	.stats_get               = virtio_dev_stats_get,
+	.xstats_get              = virtio_dev_xstats_get,
 	.stats_reset             = virtio_dev_stats_reset,
+	.xstats_reset            = virtio_dev_stats_reset,
 	.link_update             = virtio_dev_link_update,
 	.rx_queue_setup          = virtio_dev_rx_queue_setup,
 	.rx_queue_release        = virtio_dev_rx_queue_release,
@@ -623,7 +643,7 @@ virtio_dev_atomic_write_link_status(struct rte_eth_dev *dev,
 }
 
 static void
-virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+virtio_update_stats(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 {
 	unsigned i;
 
@@ -660,6 +680,64 @@ virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed;
 }
 
+static int
+virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		      unsigned n)
+{
+	unsigned i;
+	unsigned count = 0;
+
+	unsigned nstats = dev->data->nb_tx_queues * VIRTIO_NB_Q_XSTATS +
+		dev->data->nb_rx_queues * VIRTIO_NB_Q_XSTATS;
+
+	if(n < nstats)
+		return nstats;
+
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		struct virtqueue *rxvq = dev->data->rx_queues[i];
+
+		if(rxvq == NULL)
+			continue;
+
+		unsigned t;
+
+		for(t = 0; t < VIRTIO_NB_Q_XSTATS; t++) {
+			snprintf(xstats[count].name, sizeof(xstats[count].name),
+				 "rx_q%u_%s", i,
+				 rte_virtio_q_stat_strings[t].name);
+			xstats[count].value = *(uint64_t *)(((char *)rxvq) +
+				rte_virtio_q_stat_strings[t].offset);
+			count++;
+		}
+	}
+
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
+		struct virtqueue *txvq = dev->data->tx_queues[i];
+
+		if(txvq == NULL)
+			continue;
+
+		unsigned t;
+
+		for(t = 0; t < VIRTIO_NB_Q_XSTATS; t++) {
+			snprintf(xstats[count].name, sizeof(xstats[count].name),
+				 "tx_q%u_%s", i,
+				 rte_virtio_q_stat_strings[t].name);
+			xstats[count].value = *(uint64_t *)(((char *)txvq) +
+				rte_virtio_q_stat_strings[t].offset);
+			count++;
+		}
+	}
+
+	return count;
+}
+
+static void
+virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+	virtio_update_stats(dev, stats);
+}
+
 static void
 virtio_dev_stats_reset(struct rte_eth_dev *dev)
 {
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v2 05/11] igb: add xstats() implementation
  2015-09-30  9:40 [dpdk-dev] [PATCH v2 00/11] Port XStats Harry van Haaren
                   ` (3 preceding siblings ...)
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 04/11] virtio: add xstats() implementation Harry van Haaren
@ 2015-09-30  9:40 ` Harry van Haaren
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 06/11] igbvf: " Harry van Haaren
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-09-30  9:40 UTC (permalink / raw)
  To: dev

Add xstats_get() and xstats_reset() functions to igb
driver, and the neccessary strings to expose these
NIC statistics.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/e1000/igb_ethdev.c | 137 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 132 insertions(+), 5 deletions(-)

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 848ef6e..e99fb69 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -96,7 +96,10 @@ static int  eth_igb_link_update(struct rte_eth_dev *dev,
 				int wait_to_complete);
 static void eth_igb_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *rte_stats);
+static int eth_igb_xstats_get(struct rte_eth_dev *dev,
+			      struct rte_eth_xstats *xstats, unsigned n);
 static void eth_igb_stats_reset(struct rte_eth_dev *dev);
+static void eth_igb_xstats_reset(struct rte_eth_dev *dev);
 static void eth_igb_infos_get(struct rte_eth_dev *dev,
 			      struct rte_eth_dev_info *dev_info);
 static void eth_igbvf_infos_get(struct rte_eth_dev *dev,
@@ -292,7 +295,9 @@ static const struct eth_dev_ops eth_igb_ops = {
 	.allmulticast_disable = eth_igb_allmulticast_disable,
 	.link_update          = eth_igb_link_update,
 	.stats_get            = eth_igb_stats_get,
+	.xstats_get           = eth_igb_xstats_get,
 	.stats_reset          = eth_igb_stats_reset,
+	.xstats_reset         = eth_igb_xstats_reset,
 	.dev_infos_get        = eth_igb_infos_get,
 	.mtu_set              = eth_igb_mtu_set,
 	.vlan_filter_set      = eth_igb_vlan_filter_set,
@@ -354,6 +359,78 @@ static const struct eth_dev_ops igbvf_eth_dev_ops = {
 	.get_reg              = igbvf_get_regs,
 };
 
+/* store statistics names and its offset in stats structure */
+struct rte_igb_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	unsigned offset;
+};
+
+static const struct rte_igb_xstats_name_off rte_igb_stats_strings[] = {
+	{"rx_crc_errors", offsetof(struct e1000_hw_stats, crcerrs)},
+	{"rx_align_errors", offsetof(struct e1000_hw_stats, algnerrc)},
+	{"rx_symbol_errors", offsetof(struct e1000_hw_stats, symerrs)},
+	{"rx_errors", offsetof(struct e1000_hw_stats, rxerrc)},
+	{"rx_missed_packets", offsetof(struct e1000_hw_stats, mpc)},
+	{"tx_single_collision_packets", offsetof(struct e1000_hw_stats, scc)},
+	{"tx_multiple_collision_packets", offsetof(struct e1000_hw_stats, mcc)},
+	{"tx_excessive_collision_packets", offsetof(struct e1000_hw_stats,
+		ecol)},
+	{"tx_late_collisions", offsetof(struct e1000_hw_stats, latecol)},
+	{"tx_total_collisions", offsetof(struct e1000_hw_stats, colc)},
+	{"tx_deferred_packets", offsetof(struct e1000_hw_stats, dc)},
+	{"tx_no_carrier_sense_packets", offsetof(struct e1000_hw_stats, tncrs)},
+	{"rx_carrier_ext_errors", offsetof(struct e1000_hw_stats, cexterr)},
+	{"rx_length_errors", offsetof(struct e1000_hw_stats, rlec)},
+	{"rx_xon_packets", offsetof(struct e1000_hw_stats, xonrxc)},
+	{"tx_xon_packets", offsetof(struct e1000_hw_stats, xontxc)},
+	{"rx_xoff_packets", offsetof(struct e1000_hw_stats, xoffrxc)},
+	{"tx_xoff_packets", offsetof(struct e1000_hw_stats, xofftxc)},
+	{"rx_flow_control_unsupported_packets", offsetof(struct e1000_hw_stats,
+		fcruc)},
+	{"rx_size_64_packets", offsetof(struct e1000_hw_stats, prc64)},
+	{"rx_size_65_to_127_packets", offsetof(struct e1000_hw_stats, prc127)},
+	{"rx_size_128_to_255_packets", offsetof(struct e1000_hw_stats, prc255)},
+	{"rx_size_256_to_511_packets", offsetof(struct e1000_hw_stats, prc511)},
+	{"rx_size_512_to_1023_packets", offsetof(struct e1000_hw_stats,
+		prc1023)},
+	{"rx_size_1024_to_max_packets", offsetof(struct e1000_hw_stats,
+		prc1522)},
+	{"rx_broadcast_packets", offsetof(struct e1000_hw_stats, bprc)},
+	{"rx_multicast_packets", offsetof(struct e1000_hw_stats, mprc)},
+	{"rx_no_buffer_errors", offsetof(struct e1000_hw_stats, rnbc)},
+	{"rx_undersize_packets", offsetof(struct e1000_hw_stats, ruc)},
+	{"rx_fragment_packets", offsetof(struct e1000_hw_stats, rfc)},
+	{"rx_oversize_packets", offsetof(struct e1000_hw_stats, roc)},
+	{"rx_jabber_packets", offsetof(struct e1000_hw_stats, rjc)},
+	{"rx_management_packets", offsetof(struct e1000_hw_stats, mgprc)},
+	{"rx_management_dropped", offsetof(struct e1000_hw_stats, mgpdc)},
+	{"tx_management_packets", offsetof(struct e1000_hw_stats, mgptc)},
+	{"rx_total_bytes", offsetof(struct e1000_hw_stats, tor)},
+	{"tx_total_bytes", offsetof(struct e1000_hw_stats, tot)},
+	{"rx_total_packets", offsetof(struct e1000_hw_stats, tpr)},
+	{"tx_total_packets", offsetof(struct e1000_hw_stats, tpt)},
+	{"tx_size_64_packets", offsetof(struct e1000_hw_stats, ptc64)},
+	{"tx_size_65_to_127_packets", offsetof(struct e1000_hw_stats, ptc127)},
+	{"tx_size_128_to_255_packets", offsetof(struct e1000_hw_stats, ptc255)},
+	{"tx_size_256_to_511_packets", offsetof(struct e1000_hw_stats, ptc511)},
+	{"tx_size_512_to_1023_packets", offsetof(struct e1000_hw_stats,
+		ptc1023)},
+	{"tx_size_1023_to_max_packets", offsetof(struct e1000_hw_stats,
+		ptc1522)},
+	{"tx_multicast_packets", offsetof(struct e1000_hw_stats, mptc)},
+	{"tx_broadcast_packets", offsetof(struct e1000_hw_stats, bptc)},
+	{"tx_tso_packets", offsetof(struct e1000_hw_stats, tsctc)},
+	{"tx_tso_errors", offsetof(struct e1000_hw_stats, tsctfc)},
+	{"rx_sent_to_host_packets", offsetof(struct e1000_hw_stats, rpthc)},
+	{"tx_sent_by_host_packets", offsetof(struct e1000_hw_stats, hgptc)},
+	{"rx_code_violation_packets", offsetof(struct e1000_hw_stats, scvpc)},
+
+	{"interrupt_assert_count", offsetof(struct e1000_hw_stats, iac)},
+};
+
+#define IGB_NB_XSTATS (sizeof(rte_igb_stats_strings) / \
+		sizeof(rte_igb_stats_strings[0]))
+
 /**
  * Atomically reads the link status information from global
  * structure rte_eth_dev.
@@ -1257,11 +1334,8 @@ igb_hardware_init(struct e1000_hw *hw)
 
 /* This function is based on igb_update_stats_counters() in igb/if_igb.c */
 static void
-eth_igb_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
+igb_read_stats_registers(struct e1000_hw *hw, struct e1000_hw_stats *stats)
 {
-	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	struct e1000_hw_stats *stats =
-			E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
 	int pause_frames;
 
 	if(hw->phy.media_type == e1000_media_type_copper ||
@@ -1365,6 +1439,16 @@ eth_igb_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
 	stats->cexterr += E1000_READ_REG(hw, E1000_CEXTERR);
 	stats->tsctc += E1000_READ_REG(hw, E1000_TSCTC);
 	stats->tsctfc += E1000_READ_REG(hw, E1000_TSCTFC);
+}
+
+static void
+eth_igb_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_hw_stats *stats =
+			E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+
+	igb_read_stats_registers(hw, stats);
 
 	if (rte_stats == NULL)
 		return;
@@ -1407,6 +1491,50 @@ eth_igb_stats_reset(struct rte_eth_dev *dev)
 }
 
 static void
+eth_igb_xstats_reset(struct rte_eth_dev *dev)
+{
+	struct e1000_hw_stats *stats =
+			E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+
+	/* HW registers are cleared on read */
+	eth_igb_xstats_get(dev, NULL, IGB_NB_XSTATS);
+
+	/* Reset software totals */
+	memset(stats, 0, sizeof(*stats));
+}
+
+static int
+eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		   unsigned n)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_hw_stats *hw_stats =
+			E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+	unsigned i;
+
+	if(n < IGB_NB_XSTATS)
+		return IGB_NB_XSTATS;
+
+	igb_read_stats_registers(hw, hw_stats);
+
+	/* If this is a reset xstats is NULL, and we have cleared the
+	 * registers by reading them.
+	 */
+	if (!xstats)
+		return 0;
+
+	/* Extended stats */
+	for (i = 0; i < IGB_NB_XSTATS; i++) {
+		snprintf(xstats[i].name, sizeof(xstats[i].name),
+			 "%s", rte_igb_stats_strings[i].name);
+		xstats[i].value = *(uint64_t *)(((char *)hw_stats) +
+			rte_igb_stats_strings[i].offset);
+	}
+
+	return IGB_NB_XSTATS;
+}
+
+static void
 eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -1461,7 +1589,6 @@ eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
 	rte_stats->ilbbytes = hw_stats->gorlbc;
 	rte_stats->olbpackets = hw_stats->gptlbc;
 	rte_stats->olbbytes = hw_stats->gotlbc;
-
 }
 
 static void
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v2 06/11] igbvf: add xstats() implementation
  2015-09-30  9:40 [dpdk-dev] [PATCH v2 00/11] Port XStats Harry van Haaren
                   ` (4 preceding siblings ...)
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 05/11] igb: " Harry van Haaren
@ 2015-09-30  9:40 ` Harry van Haaren
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 07/11] ixgbe: update statistic strings to scheme Harry van Haaren
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-09-30  9:40 UTC (permalink / raw)
  To: dev

Add xstats functionality to igbvf PMD, adding
necessary statistic strings.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/e1000/igb_ethdev.c | 62 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 55 insertions(+), 7 deletions(-)

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index e99fb69..bf762bf 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -152,7 +152,10 @@ static int igbvf_dev_start(struct rte_eth_dev *dev);
 static void igbvf_dev_stop(struct rte_eth_dev *dev);
 static void igbvf_dev_close(struct rte_eth_dev *dev);
 static int eth_igbvf_link_update(struct e1000_hw *hw);
-static void eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats);
+static void eth_igbvf_stats_get(struct rte_eth_dev *dev,
+				struct rte_eth_stats *rte_stats);
+static int eth_igbvf_xstats_get(struct rte_eth_dev *dev,
+				struct rte_eth_xstats *xstats, unsigned n);
 static void eth_igbvf_stats_reset(struct rte_eth_dev *dev);
 static int igbvf_vlan_filter_set(struct rte_eth_dev *dev,
 		uint16_t vlan_id, int on);
@@ -346,7 +349,9 @@ static const struct eth_dev_ops igbvf_eth_dev_ops = {
 	.dev_close            = igbvf_dev_close,
 	.link_update          = eth_igb_link_update,
 	.stats_get            = eth_igbvf_stats_get,
+	.xstats_get           = eth_igbvf_xstats_get,
 	.stats_reset          = eth_igbvf_stats_reset,
+	.xstats_reset         = eth_igbvf_stats_reset,
 	.vlan_filter_set      = igbvf_vlan_filter_set,
 	.dev_infos_get        = eth_igbvf_infos_get,
 	.rx_queue_setup       = eth_igb_rx_queue_setup,
@@ -431,6 +436,17 @@ static const struct rte_igb_xstats_name_off rte_igb_stats_strings[] = {
 #define IGB_NB_XSTATS (sizeof(rte_igb_stats_strings) / \
 		sizeof(rte_igb_stats_strings[0]))
 
+static const struct rte_igb_xstats_name_off rte_igbvf_stats_strings[] = {
+	{"rx_multicast_packets", offsetof(struct e1000_vf_stats, mprc)},
+	{"rx_good_loopback_packets", offsetof(struct e1000_vf_stats, gprlbc)},
+	{"tx_good_loopback_packets", offsetof(struct e1000_vf_stats, gptlbc)},
+	{"rx_good_loopback_bytes", offsetof(struct e1000_vf_stats, gorlbc)},
+	{"tx_good_loopback_bytes", offsetof(struct e1000_vf_stats, gotlbc)},
+};
+
+#define IGBVF_NB_XSTATS (sizeof(rte_igbvf_stats_strings) / \
+		sizeof(rte_igbvf_stats_strings[0]))
+
 /**
  * Atomically reads the link status information from global
  * structure rte_eth_dev.
@@ -1535,12 +1551,8 @@ eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
 }
 
 static void
-eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
+igbvf_read_stats_registers(struct e1000_hw *hw, struct e1000_vf_stats *hw_stats)
 {
-	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	struct e1000_vf_stats *hw_stats = (struct e1000_vf_stats*)
-			  E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
-
 	/* Good Rx packets, include VF loopback */
 	UPDATE_VF_STAT(E1000_VFGPRC,
 	    hw_stats->last_gprc, hw_stats->gprc);
@@ -1576,6 +1588,43 @@ eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
 	/* Good Tx loopback octets */
 	UPDATE_VF_STAT(E1000_VFGOTLBC,
 	    hw_stats->last_gotlbc, hw_stats->gotlbc);
+}
+
+static int
+eth_igbvf_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		     unsigned n)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_vf_stats *hw_stats = (struct e1000_vf_stats *)
+			E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+	unsigned i;
+
+	if(n < IGBVF_NB_XSTATS)
+		return IGBVF_NB_XSTATS;
+
+	igbvf_read_stats_registers(hw, hw_stats);
+
+	if(!xstats)
+		return 0;
+
+	for(i = 0; i < IGBVF_NB_XSTATS; i++) {
+		snprintf(xstats[i].name, sizeof(xstats[i].name), "%s",
+			 rte_igbvf_stats_strings[i].name);
+		xstats[i].value = *(uint64_t *)(((char *)hw_stats) +
+			rte_igbvf_stats_strings[i].offset);
+	}
+
+	return IGBVF_NB_XSTATS;
+}
+
+static void
+eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_vf_stats *hw_stats = (struct e1000_vf_stats *)
+			  E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+
+	igbvf_read_stats_registers(hw, hw_stats);
 
 	if (rte_stats == NULL)
 		return;
@@ -1603,7 +1652,6 @@ eth_igbvf_stats_reset(struct rte_eth_dev *dev)
 	/* reset HW current stats*/
 	memset(&hw_stats->gprc, 0, sizeof(*hw_stats) -
 	       offsetof(struct e1000_vf_stats, gprc));
-
 }
 
 static void
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v2 07/11] ixgbe: update statistic strings to scheme
  2015-09-30  9:40 [dpdk-dev] [PATCH v2 00/11] Port XStats Harry van Haaren
                   ` (5 preceding siblings ...)
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 06/11] igbvf: " Harry van Haaren
@ 2015-09-30  9:40 ` Harry van Haaren
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 08/11] ixgbevf: add xstats() functions to VF Harry van Haaren
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-09-30  9:40 UTC (permalink / raw)
  To: dev

Updated and add statistic strings as used by xstats_get().

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 295 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 273 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index ec2918c..4fb7313 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -506,29 +506,280 @@ struct rte_ixgbe_xstats_name_off {
 };
 
 static const struct rte_ixgbe_xstats_name_off rte_ixgbe_stats_strings[] = {
-	{"rx_illegal_byte_err", offsetof(struct ixgbe_hw_stats, errbc)},
-	{"rx_len_err", offsetof(struct ixgbe_hw_stats, rlec)},
-	{"rx_undersize_count", offsetof(struct ixgbe_hw_stats, ruc)},
-	{"rx_oversize_count", offsetof(struct ixgbe_hw_stats, roc)},
-	{"rx_fragment_count", offsetof(struct ixgbe_hw_stats, rfc)},
-	{"rx_jabber_count", offsetof(struct ixgbe_hw_stats, rjc)},
-	{"l3_l4_xsum_error", offsetof(struct ixgbe_hw_stats, xec)},
-	{"mac_local_fault", offsetof(struct ixgbe_hw_stats, mlfc)},
-	{"mac_remote_fault", offsetof(struct ixgbe_hw_stats, mrfc)},
-	{"mac_short_pkt_discard", offsetof(struct ixgbe_hw_stats, mspdc)},
-	{"fccrc_error", offsetof(struct ixgbe_hw_stats, fccrc)},
-	{"fcoe_drop", offsetof(struct ixgbe_hw_stats, fcoerpdc)},
-	{"fc_last_error", offsetof(struct ixgbe_hw_stats, fclast)},
-	{"rx_broadcast_packets", offsetof(struct ixgbe_hw_stats, bprc)},
-	{"rx_phy_multicast_packets", offsetof(struct ixgbe_hw_stats, mprc)},
-	{"mgmt_pkts_dropped", offsetof(struct ixgbe_hw_stats, mngpdc)},
 	{"rx_crc_errors", offsetof(struct ixgbe_hw_stats, crcerrs)},
-	{"fdir_match", offsetof(struct ixgbe_hw_stats, fdirmatch)},
-	{"fdir_miss", offsetof(struct ixgbe_hw_stats, fdirmiss)},
-	{"tx_flow_control_xon", offsetof(struct ixgbe_hw_stats, lxontxc)},
-	{"rx_flow_control_xon", offsetof(struct ixgbe_hw_stats, lxonrxc)},
-	{"tx_flow_control_xoff", offsetof(struct ixgbe_hw_stats, lxofftxc)},
-	{"rx_flow_control_xoff", offsetof(struct ixgbe_hw_stats, lxoffrxc)},
+	{"rx_illegal_byte_errors", offsetof(struct ixgbe_hw_stats, illerrc)},
+	{"rx_error_bytes", offsetof(struct ixgbe_hw_stats, errbc)},
+	{"mac_local_errors", offsetof(struct ixgbe_hw_stats, mlfc)},
+	{"mac_remote_errors", offsetof(struct ixgbe_hw_stats, mrfc)},
+	{"rx_length_errors", offsetof(struct ixgbe_hw_stats, rlec)},
+	{"tx_xon_packets", offsetof(struct ixgbe_hw_stats, lxontxc)},
+	{"rx_xon_packets", offsetof(struct ixgbe_hw_stats, lxonrxc)},
+	{"tx_xoff_packets", offsetof(struct ixgbe_hw_stats, lxofftxc)},
+	{"rx_xoff_packets", offsetof(struct ixgbe_hw_stats, lxoffrxc)},
+	{"rx_size_64_packets", offsetof(struct ixgbe_hw_stats, prc64)},
+	{"rx_size_65_to_127_packets", offsetof(struct ixgbe_hw_stats, prc127)},
+	{"rx_size_128_to_255_packets", offsetof(struct ixgbe_hw_stats, prc255)},
+	{"rx_size_256_to_511_packets", offsetof(struct ixgbe_hw_stats, prc511)},
+	{"rx_size_512_to_1023_packets", offsetof(struct ixgbe_hw_stats,
+		prc1023)},
+	{"rx_size_1024_to_max_packets", offsetof(struct ixgbe_hw_stats,
+		prc1522)},
+	{"rx_broadcast_packets", offsetof(struct ixgbe_hw_stats, bprc)},
+	{"rx_multicast_packets", offsetof(struct ixgbe_hw_stats, mprc)},
+	{"rx_fragment_errors", offsetof(struct ixgbe_hw_stats, rfc)},
+	{"rx_undersize_errors", offsetof(struct ixgbe_hw_stats, ruc)},
+	{"rx_oversize_errors", offsetof(struct ixgbe_hw_stats, roc)},
+	{"rx_jabber_errors", offsetof(struct ixgbe_hw_stats, rjc)},
+	{"rx_managment_packets", offsetof(struct ixgbe_hw_stats, mngprc)},
+	{"rx_managment_dropped", offsetof(struct ixgbe_hw_stats, mngpdc)},
+	{"tx_managment_packets", offsetof(struct ixgbe_hw_stats, mngptc)},
+	{"rx_total_bytes", offsetof(struct ixgbe_hw_stats, tor)},
+	{"rx_total_packets", offsetof(struct ixgbe_hw_stats, tpr)},
+	{"tx_total_bytes", offsetof(struct ixgbe_hw_stats, tpt)},
+	{"tx_size_64_packets", offsetof(struct ixgbe_hw_stats, ptc64)},
+	{"tx_size_65_to_127_packets", offsetof(struct ixgbe_hw_stats, ptc127)},
+	{"tx_size_128_to_255_packets", offsetof(struct ixgbe_hw_stats, ptc255)},
+	{"tx_size_256_to_511_packets", offsetof(struct ixgbe_hw_stats, ptc511)},
+	{"tx_size_512_to_1023_packets", offsetof(struct ixgbe_hw_stats,
+		ptc1023)},
+	{"tx_size_1024_to_max_packets", offsetof(struct ixgbe_hw_stats,
+		ptc1522)},
+	{"tx_multicast_packets", offsetof(struct ixgbe_hw_stats, mptc)},
+	{"tx_broadcast_packets", offsetof(struct ixgbe_hw_stats, bptc)},
+	{"rx_mac_short_packet_discard", offsetof(struct ixgbe_hw_stats, mspdc)},
+	{"rx_l3_l4_xsum_error", offsetof(struct ixgbe_hw_stats, xec)},
+
+	{"flow_director_added_filters", offsetof(struct ixgbe_hw_stats,
+		fdirustat_add)},
+	{"flow_director_removed_filters", offsetof(struct ixgbe_hw_stats,
+		fdirustat_remove)},
+	{"flow_director_filter_add_errors", offsetof(struct ixgbe_hw_stats,
+		fdirfstat_fadd)},
+	{"flow_director_filter_remove_errors", offsetof(struct ixgbe_hw_stats,
+		fdirfstat_fremove)},
+	{"flow_director_matched_filters", offsetof(struct ixgbe_hw_stats,
+		fdirmatch)},
+	{"flow_director_missed_filters", offsetof(struct ixgbe_hw_stats,
+		fdirmiss)},
+
+	{"rx_fcoe_crc_errors", offsetof(struct ixgbe_hw_stats, fccrc)},
+	{"rx_fcoe_dropped", offsetof(struct ixgbe_hw_stats, fcoerpdc)},
+	{"rx_fcoe_no_mbufs_avail_errors", offsetof(struct ixgbe_hw_stats,
+		fclast)},
+	{"rx_fcoe_packets", offsetof(struct ixgbe_hw_stats, fcoeprc)},
+	{"tx_fcoe_packets", offsetof(struct ixgbe_hw_stats, fcoeptc)},
+	{"rx_fcoe_bytes", offsetof(struct ixgbe_hw_stats, fcoedwrc)},
+	{"tx_fcoe_bytes", offsetof(struct ixgbe_hw_stats, fcoedwtc)},
+	{"rx_fcoe_no_direct_data_placement", offsetof(struct ixgbe_hw_stats,
+		fcoe_noddp)},
+	{"rx_fcoe_no_direct_data_placement_ext_buff",
+		offsetof(struct ixgbe_hw_stats, fcoe_noddp_ext_buff)},
+
+	{"tx_flow_control_xon_packets", offsetof(struct ixgbe_hw_stats,
+		lxontxc)},
+	{"rx_flow_control_xon_packets", offsetof(struct ixgbe_hw_stats,
+		lxonrxc)},
+	{"tx_flow_control_xoff_packets", offsetof(struct ixgbe_hw_stats,
+		lxofftxc)},
+	{"rx_flow_control_xoff_packets", offsetof(struct ixgbe_hw_stats,
+		lxoffrxc)},
+	{"rx_total_missed_packets", offsetof(struct ixgbe_hw_stats, mpctotal)},
+
+	{"rx_q0_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[0])},
+	{"rx_q1_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[1])},
+	{"rx_q2_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[2])},
+	{"rx_q3_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[3])},
+	{"rx_q4_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[4])},
+	{"rx_q5_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[5])},
+	{"rx_q6_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[6])},
+	{"rx_q7_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[7])},
+
+	{"rx_q0_no_mbufs_avail_errors", offsetof(struct ixgbe_hw_stats,
+		rnbc[0])},
+	{"rx_q1_no_mbufs_avail_errors", offsetof(struct ixgbe_hw_stats,
+		rnbc[1])},
+	{"rx_q2_no_mbufs_avail_errors", offsetof(struct ixgbe_hw_stats,
+		rnbc[2])},
+	{"rx_q3_no_mbufs_avail_errors", offsetof(struct ixgbe_hw_stats,
+		rnbc[3])},
+	{"rx_q4_no_mbufs_avail_errors", offsetof(struct ixgbe_hw_stats,
+		rnbc[4])},
+	{"rx_q5_no_mbufs_avail_errors", offsetof(struct ixgbe_hw_stats,
+		rnbc[5])},
+	{"rx_q6_no_mbufs_avail_errors", offsetof(struct ixgbe_hw_stats,
+		rnbc[6])},
+	{"rx_q7_no_mbufs_avail_errors", offsetof(struct ixgbe_hw_stats,
+		rnbc[7])},
+
+	{"tx_q0_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxontxc[0])},
+	{"tx_q1_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxontxc[1])},
+	{"tx_q2_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxontxc[2])},
+	{"tx_q3_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxontxc[3])},
+	{"tx_q4_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxontxc[4])},
+	{"tx_q5_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxontxc[5])},
+	{"tx_q6_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxontxc[6])},
+	{"tx_q7_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxontxc[7])},
+
+	{"rx_q0_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxonrxc[0])},
+	{"rx_q1_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxonrxc[1])},
+	{"rx_q2_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxonrxc[2])},
+	{"rx_q3_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxonrxc[3])},
+	{"rx_q4_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxonrxc[4])},
+	{"rx_q5_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxonrxc[5])},
+	{"rx_q6_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxonrxc[6])},
+	{"rx_q7_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxonrxc[7])},
+
+	{"tx_q0_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxofftxc[0])},
+	{"tx_q1_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxofftxc[1])},
+	{"tx_q2_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxofftxc[2])},
+	{"tx_q3_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxofftxc[3])},
+	{"tx_q4_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxofftxc[4])},
+	{"tx_q5_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxofftxc[5])},
+	{"tx_q6_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxofftxc[6])},
+	{"tx_q7_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxofftxc[7])},
+
+	{"rx_q0_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxoffrxc[0])},
+	{"rx_q1_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxoffrxc[1])},
+	{"rx_q2_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxoffrxc[2])},
+	{"rx_q3_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxoffrxc[3])},
+	{"rx_q4_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxoffrxc[4])},
+	{"rx_q5_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxoffrxc[5])},
+	{"rx_q6_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxoffrxc[6])},
+	{"rx_q7_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxoffrxc[7])},
+
+	{"xx_q0_xon_to_off_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxon2offc[0])},
+	{"xx_q1_xon_to_off_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxon2offc[1])},
+	{"xx_q2_xon_to_off_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxon2offc[2])},
+	{"xx_q3_xon_to_off_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxon2offc[3])},
+	{"xx_q4_xon_to_off_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxon2offc[4])},
+	{"xx_q5_xon_to_off_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxon2offc[5])},
+	{"xx_q6_xon_to_off_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxon2offc[6])},
+	{"xx_q7_xon_to_off_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxon2offc[7])},
+
+	{"rx_q0_packets", offsetof(struct ixgbe_hw_stats, qprc[0])},
+	{"rx_q1_packets", offsetof(struct ixgbe_hw_stats, qprc[1])},
+	{"rx_q2_packets", offsetof(struct ixgbe_hw_stats, qprc[2])},
+	{"rx_q3_packets", offsetof(struct ixgbe_hw_stats, qprc[3])},
+	{"rx_q4_packets", offsetof(struct ixgbe_hw_stats, qprc[4])},
+	{"rx_q5_packets", offsetof(struct ixgbe_hw_stats, qprc[5])},
+	{"rx_q6_packets", offsetof(struct ixgbe_hw_stats, qprc[6])},
+	{"rx_q7_packets", offsetof(struct ixgbe_hw_stats, qprc[7])},
+	{"rx_q8_packets", offsetof(struct ixgbe_hw_stats, qprc[8])},
+	{"rx_q9_packets", offsetof(struct ixgbe_hw_stats, qprc[9])},
+	{"rx_q10_packets", offsetof(struct ixgbe_hw_stats, qprc[10])},
+	{"rx_q11_packets", offsetof(struct ixgbe_hw_stats, qprc[11])},
+	{"rx_q12_packets", offsetof(struct ixgbe_hw_stats, qprc[12])},
+	{"rx_q13_packets", offsetof(struct ixgbe_hw_stats, qprc[13])},
+	{"rx_q14_packets", offsetof(struct ixgbe_hw_stats, qprc[14])},
+	{"rx_q15_packets", offsetof(struct ixgbe_hw_stats, qprc[15])},
+
+	{"tx_q0_packets", offsetof(struct ixgbe_hw_stats, qptc[0])},
+	{"tx_q1_packets", offsetof(struct ixgbe_hw_stats, qptc[1])},
+	{"tx_q2_packets", offsetof(struct ixgbe_hw_stats, qptc[2])},
+	{"tx_q3_packets", offsetof(struct ixgbe_hw_stats, qptc[3])},
+	{"tx_q4_packets", offsetof(struct ixgbe_hw_stats, qptc[4])},
+	{"tx_q5_packets", offsetof(struct ixgbe_hw_stats, qptc[5])},
+	{"tx_q6_packets", offsetof(struct ixgbe_hw_stats, qptc[6])},
+	{"tx_q7_packets", offsetof(struct ixgbe_hw_stats, qptc[7])},
+	{"tx_q8_packets", offsetof(struct ixgbe_hw_stats, qptc[8])},
+	{"tx_q9_packets", offsetof(struct ixgbe_hw_stats, qptc[9])},
+	{"tx_q10_packets", offsetof(struct ixgbe_hw_stats, qptc[10])},
+	{"tx_q11_packets", offsetof(struct ixgbe_hw_stats, qptc[11])},
+	{"tx_q12_packets", offsetof(struct ixgbe_hw_stats, qptc[12])},
+	{"tx_q13_packets", offsetof(struct ixgbe_hw_stats, qptc[13])},
+	{"tx_q14_packets", offsetof(struct ixgbe_hw_stats, qptc[14])},
+	{"tx_q15_packets", offsetof(struct ixgbe_hw_stats, qptc[15])},
+
+	{"rx_q0_bytes", offsetof(struct ixgbe_hw_stats, qbrc[0])},
+	{"rx_q1_bytes", offsetof(struct ixgbe_hw_stats, qbrc[1])},
+	{"rx_q2_bytes", offsetof(struct ixgbe_hw_stats, qbrc[2])},
+	{"rx_q3_bytes", offsetof(struct ixgbe_hw_stats, qbrc[3])},
+	{"rx_q4_bytes", offsetof(struct ixgbe_hw_stats, qbrc[4])},
+	{"rx_q5_bytes", offsetof(struct ixgbe_hw_stats, qbrc[5])},
+	{"rx_q6_bytes", offsetof(struct ixgbe_hw_stats, qbrc[6])},
+	{"rx_q7_bytes", offsetof(struct ixgbe_hw_stats, qbrc[7])},
+	{"rx_q8_bytes", offsetof(struct ixgbe_hw_stats, qbrc[8])},
+	{"rx_q9_bytes", offsetof(struct ixgbe_hw_stats, qbrc[9])},
+	{"rx_q10_bytes", offsetof(struct ixgbe_hw_stats, qbrc[10])},
+	{"rx_q11_bytes", offsetof(struct ixgbe_hw_stats, qbrc[11])},
+	{"rx_q12_bytes", offsetof(struct ixgbe_hw_stats, qbrc[12])},
+	{"rx_q13_bytes", offsetof(struct ixgbe_hw_stats, qbrc[13])},
+	{"rx_q14_bytes", offsetof(struct ixgbe_hw_stats, qbrc[14])},
+	{"rx_q15_bytes", offsetof(struct ixgbe_hw_stats, qbrc[15])},
+
+	{"tx_q0_bytes", offsetof(struct ixgbe_hw_stats, qbtc[0])},
+	{"tx_q1_bytes", offsetof(struct ixgbe_hw_stats, qbtc[1])},
+	{"tx_q2_bytes", offsetof(struct ixgbe_hw_stats, qbtc[2])},
+	{"tx_q3_bytes", offsetof(struct ixgbe_hw_stats, qbtc[3])},
+	{"tx_q4_bytes", offsetof(struct ixgbe_hw_stats, qbtc[4])},
+	{"tx_q5_bytes", offsetof(struct ixgbe_hw_stats, qbtc[5])},
+	{"tx_q6_bytes", offsetof(struct ixgbe_hw_stats, qbtc[6])},
+	{"tx_q7_bytes", offsetof(struct ixgbe_hw_stats, qbtc[7])},
+	{"tx_q8_bytes", offsetof(struct ixgbe_hw_stats, qbtc[8])},
+	{"tx_q9_bytes", offsetof(struct ixgbe_hw_stats, qbtc[9])},
+	{"tx_q10_bytes", offsetof(struct ixgbe_hw_stats, qbtc[10])},
+	{"tx_q11_bytes", offsetof(struct ixgbe_hw_stats, qbtc[11])},
+	{"tx_q12_bytes", offsetof(struct ixgbe_hw_stats, qbtc[12])},
+	{"tx_q13_bytes", offsetof(struct ixgbe_hw_stats, qbtc[13])},
+	{"tx_q14_bytes", offsetof(struct ixgbe_hw_stats, qbtc[14])},
+	{"tx_q15_bytes", offsetof(struct ixgbe_hw_stats, qbtc[15])},
+
+	{"rx_q0_dropped", offsetof(struct ixgbe_hw_stats, qprdc[0])},
+	{"rx_q1_dropped", offsetof(struct ixgbe_hw_stats, qprdc[1])},
+	{"rx_q2_dropped", offsetof(struct ixgbe_hw_stats, qprdc[2])},
+	{"rx_q3_dropped", offsetof(struct ixgbe_hw_stats, qprdc[3])},
+	{"rx_q4_dropped", offsetof(struct ixgbe_hw_stats, qprdc[4])},
+	{"rx_q5_dropped", offsetof(struct ixgbe_hw_stats, qprdc[5])},
+	{"rx_q6_dropped", offsetof(struct ixgbe_hw_stats, qprdc[6])},
+	{"rx_q7_dropped", offsetof(struct ixgbe_hw_stats, qprdc[7])},
+	{"rx_q8_dropped", offsetof(struct ixgbe_hw_stats, qprdc[8])},
+	{"rx_q9_dropped", offsetof(struct ixgbe_hw_stats, qprdc[9])},
+	{"rx_q10_dropped", offsetof(struct ixgbe_hw_stats, qprdc[10])},
+	{"rx_q11_dropped", offsetof(struct ixgbe_hw_stats, qprdc[11])},
+	{"rx_q12_dropped", offsetof(struct ixgbe_hw_stats, qprdc[12])},
+	{"rx_q13_dropped", offsetof(struct ixgbe_hw_stats, qprdc[13])},
+	{"rx_q14_dropped", offsetof(struct ixgbe_hw_stats, qprdc[14])},
+	{"rx_q15_dropped", offsetof(struct ixgbe_hw_stats, qprdc[15])},
 };
 
 #define IXGBE_NB_XSTATS (sizeof(rte_ixgbe_stats_strings) /	\
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v2 08/11] ixgbevf: add xstats() functions to VF
  2015-09-30  9:40 [dpdk-dev] [PATCH v2 00/11] Port XStats Harry van Haaren
                   ` (6 preceding siblings ...)
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 07/11] ixgbe: update statistic strings to scheme Harry van Haaren
@ 2015-09-30  9:40 ` Harry van Haaren
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 09/11] i40e: add xstats() implementation Harry van Haaren
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-09-30  9:40 UTC (permalink / raw)
  To: dev

Add xstats() functions and stat strings as necessary to ixgbevf PMD.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 51 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 49 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 4fb7313..1518cc1 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -149,6 +149,8 @@ static void ixgbe_dev_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *stats);
 static int ixgbe_dev_xstats_get(struct rte_eth_dev *dev,
 				struct rte_eth_xstats *xstats, unsigned n);
+static int ixgbevf_dev_xstats_get(struct rte_eth_dev *dev,
+				  struct rte_eth_xstats *xstats, unsigned n);
 static void ixgbe_dev_stats_reset(struct rte_eth_dev *dev);
 static void ixgbe_dev_xstats_reset(struct rte_eth_dev *dev);
 static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
@@ -477,7 +479,9 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
 	.dev_stop             = ixgbevf_dev_stop,
 	.link_update          = ixgbe_dev_link_update,
 	.stats_get            = ixgbevf_dev_stats_get,
+	.xstats_get           = ixgbevf_dev_xstats_get,
 	.stats_reset          = ixgbevf_dev_stats_reset,
+	.xstats_reset         = ixgbevf_dev_stats_reset,
 	.dev_close            = ixgbevf_dev_close,
 	.dev_infos_get        = ixgbevf_dev_info_get,
 	.mtu_set              = ixgbevf_dev_set_mtu,
@@ -785,6 +789,13 @@ static const struct rte_ixgbe_xstats_name_off rte_ixgbe_stats_strings[] = {
 #define IXGBE_NB_XSTATS (sizeof(rte_ixgbe_stats_strings) /	\
 		sizeof(rte_ixgbe_stats_strings[0]))
 
+static const struct rte_ixgbe_xstats_name_off rte_ixgbevf_stats_strings[] = {
+	{"rx_multicast_packets", offsetof(struct ixgbevf_hw_stats, vfmprc)},
+};
+
+#define IXGBEVF_NB_XSTATS (sizeof(rte_ixgbevf_stats_strings) /	\
+		sizeof(rte_ixgbevf_stats_strings[0]))
+
 /**
  * Atomically reads the link status information from global
  * structure rte_eth_dev.
@@ -2531,7 +2542,7 @@ ixgbe_dev_xstats_reset(struct rte_eth_dev *dev)
 }
 
 static void
-ixgbevf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+ixgbevf_update_stats(struct rte_eth_dev *dev)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct ixgbevf_hw_stats *hw_stats = (struct ixgbevf_hw_stats*)
@@ -2556,8 +2567,44 @@ ixgbevf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	/* Rx Multicst Packet */
 	UPDATE_VF_STAT(IXGBE_VFMPRC,
 	    hw_stats->last_vfmprc, hw_stats->vfmprc);
+}
 
-	if (stats == NULL)
+static int
+ixgbevf_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		       unsigned n)
+{
+	struct ixgbevf_hw_stats *hw_stats = (struct ixgbevf_hw_stats *)
+			IXGBE_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+	unsigned i;
+
+	if(n < IXGBEVF_NB_XSTATS)
+		return IXGBEVF_NB_XSTATS;
+
+	ixgbevf_update_stats(dev);
+
+	if (!xstats)
+		return 0;
+
+	/* Extended stats */
+	for (i = 0; i < IXGBEVF_NB_XSTATS; i++) {
+		snprintf(xstats[i].name, sizeof(xstats[i].name),
+			 "%s", rte_ixgbevf_stats_strings[i].name);
+		xstats[i].value = *(uint64_t *)(((char *)hw_stats) +
+			rte_ixgbevf_stats_strings[i].offset);
+	}
+
+	return IXGBEVF_NB_XSTATS;
+}
+
+static void
+ixgbevf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+	struct ixgbevf_hw_stats *hw_stats = (struct ixgbevf_hw_stats *)
+			  IXGBE_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+
+	ixgbevf_update_stats(dev);
+
+	if(stats == NULL)
 		return;
 
 	stats->ipackets = hw_stats->vfgprc;
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v2 09/11] i40e: add xstats() implementation
  2015-09-30  9:40 [dpdk-dev] [PATCH v2 00/11] Port XStats Harry van Haaren
                   ` (7 preceding siblings ...)
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 08/11] ixgbevf: add xstats() functions to VF Harry van Haaren
@ 2015-09-30  9:40 ` Harry van Haaren
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 10/11] i40evf: " Harry van Haaren
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 11/11] fm10k: " Harry van Haaren
  10 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-09-30  9:40 UTC (permalink / raw)
  To: dev

Add xstats functions to i40e PMD, allowing extended statistics
to be retrieved from the NIC and exposed to the DPDK.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 268 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 261 insertions(+), 7 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 2dd9fdc..f2952b9 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -127,7 +127,10 @@ static int i40e_dev_set_link_up(struct rte_eth_dev *dev);
 static int i40e_dev_set_link_down(struct rte_eth_dev *dev);
 static void i40e_dev_stats_get(struct rte_eth_dev *dev,
 			       struct rte_eth_stats *stats);
+static int i40e_dev_xstats_get(struct rte_eth_dev *dev,
+			       struct rte_eth_xstats *xstats, unsigned n);
 static void i40e_dev_stats_reset(struct rte_eth_dev *dev);
+static void i40e_dev_xstats_reset(struct rte_eth_dev *dev);
 static int i40e_dev_queue_stats_mapping_set(struct rte_eth_dev *dev,
 					    uint16_t queue_id,
 					    uint8_t stat_idx,
@@ -232,6 +235,8 @@ static int i40e_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
 					   uint32_t flags);
 static int i40e_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
 					   struct timespec *timestamp);
+static void i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw);
+
 
 static const struct rte_pci_id pci_id_i40e_map[] = {
 #define RTE_PCI_DEV_ID_DECL_I40E(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
@@ -252,7 +257,9 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
 	.dev_set_link_down            = i40e_dev_set_link_down,
 	.link_update                  = i40e_dev_link_update,
 	.stats_get                    = i40e_dev_stats_get,
+	.xstats_get                   = i40e_dev_xstats_get,
 	.stats_reset                  = i40e_dev_stats_reset,
+	.xstats_reset                 = i40e_dev_xstats_reset,
 	.queue_stats_mapping_set      = i40e_dev_queue_stats_mapping_set,
 	.dev_infos_get                = i40e_dev_info_get,
 	.vlan_filter_set              = i40e_vlan_filter_set,
@@ -291,6 +298,190 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
 	.timesync_read_tx_timestamp   = i40e_timesync_read_tx_timestamp,
 };
 
+/* store statistics names and its offset in stats structure */
+struct rte_i40e_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	unsigned offset;
+};
+
+static const struct rte_i40e_xstats_name_off rte_i40e_stats_strings[] = {
+	{"rx_bytes", offsetof(struct i40e_eth_stats, rx_bytes)},
+	{"rx_unicast_packets", offsetof(struct i40e_eth_stats, rx_unicast)},
+	{"rx_multicast_packets", offsetof(struct i40e_eth_stats, rx_multicast)},
+	{"rx_broadcast_packets", offsetof(struct i40e_eth_stats, rx_broadcast)},
+	{"rx_dropped", offsetof(struct i40e_eth_stats, rx_discards)},
+	{"rx_unknown_protocol_packets", offsetof(struct i40e_eth_stats,
+		rx_unknown_protocol)},
+	{"tx_bytes", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_unicast_packets", offsetof(struct i40e_eth_stats, tx_unicast)},
+	{"tx_multicast_packets", offsetof(struct i40e_eth_stats, tx_multicast)},
+	{"tx_broadcast_packets", offsetof(struct i40e_eth_stats, tx_broadcast)},
+	{"tx_dropped", offsetof(struct i40e_eth_stats, tx_discards)},
+	{"tx_errors", offsetof(struct i40e_eth_stats, tx_errors)},
+};
+
+static const struct rte_i40e_xstats_name_off rte_i40e_hw_port_strings[] = {
+	{"tx_link_down_dropped", offsetof(struct i40e_hw_port_stats,
+		tx_dropped_link_down)},
+	{"rx_crc_errors", offsetof(struct i40e_hw_port_stats, crc_errors)},
+	{"rx_illegal_bytes", offsetof(struct i40e_hw_port_stats,
+		illegal_bytes)},
+	{"rx_error_bytes", offsetof(struct i40e_hw_port_stats, error_bytes)},
+	{"mac_local_errors", offsetof(struct i40e_hw_port_stats,
+		mac_local_faults)},
+	{"mac_remote_errors", offsetof(struct i40e_hw_port_stats,
+		mac_remote_faults)},
+	{"rx_length_errors", offsetof(struct i40e_hw_port_stats,
+		rx_length_errors)},
+	{"tx_xon_packets", offsetof(struct i40e_hw_port_stats, link_xon_tx)},
+	{"rx_xon_packets", offsetof(struct i40e_hw_port_stats, link_xon_rx)},
+	{"tx_xoff_packets", offsetof(struct i40e_hw_port_stats, link_xoff_tx)},
+	{"rx_xoff_packets", offsetof(struct i40e_hw_port_stats, link_xoff_rx)},
+	{"rx_size_64_packets", offsetof(struct i40e_hw_port_stats, rx_size_64)},
+	{"rx_size_65_to_127_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_127)},
+	{"rx_size_128_to_255_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_255)},
+	{"rx_size_256_to_511_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_511)},
+	{"rx_size_512_to_1023_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_1023)},
+	{"rx_size_1024_to_1522_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_1522)},
+	{"rx_size_1523_to_max_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_big)},
+	{"rx_undersized_packets", offsetof(struct i40e_hw_port_stats,
+		rx_undersize)},
+	{"rx_oversize_packets", offsetof(struct i40e_hw_port_stats,
+		rx_oversize)},
+	{"rx_mac_short_dropped", offsetof(struct i40e_hw_port_stats,
+		mac_short_packet_dropped)},
+	{"rx_fragmented_packets", offsetof(struct i40e_hw_port_stats,
+		rx_fragments)},
+	{"rx_jabber_packets", offsetof(struct i40e_hw_port_stats, rx_jabber)},
+	{"tx_size_64_packets", offsetof(struct i40e_hw_port_stats, tx_size_64)},
+	{"tx_size_65_to_127_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_127)},
+	{"tx_size_128_to_255_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_255)},
+	{"tx_size_256_to_511_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_511)},
+	{"tx_size_512_to_1023_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_1023)},
+	{"tx_size_1024_to_1522_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_1522)},
+	{"tx_size_1523_to_max_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_big)},
+	{"rx_flow_director_atr_match_packets",
+		offsetof(struct i40e_hw_port_stats, fd_atr_match)},
+	{"rx_flow_director_sb_match_packets",
+		offsetof(struct i40e_hw_port_stats, fd_sb_match)},
+	{"tx_low_power_idle_status", offsetof(struct i40e_hw_port_stats,
+		tx_lpi_status)},
+	{"rx_low_power_idle_status", offsetof(struct i40e_hw_port_stats,
+		rx_lpi_status)},
+	{"tx_low_power_idle_count", offsetof(struct i40e_hw_port_stats,
+		tx_lpi_count)},
+	{"rx_low_power_idle_count", offsetof(struct i40e_hw_port_stats,
+		rx_lpi_count)},
+
+	/* priority_xon_rx[8] */
+	{"tx_q0_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_tx[0])},
+	{"tx_q1_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_tx[1])},
+	{"tx_q2_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_tx[2])},
+	{"tx_q3_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_tx[3])},
+	{"tx_q4_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_tx[4])},
+	{"tx_q5_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_tx[5])},
+	{"tx_q6_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_tx[6])},
+	{"tx_q7_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_tx[7])},
+
+	/* priority_xon_rx[8] */
+	{"rx_q0_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_rx[0])},
+	{"rx_q1_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_rx[1])},
+	{"rx_q2_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_rx[2])},
+	{"rx_q3_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_rx[3])},
+	{"rx_q4_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_rx[4])},
+	{"rx_q5_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_rx[5])},
+	{"rx_q6_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_rx[6])},
+	{"rx_q7_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_rx[7])},
+
+	/* priority_xoff_tx[8] */
+	{"tx_q0_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_tx[0])},
+	{"tx_q1_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_tx[1])},
+	{"tx_q2_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_tx[2])},
+	{"tx_q3_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_tx[3])},
+	{"tx_q4_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_tx[4])},
+	{"tx_q5_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_tx[5])},
+	{"tx_q6_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_tx[6])},
+	{"tx_q7_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_tx[7])},
+
+	/* priority_xoff_rx[8] */
+	{"rx_q0_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_rx[0])},
+	{"rx_q1_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_rx[1])},
+	{"rx_q2_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_rx[2])},
+	{"rx_q3_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_rx[3])},
+	{"rx_q4_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_rx[4])},
+	{"rx_q5_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_rx[5])},
+	{"rx_q6_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_rx[6])},
+	{"rx_q7_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_rx[7])},
+
+	/* priority_xon_2_xoff[8] */
+	{"xx_q0_xon_to_xoff_priority_packets",
+		offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[0])},
+	{"xx_q1_xon_to_xoff_priority_packets",
+		offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[1])},
+	{"xx_q2_xon_to_xoff_priority_packets",
+		offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[2])},
+	{"xx_q3_xon_to_xoff_priority_packets",
+		offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[3])},
+	{"xx_q4_xon_to_xoff_priority_packets",
+		offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[4])},
+	{"xx_q5_xon_to_xoff_priority_packets",
+		offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[5])},
+	{"xx_q6_xon_to_xoff_priority_packets",
+		offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[6])},
+	{"xx_q7_xon_to_xoff_priority_packets",
+		offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[7])},
+};
+
+#define I40E_NB_ETH_XSTATS (sizeof(rte_i40e_stats_strings) / \
+		sizeof(rte_i40e_stats_strings[0]))
+#define I40E_NB_HW_PORT_XSTATS (sizeof(rte_i40e_hw_port_strings) / \
+		sizeof(rte_i40e_hw_port_strings[0]))
+#define I40E_NB_XSTATS (I40E_NB_ETH_XSTATS + I40E_NB_HW_PORT_XSTATS)
+
 static struct eth_driver rte_i40e_pmd = {
 	.pci_drv = {
 		.name = "rte_i40e_pmd",
@@ -1322,16 +1513,12 @@ i40e_update_vsi_stats(struct i40e_vsi *vsi)
 		    vsi->vsi_id);
 }
 
-/* Get all statistics of a port */
 static void
-i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw)
 {
-	uint32_t i;
-	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	unsigned int i;
 	struct i40e_hw_port_stats *ns = &pf->stats; /* new stats */
 	struct i40e_hw_port_stats *os = &pf->stats_offset; /* old stats */
-
 	/* Get statistics of struct i40e_eth_stats */
 	i40e_stat_update_48(hw, I40E_GLPRT_GORCH(hw->port),
 			    I40E_GLPRT_GORCL(hw->port),
@@ -1508,8 +1695,21 @@ i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 
 	pf->offset_loaded = true;
 
-	if (pf->main_vsi)
+	if(pf->main_vsi)
 		i40e_update_vsi_stats(pf->main_vsi);
+}
+
+/* Get all statistics of a port */
+static void
+i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct i40e_hw_port_stats *ns = &pf->stats; /* new stats */
+	unsigned i;
+
+	/* call read registers - updates values, now write them to struct */
+	i40e_read_stats_registers(pf, hw);
 
 	stats->ipackets = ns->eth.rx_unicast + ns->eth.rx_multicast +
 						ns->eth.rx_broadcast;
@@ -1599,6 +1799,60 @@ i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	PMD_DRV_LOG(DEBUG, "***************** PF stats end ********************");
 }
 
+static void
+i40e_dev_xstats_reset(struct rte_eth_dev *dev)
+{
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct i40e_hw_port_stats *hw_stats = &pf->stats;
+
+	/* The hw registers are cleared on read */
+	pf->offset_loaded = false;
+	i40e_read_stats_registers(pf, hw);
+
+	/* reset software counters */
+	memset(hw_stats, 0, sizeof(*hw_stats));
+}
+
+static int
+i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		    unsigned n)
+{
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	unsigned i, count = 0;
+	struct i40e_hw_port_stats *hw_stats = &pf->stats;
+
+	if(n < I40E_NB_XSTATS)
+		return I40E_NB_XSTATS;
+
+	i40e_read_stats_registers(pf, hw);
+
+	/* Reset */
+	if(xstats == NULL)
+		return 0;
+
+	/* copy from i40e_eth_stats struct */
+	for(i = 0; i < I40E_NB_ETH_XSTATS; i++) {
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "%s", rte_i40e_stats_strings[i].name);
+		xstats[count].value = *(uint64_t *)(((char *)&hw_stats->eth) +
+			rte_i40e_stats_strings[i].offset);
+		count++;
+	}
+
+	/* copy from i40e_hw_port struct */
+	for(i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) {
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "%s", rte_i40e_hw_port_strings[i].name);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				rte_i40e_hw_port_strings[i].offset);
+		count++;
+	}
+
+	return I40E_NB_XSTATS;
+}
+
 /* Reset the statistics */
 static void
 i40e_dev_stats_reset(struct rte_eth_dev *dev)
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v2 10/11] i40evf: add xstats() implementation
  2015-09-30  9:40 [dpdk-dev] [PATCH v2 00/11] Port XStats Harry van Haaren
                   ` (8 preceding siblings ...)
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 09/11] i40e: add xstats() implementation Harry van Haaren
@ 2015-09-30  9:40 ` Harry van Haaren
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 11/11] fm10k: " Harry van Haaren
  10 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-09-30  9:40 UTC (permalink / raw)
  To: dev

Add implementation of xstats() functions in i40evf PMD.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/i40e/i40e_ethdev_vf.c | 89 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 86 insertions(+), 3 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index b694400..3181400 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -112,6 +112,9 @@ static int i40evf_dev_link_update(struct rte_eth_dev *dev,
 				  __rte_unused int wait_to_complete);
 static void i40evf_dev_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *stats);
+static int i40evf_dev_xstats_get(struct rte_eth_dev *dev,
+				 struct rte_eth_xstats *xstats, unsigned n);
+static void i40evf_dev_xstats_reset(struct rte_eth_dev *dev);
 static int i40evf_vlan_filter_set(struct rte_eth_dev *dev,
 				  uint16_t vlan_id, int on);
 static void i40evf_vlan_offload_set(struct rte_eth_dev *dev, int mask);
@@ -148,6 +151,30 @@ static int i40evf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 /* Default hash key buffer for RSS */
 static uint32_t rss_key_default[I40E_VFQF_HKEY_MAX_INDEX + 1];
 
+struct rte_i40evf_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	unsigned offset;
+};
+
+static const struct rte_i40evf_xstats_name_off rte_i40evf_stats_strings[] = {
+	{"rx_bytes", offsetof(struct i40e_eth_stats, rx_bytes)},
+	{"rx_unicast_packets", offsetof(struct i40e_eth_stats, rx_unicast)},
+	{"rx_multicast_packets", offsetof(struct i40e_eth_stats, rx_multicast)},
+	{"rx_broadcast_packets", offsetof(struct i40e_eth_stats, rx_broadcast)},
+	{"rx_dropped_packets", offsetof(struct i40e_eth_stats, rx_discards)},
+	{"rx_unknown_protocol_packets", offsetof(struct i40e_eth_stats,
+		rx_unknown_protocol)},
+	{"tx_bytes", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_unicast_packets", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_multicast_packets", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_broadcast_packets", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_dropped_packets", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_error_packets", offsetof(struct i40e_eth_stats, tx_bytes)},
+};
+
+#define I40EVF_NB_XSTATS (sizeof(rte_i40evf_stats_strings) / \
+		sizeof(rte_i40evf_stats_strings[0]))
+
 static const struct eth_dev_ops i40evf_eth_dev_ops = {
 	.dev_configure        = i40evf_dev_configure,
 	.dev_start            = i40evf_dev_start,
@@ -158,6 +185,8 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = {
 	.allmulticast_disable = i40evf_dev_allmulticast_disable,
 	.link_update          = i40evf_dev_link_update,
 	.stats_get            = i40evf_dev_stats_get,
+	.xstats_get           = i40evf_dev_xstats_get,
+	.xstats_reset         = i40evf_dev_xstats_reset,
 	.dev_close            = i40evf_dev_close,
 	.dev_infos_get        = i40evf_dev_info_get,
 	.vlan_filter_set      = i40evf_vlan_filter_set,
@@ -888,11 +917,10 @@ i40evf_del_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 }
 
 static int
-i40evf_get_statics(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+i40evf_update_stats(struct rte_eth_dev *dev, struct i40e_eth_stats **pstats)
 {
 	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 	struct i40e_virtchnl_queue_select q_stats;
-	struct i40e_eth_stats *pstats;
 	int err;
 	struct vf_cmd_info args;
 
@@ -907,9 +935,23 @@ i40evf_get_statics(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	err = i40evf_execute_vf_cmd(dev, &args);
 	if (err) {
 		PMD_DRV_LOG(ERR, "fail to execute command OP_GET_STATS");
+		*pstats = NULL;
 		return err;
 	}
-	pstats = (struct i40e_eth_stats *)args.out_buffer;
+	*pstats = (struct i40e_eth_stats *)args.out_buffer;
+	return 0;
+}
+
+static int
+i40evf_get_statics(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+	int ret;
+	struct i40e_eth_stats *pstats = NULL;
+
+	ret = i40evf_update_stats(dev, &pstats);
+	if(ret != 0)
+		return 0;
+
 	stats->ipackets = pstats->rx_unicast + pstats->rx_multicast +
 						pstats->rx_broadcast;
 	stats->opackets = pstats->tx_broadcast + pstats->tx_multicast +
@@ -922,6 +964,47 @@ i40evf_get_statics(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	return 0;
 }
 
+static void
+i40evf_dev_xstats_reset(struct rte_eth_dev *dev)
+{
+	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+	struct i40e_eth_stats *pstats = NULL;
+
+	/* read stat values to clear hardware registers */
+	i40evf_update_stats(dev, &pstats);
+
+	/* set stats offset base on current values */
+	vf->vsi.eth_stats_offset = vf->vsi.eth_stats;
+}
+
+static int i40evf_dev_xstats_get(struct rte_eth_dev *dev,
+				 struct rte_eth_xstats *xstats, unsigned n)
+{
+	int ret;
+	unsigned i;
+	struct i40e_eth_stats *pstats = NULL;
+
+	if(n < I40EVF_NB_XSTATS)
+		return I40EVF_NB_XSTATS;
+
+	ret = i40evf_update_stats(dev, &pstats);
+	if(ret != 0)
+		return 0;
+
+	if(!xstats)
+		return 0;
+
+	/* loop over xstats array and values from pstats */
+	for(i = 0; i < I40EVF_NB_XSTATS; i++) {
+		snprintf(xstats[i].name, sizeof(xstats[i].name),
+			 "%s", rte_i40evf_stats_strings[i].name);
+		xstats[i].value = *(uint64_t *)(((char *)pstats) +
+			rte_i40evf_stats_strings[i].offset);
+	}
+
+	return I40EVF_NB_XSTATS;
+}
+
 static int
 i40evf_add_vlan(struct rte_eth_dev *dev, uint16_t vlanid)
 {
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v2 11/11] fm10k: add xstats() implementation
  2015-09-30  9:40 [dpdk-dev] [PATCH v2 00/11] Port XStats Harry van Haaren
                   ` (9 preceding siblings ...)
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 10/11] i40evf: " Harry van Haaren
@ 2015-09-30  9:40 ` Harry van Haaren
  10 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-09-30  9:40 UTC (permalink / raw)
  To: dev

Add xstats() functions and statistic strings.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/fm10k/fm10k_ethdev.c | 69 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index a69c990..2d92fd3 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -68,6 +68,37 @@ fm10k_MACVLAN_remove_all(struct rte_eth_dev *dev);
 static void fm10k_tx_queue_release(void *queue);
 static void fm10k_rx_queue_release(void *queue);
 
+struct rte_fm10k_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	unsigned offset;
+};
+
+struct rte_fm10k_xstats_name_off rte_fm10k_hw_stats_strings[] = {
+	{"completion_timeout_count", offsetof(struct fm10k_hw_stats, timeout)},
+	{"unsupported_requests_count", offsetof(struct fm10k_hw_stats, ur)},
+	{"completer_abort_count", offsetof(struct fm10k_hw_stats, ca)},
+	{"unsupported_message_count", offsetof(struct fm10k_hw_stats, um)},
+	{"checksum_error_count", offsetof(struct fm10k_hw_stats, xec)},
+	{"vlan_dropped", offsetof(struct fm10k_hw_stats, vlan_drop)},
+	{"loopback_dropped", offsetof(struct fm10k_hw_stats, loopback_drop)},
+	{"no_descriptor_dropped", offsetof(struct fm10k_hw_stats, nodesc_drop)},
+};
+
+struct rte_fm10k_xstats_name_off rte_fm10k_hw_stats_q_strings[] = {
+	{"tx_q_bytes", offsetof(struct fm10k_hw_stats_q, tx_bytes)},
+	{"tx_q_packets", offsetof(struct fm10k_hw_stats_q, tx_packets)},
+	{"rx_q_bytes", offsetof(struct fm10k_hw_stats_q, rx_bytes)},
+	{"rx_q_packets", offsetof(struct fm10k_hw_stats_q, rx_packets)},
+	{"rx_q_dropped", offsetof(struct fm10k_hw_stats_q, rx_drops)},
+};
+
+#define FM10K_NB_HW_XSTATS (sizeof(rte_fm10k_hw_stats_strings) / \
+		sizeof(rte_fm10k_hw_stats_strings[0]))
+#define FM10K_NB_Q_XSTATS (sizeof(rte_fm10k_hw_stats_q_strings) / \
+		sizeof(rte_fm10k_hw_stats_q_strings[0]))
+#define FM10K_NB_XSTATS (FM10K_NB_HW_XSTATS + FM10K_NB_Q_XSTATS * \
+		FM10K_MAX_QUEUES_PF)
+
 static void
 fm10k_mbx_initlock(struct fm10k_hw *hw)
 {
@@ -867,6 +898,42 @@ fm10k_link_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static int
+fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		 unsigned n)
+{
+	struct fm10k_hw_stats *hw_stats =
+		FM10K_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+	unsigned i, q, count = 0;
+
+	if(n < FM10K_NB_XSTATS)
+		return FM10K_NB_XSTATS;
+
+	/* Global stats */
+	for(i = 0; i < FM10K_NB_HW_XSTATS; i++) {
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "%s", rte_fm10k_hw_stats_strings[count].name);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+			rte_fm10k_hw_stats_strings[count].offset);
+		count++;
+	}
+
+	/* PF queue stats */
+	for(q = 0; q < FM10K_MAX_QUEUES_PF; q++) {
+		for(i = 0; i < FM10K_NB_Q_XSTATS; i++) {
+			snprintf(xstats[count].name, sizeof(xstats[count].name),
+				 "rx_q%u_%s", q,
+				 rte_fm10k_hw_stats_q_strings[i].name);
+			xstats[count].value =
+				*(uint64_t *)(((char *)&hw_stats->q[q]) +
+				rte_fm10k_hw_stats_q_strings[i].offset);
+			count++;
+		}
+	}
+
+	return FM10K_NB_XSTATS;
+}
+
 static void
 fm10k_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 {
@@ -2034,7 +2101,9 @@ static const struct eth_dev_ops fm10k_eth_dev_ops = {
 	.allmulticast_enable    = fm10k_dev_allmulticast_enable,
 	.allmulticast_disable   = fm10k_dev_allmulticast_disable,
 	.stats_get		= fm10k_stats_get,
+	.xstats_get		= fm10k_xstats_get,
 	.stats_reset		= fm10k_stats_reset,
+	.xstats_reset		= fm10k_stats_reset,
 	.link_update		= fm10k_link_update,
 	.dev_infos_get		= fm10k_dev_infos_get,
 	.vlan_filter_set	= fm10k_vlan_filter_set,
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v2 04/11] virtio: add xstats() implementation
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 04/11] virtio: add xstats() implementation Harry van Haaren
@ 2015-09-30 17:44   ` Stephen Hemminger
  2015-10-01  8:00     ` Van Haaren, Harry
  0 siblings, 1 reply; 77+ messages in thread
From: Stephen Hemminger @ 2015-09-30 17:44 UTC (permalink / raw)
  To: Harry van Haaren; +Cc: dev

On Wed, 30 Sep 2015 10:40:15 +0100
Harry van Haaren <harry.van.haaren@intel.com> wrote:

> +/* [rt]x_qX_ is prepended to the name string here */
> +static const struct rte_virtio_xstats_name_off rte_virtio_q_stat_strings[] = {
> +	{"packets", offsetof(struct virtqueue, packets)},
> +	{"bytes", offsetof(struct virtqueue, bytes)},
> +	{"errors", offsetof(struct virtqueue, errors)},
> +}

I don't see the point of this. The point of xstats is to tell the application
about statistics not available through other means.

These stats should be available already in the per queue stats.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v2 04/11] virtio: add xstats() implementation
  2015-09-30 17:44   ` Stephen Hemminger
@ 2015-10-01  8:00     ` Van Haaren, Harry
  0 siblings, 0 replies; 77+ messages in thread
From: Van Haaren, Harry @ 2015-10-01  8:00 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> > +/* [rt]x_qX_ is prepended to the name string here */ static const
> > +struct rte_virtio_xstats_name_off rte_virtio_q_stat_strings[] = {
> > +	{"packets", offsetof(struct virtqueue, packets)},
> > +	{"bytes", offsetof(struct virtqueue, bytes)},
> > +	{"errors", offsetof(struct virtqueue, errors)}, }
> 
> I don't see the point of this. The point of xstats is to tell the application about
> statistics not available through other means.
>
> These stats should be available already in the per queue stats.

You're right - these stats are already available in the per-Q stats part of rte_eth_stats.
The virtio implementation of xstats is mostly framework code so we can add other
stats, for example packet size counters, in the near future.

Thanks for reviewing, -Harry

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v3 00/11] Port XStats
  2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 01/11] doc: add extended statistics notes Harry van Haaren
@ 2015-10-22 15:48   ` Harry van Haaren
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 01/11] doc: add extended statistics notes Harry van Haaren
                       ` (11 more replies)
  0 siblings, 12 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-10-22 15:48 UTC (permalink / raw)
  To: dev

This patchset adds an implementation of the xstats_get() and xstats_reset() API
to the following PMDs: virtio, igb, igbvf, ixgbe, ixgbevf, i40e, i40evf and
fm10k.

The xstats API allows DPDK apps to gain access to extended statistics from each
port on a NIC. These statistics are structured as per a scheme detailed in the
patch for the doc/prog_guide.


Harry van Haaren (11):
  doc: add extended statistics notes
  doc: add extended statistics to prog_guide
  ethdev: update xstats_get() strings and Q handling
  virtio: add xstats() implementation
  igb: add xstats() implementation
  igbvf: add xstats() implementation
  ixgbe: update statistic strings to scheme
  ixgbevf: add xstats() functions to VF
  i40e: add xstats() implementation
  i40evf: add xstats() implementation
  fm10k: add xstats() implementation

 doc/guides/prog_guide/poll_mode_drv.rst |  51 ++++-
 doc/guides/rel_notes/release_2_2.rst    |  12 ++
 drivers/net/e1000/igb_ethdev.c          | 194 +++++++++++++++++-
 drivers/net/fm10k/fm10k_ethdev.c        |  87 ++++++++
 drivers/net/i40e/i40e_ethdev.c          | 265 +++++++++++++++++++++++-
 drivers/net/i40e/i40e_ethdev_vf.c       |  89 +++++++-
 drivers/net/ixgbe/ixgbe_ethdev.c        | 346 +++++++++++++++++++++++++++++---
 drivers/net/virtio/virtio_ethdev.c      |  98 ++++++++-
 drivers/net/virtio/virtio_rxtx.c        |  32 +++
 drivers/net/virtio/virtqueue.h          |   4 +
 lib/librte_ether/rte_ethdev.c           |  38 ++--
 11 files changed, 1154 insertions(+), 62 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v3 01/11] doc: add extended statistics notes
  2015-10-22 15:48   ` [dpdk-dev] [PATCH v3 00/11] Port XStats Harry van Haaren
@ 2015-10-22 15:48     ` Harry van Haaren
  2015-10-30 11:36       ` [dpdk-dev] [PATCH v4 00/10] Port XStats Harry van Haaren
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 02/11] doc: add extended statistics to prog_guide Harry van Haaren
                       ` (10 subsequent siblings)
  11 siblings, 1 reply; 77+ messages in thread
From: Harry van Haaren @ 2015-10-22 15:48 UTC (permalink / raw)
  To: dev

Add release notes for this patchset.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 doc/guides/rel_notes/release_2_2.rst | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/doc/guides/rel_notes/release_2_2.rst b/doc/guides/rel_notes/release_2_2.rst
index 4f75cff..fe93629 100644
--- a/doc/guides/rel_notes/release_2_2.rst
+++ b/doc/guides/rel_notes/release_2_2.rst
@@ -9,6 +9,18 @@ New Features
   *  Added support for Jumbo Frames.
   *  Optimize forwarding performance for Chelsio T5 40GbE cards.
 
+* **Extended Statistics**
+
+  Define extended statistics naming scheme to store metadata in the name
+  string name of each statistic. Implemented the extended stats API for
+  these PMDs:
+
+  * igb
+  * igbvf
+  * i40e
+  * i40evf
+  * fm10k
+  * virtio
 
 Resolved Issues
 ---------------
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v3 02/11] doc: add extended statistics to prog_guide
  2015-10-22 15:48   ` [dpdk-dev] [PATCH v3 00/11] Port XStats Harry van Haaren
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 01/11] doc: add extended statistics notes Harry van Haaren
@ 2015-10-22 15:48     ` Harry van Haaren
  2015-10-23 14:29       ` Tahhan, Maryam
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 03/11] ethdev: update xstats_get() strings and Q handling Harry van Haaren
                       ` (9 subsequent siblings)
  11 siblings, 1 reply; 77+ messages in thread
From: Harry van Haaren @ 2015-10-22 15:48 UTC (permalink / raw)
  To: dev

Add extended statistic section to the programmers
guide, poll mode driver section. This section describes
how the strings stats are formatted, and how the client
code can use this to gather information about the stat.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 doc/guides/prog_guide/poll_mode_drv.rst | 51 ++++++++++++++++++++++++++++++++-
 1 file changed, 50 insertions(+), 1 deletion(-)

diff --git a/doc/guides/prog_guide/poll_mode_drv.rst b/doc/guides/prog_guide/poll_mode_drv.rst
index 8780ba3..44cc9ce 100644
--- a/doc/guides/prog_guide/poll_mode_drv.rst
+++ b/doc/guides/prog_guide/poll_mode_drv.rst
@@ -1,5 +1,5 @@
 ..  BSD LICENSE
-    Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+    Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
     All rights reserved.
 
     Redistribution and use in source and binary forms, with or without
@@ -294,3 +294,52 @@ Ethernet Device API
 ~~~~~~~~~~~~~~~~~~~
 
 The Ethernet device API exported by the Ethernet PMDs is described in the *DPDK API Reference*.
+
+Extended Statistics API
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The extended statistics API allows each individual PMD to expose a unique set
+of statistics. The client of the API provides an array of
+``struct rte_eth_xstats`` type. Each ``struct rte_eth_xstats`` contains a
+string and value pair. The amount of xstats exposed, and position of the
+statistic in the array must remain constant during runtime.
+
+A naming scheme exists for the strings exposed to clients of the API. This is
+to allow scraping of the API for statistics of interest. The naming scheme uses
+strings split by a single underscore ``_``. The scheme is as follows:
+
+* direction
+* detail 1
+* detail 2
+* detail n
+* unit
+
+Examples of common statistics xstats strings, formatted to comply to the scheme
+proposed above:
+
+* ``rx_bytes``
+* ``rx_crc_errors``
+* ``tx_multicast_packets``
+
+The scheme, although quite simple, allows flexibility in presenting and reading
+information from the statistic strings. The following example illustrates the
+naming scheme:``rx_packets``. In this example, the string is split into two
+components. The first component ``rx`` indicates that the statistic is
+associated with the receive side of the NIC.  The second component ``packets``
+indicates that the unit of measure is packets.
+
+A more complicated example: ``tx_size_128_to_255_packets``. In this example,
+``tx`` indicates transmission, ``size``  is the first detail, ``128`` etc are
+more details, and ``packets`` indicates that this is a packet counter.
+
+Some additions in the metadata scheme are as follows:
+
+* If the first part does not match ``rx`` or ``tx``, the statistic does not
+  have an affinity with either recieve of transmit.
+
+* If the first letter of the second part is ``q`` and this ``q`` is followed
+  by a number, this statistic is part of a specific queue.
+
+An example where queue numbers are used is as follows: ``tx_q7_bytes`` which
+indicates this statistic applies to queue number 7, and represents the number
+of transmitted bytes on that queue.
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v3 03/11] ethdev: update xstats_get() strings and Q handling
  2015-10-22 15:48   ` [dpdk-dev] [PATCH v3 00/11] Port XStats Harry van Haaren
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 01/11] doc: add extended statistics notes Harry van Haaren
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 02/11] doc: add extended statistics to prog_guide Harry van Haaren
@ 2015-10-22 15:48     ` Harry van Haaren
  2015-10-23 14:35       ` Tahhan, Maryam
  2015-10-23 15:28       ` Tahhan, Maryam
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 04/11] virtio: add xstats() implementation Harry van Haaren
                       ` (8 subsequent siblings)
  11 siblings, 2 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-10-22 15:48 UTC (permalink / raw)
  To: dev

Update the strings used for presenting stats to adhere
to the scheme previously presented. Updated xstats_get()
function to handle Q information only if xstats() is not
implemented in the PMD, providing the PMD with the needed
flexibility to expose its extended Q stats.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 lib/librte_ether/rte_ethdev.c | 38 +++++++++++++++++++++++---------------
 1 file changed, 23 insertions(+), 15 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index f593f6e..07f0c26 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -137,27 +137,30 @@ struct rte_eth_xstats_name_off {
 };
 
 static const struct rte_eth_xstats_name_off rte_stats_strings[] = {
-	{"rx_packets", offsetof(struct rte_eth_stats, ipackets)},
-	{"tx_packets", offsetof(struct rte_eth_stats, opackets)},
-	{"rx_bytes", offsetof(struct rte_eth_stats, ibytes)},
-	{"tx_bytes", offsetof(struct rte_eth_stats, obytes)},
-	{"tx_errors", offsetof(struct rte_eth_stats, oerrors)},
+	{"rx_good_packets", offsetof(struct rte_eth_stats, ipackets)},
+	{"tx_good_packets", offsetof(struct rte_eth_stats, opackets)},
+	{"rx_good_bytes", offsetof(struct rte_eth_stats, ibytes)},
+	{"tx_good_bytes", offsetof(struct rte_eth_stats, obytes)},
 	{"rx_errors", offsetof(struct rte_eth_stats, ierrors)},
-	{"alloc_rx_buff_failed", offsetof(struct rte_eth_stats, rx_nombuf)},
+	{"tx_errors", offsetof(struct rte_eth_stats, oerrors)},
+	{"rx_mbuf_allocation_errors", offsetof(struct rte_eth_stats,
+		rx_nombuf)},
 };
+
 #define RTE_NB_STATS (sizeof(rte_stats_strings) / sizeof(rte_stats_strings[0]))
 
 static const struct rte_eth_xstats_name_off rte_rxq_stats_strings[] = {
-	{"rx_packets", offsetof(struct rte_eth_stats, q_ipackets)},
-	{"rx_bytes", offsetof(struct rte_eth_stats, q_ibytes)},
+	{"packets", offsetof(struct rte_eth_stats, q_ipackets)},
+	{"bytes", offsetof(struct rte_eth_stats, q_ibytes)},
+	{"errors", offsetof(struct rte_eth_stats, q_errors)},
 };
+
 #define RTE_NB_RXQ_STATS (sizeof(rte_rxq_stats_strings) /	\
 		sizeof(rte_rxq_stats_strings[0]))
 
 static const struct rte_eth_xstats_name_off rte_txq_stats_strings[] = {
-	{"tx_packets", offsetof(struct rte_eth_stats, q_opackets)},
-	{"tx_bytes", offsetof(struct rte_eth_stats, q_obytes)},
-	{"tx_errors", offsetof(struct rte_eth_stats, q_errors)},
+	{"packets", offsetof(struct rte_eth_stats, q_opackets)},
+	{"bytes", offsetof(struct rte_eth_stats, q_obytes)},
 };
 #define RTE_NB_TXQ_STATS (sizeof(rte_txq_stats_strings) /	\
 		sizeof(rte_txq_stats_strings[0]))
@@ -1666,8 +1669,6 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 
 	/* Return generic statistics */
 	count = RTE_NB_STATS;
-	count += dev->data->nb_rx_queues * RTE_NB_RXQ_STATS;
-	count += dev->data->nb_tx_queues * RTE_NB_TXQ_STATS;
 
 	/* implemented by the driver */
 	if (dev->dev_ops->xstats_get != NULL) {
@@ -1679,6 +1680,9 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 
 		if (xcount < 0)
 			return xcount;
+	} else {
+		count += dev->data->nb_rx_queues * RTE_NB_RXQ_STATS;
+		count += dev->data->nb_tx_queues * RTE_NB_TXQ_STATS;
 	}
 
 	if (n < count + xcount)
@@ -1698,6 +1702,10 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 		xstats[count++].value = val;
 	}
 
+	/* if xstats_get() is implemented by the PMD, the Q stats are done */
+	if (dev->dev_ops->xstats_get != NULL)
+		return count + xcount;
+
 	/* per-rxq stats */
 	for (q = 0; q < dev->data->nb_rx_queues; q++) {
 		for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
@@ -1706,7 +1714,7 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 					q * sizeof(uint64_t));
 			val = *stats_ptr;
 			snprintf(xstats[count].name, sizeof(xstats[count].name),
-				"rx_queue_%u_%s", q,
+				"rx_q%u_%s", q,
 				rte_rxq_stats_strings[i].name);
 			xstats[count++].value = val;
 		}
@@ -1720,7 +1728,7 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 					q * sizeof(uint64_t));
 			val = *stats_ptr;
 			snprintf(xstats[count].name, sizeof(xstats[count].name),
-				"tx_queue_%u_%s", q,
+				"tx_q%u_%s", q,
 				rte_txq_stats_strings[i].name);
 			xstats[count++].value = val;
 		}
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v3 04/11] virtio: add xstats() implementation
  2015-10-22 15:48   ` [dpdk-dev] [PATCH v3 00/11] Port XStats Harry van Haaren
                       ` (2 preceding siblings ...)
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 03/11] ethdev: update xstats_get() strings and Q handling Harry van Haaren
@ 2015-10-22 15:48     ` Harry van Haaren
  2015-10-29 16:19       ` Tahhan, Maryam
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 05/11] igb: " Harry van Haaren
                       ` (7 subsequent siblings)
  11 siblings, 1 reply; 77+ messages in thread
From: Harry van Haaren @ 2015-10-22 15:48 UTC (permalink / raw)
  To: dev

Add xstats() functions and statistic strings to virtio PMD.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 98 +++++++++++++++++++++++++++++++++++++-
 drivers/net/virtio/virtio_rxtx.c   | 32 +++++++++++++
 drivers/net/virtio/virtqueue.h     |  4 ++
 3 files changed, 132 insertions(+), 2 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 02f698a..c97d6e9 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -80,7 +80,10 @@ static int virtio_dev_link_update(struct rte_eth_dev *dev,
 static void virtio_set_hwaddr(struct virtio_hw *hw);
 static void virtio_get_hwaddr(struct virtio_hw *hw);
 
-static void virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats);
+static void virtio_dev_stats_get(struct rte_eth_dev *dev,
+				 struct rte_eth_stats *stats);
+static int virtio_dev_xstats_get(struct rte_eth_dev *dev,
+				 struct rte_eth_xstats *xstats, unsigned n);
 static void virtio_dev_stats_reset(struct rte_eth_dev *dev);
 static void virtio_dev_free_mbufs(struct rte_eth_dev *dev);
 static int virtio_vlan_filter_set(struct rte_eth_dev *dev,
@@ -109,6 +112,31 @@ static const struct rte_pci_id pci_id_virtio_map[] = {
 { .vendor_id = 0, /* sentinel */ },
 };
 
+struct rte_virtio_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	unsigned offset;
+};
+
+/* [rt]x_qX_ is prepended to the name string here */
+static const struct rte_virtio_xstats_name_off rte_virtio_q_stat_strings[] = {
+	{"good_packets",           offsetof(struct virtqueue, packets)},
+	{"good_bytes",             offsetof(struct virtqueue, bytes)},
+	{"errors",                 offsetof(struct virtqueue, errors)},
+	{"multicast_packets",      offsetof(struct virtqueue, multicast)},
+	{"broadcast_packets",      offsetof(struct virtqueue, broadcast)},
+	{"undersize_packets",      offsetof(struct virtqueue, size_bins[0])},
+	{"size_64_packets",        offsetof(struct virtqueue, size_bins[1])},
+	{"size_65_127_packets",    offsetof(struct virtqueue, size_bins[2])},
+	{"size_128_255_packets",   offsetof(struct virtqueue, size_bins[3])},
+	{"size_256_511_packets",   offsetof(struct virtqueue, size_bins[4])},
+	{"size_512_1023_packets",  offsetof(struct virtqueue, size_bins[5])},
+	{"size_1024_1517_packets", offsetof(struct virtqueue, size_bins[6])},
+	{"size_1518_max_packets",  offsetof(struct virtqueue, size_bins[7])},
+};
+
+#define VIRTIO_NB_Q_XSTATS (sizeof(rte_virtio_q_stat_strings) / \
+			    sizeof(rte_virtio_q_stat_strings[0]))
+
 static int
 virtio_send_command(struct virtqueue *vq, struct virtio_pmd_ctrl *ctrl,
 		int *dlen, int pkt_num)
@@ -568,7 +596,9 @@ static const struct eth_dev_ops virtio_eth_dev_ops = {
 
 	.dev_infos_get           = virtio_dev_info_get,
 	.stats_get               = virtio_dev_stats_get,
+	.xstats_get              = virtio_dev_xstats_get,
 	.stats_reset             = virtio_dev_stats_reset,
+	.xstats_reset            = virtio_dev_stats_reset,
 	.link_update             = virtio_dev_link_update,
 	.rx_queue_setup          = virtio_dev_rx_queue_setup,
 	.rx_queue_release        = virtio_dev_rx_queue_release,
@@ -623,7 +653,7 @@ virtio_dev_atomic_write_link_status(struct rte_eth_dev *dev,
 }
 
 static void
-virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+virtio_update_stats(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 {
 	unsigned i;
 
@@ -660,6 +690,64 @@ virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed;
 }
 
+static int
+virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		      unsigned n)
+{
+	unsigned i;
+	unsigned count = 0;
+
+	unsigned nstats = dev->data->nb_tx_queues * VIRTIO_NB_Q_XSTATS +
+		dev->data->nb_rx_queues * VIRTIO_NB_Q_XSTATS;
+
+	if(n < nstats)
+		return nstats;
+
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		struct virtqueue *rxvq = dev->data->rx_queues[i];
+
+		if(rxvq == NULL)
+			continue;
+
+		unsigned t;
+
+		for(t = 0; t < VIRTIO_NB_Q_XSTATS; t++) {
+			snprintf(xstats[count].name, sizeof(xstats[count].name),
+				 "rx_q%u_%s", i,
+				 rte_virtio_q_stat_strings[t].name);
+			xstats[count].value = *(uint64_t *)(((char *)rxvq) +
+				rte_virtio_q_stat_strings[t].offset);
+			count++;
+		}
+	}
+
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
+		struct virtqueue *txvq = dev->data->tx_queues[i];
+
+		if(txvq == NULL)
+			continue;
+
+		unsigned t;
+
+		for(t = 0; t < VIRTIO_NB_Q_XSTATS; t++) {
+			snprintf(xstats[count].name, sizeof(xstats[count].name),
+				 "tx_q%u_%s", i,
+				 rte_virtio_q_stat_strings[t].name);
+			xstats[count].value = *(uint64_t *)(((char *)txvq) +
+				rte_virtio_q_stat_strings[t].offset);
+			count++;
+		}
+	}
+
+	return count;
+}
+
+static void
+virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+	virtio_update_stats(dev, stats);
+}
+
 static void
 virtio_dev_stats_reset(struct rte_eth_dev *dev)
 {
@@ -673,6 +761,9 @@ virtio_dev_stats_reset(struct rte_eth_dev *dev)
 		txvq->packets = 0;
 		txvq->bytes = 0;
 		txvq->errors = 0;
+		txvq->multicast = 0;
+		txvq->broadcast = 0;
+		memset(txvq->size_bins, 0, sizeof(txvq->size_bins[0]) * 8);
 	}
 
 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
@@ -683,6 +774,9 @@ virtio_dev_stats_reset(struct rte_eth_dev *dev)
 		rxvq->packets = 0;
 		rxvq->bytes = 0;
 		rxvq->errors = 0;
+		rxvq->multicast = 0;
+		rxvq->broadcast = 0;
+		memset(rxvq->size_bins, 0, sizeof(rxvq->size_bins[0]) * 8);
 	}
 
 	dev->data->rx_mbuf_alloc_failed = 0;
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index d35c5f9..a615916 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -482,6 +482,34 @@ virtio_discard_rxbuf(struct virtqueue *vq, struct rte_mbuf *m)
 	}
 }
 
+static void
+virtio_update_packet_stats(struct virtqueue *vq, struct rte_mbuf *mbuf)
+{
+	uint32_t s = mbuf->pkt_len;
+	struct ether_addr *ea;
+
+	if(s == 64) {
+		vq->size_bins[1]++;
+	} else if(s > 64 && s < 1024) {
+		uint32_t bin;
+
+		/* count zeros, and offset into correct bin */
+		bin = (sizeof(s) * 8) - __builtin_clz(s) - 5;
+		vq->size_bins[bin]++;
+	} else {
+		if(s < 64)
+			vq->size_bins[0]++;
+		else if(s < 1519)
+			vq->size_bins[6]++;
+		else if(s >= 1519)
+			vq->size_bins[7]++;
+	}
+
+	ea = rte_pktmbuf_mtod(mbuf, struct ether_addr *);
+	vq->multicast += is_multicast_ether_addr(ea);
+	vq->broadcast += is_broadcast_ether_addr(ea);
+}
+
 #define VIRTIO_MBUF_BURST_SZ 64
 #define DESC_PER_CACHELINE (RTE_CACHE_LINE_SIZE / sizeof(struct vring_desc))
 uint16_t
@@ -543,7 +571,9 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 		VIRTIO_DUMP_PACKET(rxm, rxm->data_len);
 
 		rx_pkts[nb_rx++] = rxm;
+
 		rxvq->bytes += rx_pkts[nb_rx - 1]->pkt_len;
+		virtio_update_packet_stats(rxvq, rxm);
 	}
 
 	rxvq->packets += nb_rx;
@@ -706,6 +736,7 @@ virtio_recv_mergeable_pkts(void *rx_queue,
 			rx_pkts[nb_rx]->data_len);
 
 		rxvq->bytes += rx_pkts[nb_rx]->pkt_len;
+		virtio_update_packet_stats(rxvq, rx_pkts[nb_rx]);
 		nb_rx++;
 	}
 
@@ -806,6 +837,7 @@ virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 			}
 			nb_tx++;
 			txvq->bytes += txm->pkt_len;
+			virtio_update_packet_stats(txvq, txm);
 		} else {
 			PMD_TX_LOG(ERR, "No free tx descriptors to transmit");
 			break;
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 7789411..9032e6d 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -194,6 +194,10 @@ struct virtqueue {
 	uint64_t	packets;
 	uint64_t	bytes;
 	uint64_t	errors;
+	uint64_t	multicast;
+	uint64_t	broadcast;
+	/* Size bins in array as RFC 2819, undersized [0], 64 [1], etc */
+	uint64_t	size_bins[8];
 
 	struct vq_desc_extra {
 		void              *cookie;
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v3 05/11] igb: add xstats() implementation
  2015-10-22 15:48   ` [dpdk-dev] [PATCH v3 00/11] Port XStats Harry van Haaren
                       ` (3 preceding siblings ...)
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 04/11] virtio: add xstats() implementation Harry van Haaren
@ 2015-10-22 15:48     ` Harry van Haaren
  2015-10-23 14:56       ` Tahhan, Maryam
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 06/11] igbvf: " Harry van Haaren
                       ` (6 subsequent siblings)
  11 siblings, 1 reply; 77+ messages in thread
From: Harry van Haaren @ 2015-10-22 15:48 UTC (permalink / raw)
  To: dev

Add xstats_get() and xstats_reset() functions to igb
driver, and the neccessary strings to expose these
NIC statistics.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/e1000/igb_ethdev.c | 136 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 131 insertions(+), 5 deletions(-)

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 2b081b1..afa4cb4 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -96,7 +96,10 @@ static int  eth_igb_link_update(struct rte_eth_dev *dev,
 				int wait_to_complete);
 static void eth_igb_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *rte_stats);
+static int eth_igb_xstats_get(struct rte_eth_dev *dev,
+			      struct rte_eth_xstats *xstats, unsigned n);
 static void eth_igb_stats_reset(struct rte_eth_dev *dev);
+static void eth_igb_xstats_reset(struct rte_eth_dev *dev);
 static void eth_igb_infos_get(struct rte_eth_dev *dev,
 			      struct rte_eth_dev_info *dev_info);
 static void eth_igbvf_infos_get(struct rte_eth_dev *dev,
@@ -292,7 +295,9 @@ static const struct eth_dev_ops eth_igb_ops = {
 	.allmulticast_disable = eth_igb_allmulticast_disable,
 	.link_update          = eth_igb_link_update,
 	.stats_get            = eth_igb_stats_get,
+	.xstats_get           = eth_igb_xstats_get,
 	.stats_reset          = eth_igb_stats_reset,
+	.xstats_reset         = eth_igb_xstats_reset,
 	.dev_infos_get        = eth_igb_infos_get,
 	.mtu_set              = eth_igb_mtu_set,
 	.vlan_filter_set      = eth_igb_vlan_filter_set,
@@ -354,6 +359,77 @@ static const struct eth_dev_ops igbvf_eth_dev_ops = {
 	.get_reg              = igbvf_get_regs,
 };
 
+/* store statistics names and its offset in stats structure */
+struct rte_igb_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	unsigned offset;
+};
+
+static const struct rte_igb_xstats_name_off rte_igb_stats_strings[] = {
+	{"rx_crc_errors", offsetof(struct e1000_hw_stats, crcerrs)},
+	{"rx_align_errors", offsetof(struct e1000_hw_stats, algnerrc)},
+	{"rx_symbol_errors", offsetof(struct e1000_hw_stats, symerrs)},
+	{"rx_missed_packets", offsetof(struct e1000_hw_stats, mpc)},
+	{"tx_single_collision_packets", offsetof(struct e1000_hw_stats, scc)},
+	{"tx_multiple_collision_packets", offsetof(struct e1000_hw_stats, mcc)},
+	{"tx_excessive_collision_packets", offsetof(struct e1000_hw_stats,
+		ecol)},
+	{"tx_late_collisions", offsetof(struct e1000_hw_stats, latecol)},
+	{"tx_total_collisions", offsetof(struct e1000_hw_stats, colc)},
+	{"tx_deferred_packets", offsetof(struct e1000_hw_stats, dc)},
+	{"tx_no_carrier_sense_packets", offsetof(struct e1000_hw_stats, tncrs)},
+	{"rx_carrier_ext_errors", offsetof(struct e1000_hw_stats, cexterr)},
+	{"rx_length_errors", offsetof(struct e1000_hw_stats, rlec)},
+	{"rx_xon_packets", offsetof(struct e1000_hw_stats, xonrxc)},
+	{"tx_xon_packets", offsetof(struct e1000_hw_stats, xontxc)},
+	{"rx_xoff_packets", offsetof(struct e1000_hw_stats, xoffrxc)},
+	{"tx_xoff_packets", offsetof(struct e1000_hw_stats, xofftxc)},
+	{"rx_flow_control_unsupported_packets", offsetof(struct e1000_hw_stats,
+		fcruc)},
+	{"rx_size_64_packets", offsetof(struct e1000_hw_stats, prc64)},
+	{"rx_size_65_to_127_packets", offsetof(struct e1000_hw_stats, prc127)},
+	{"rx_size_128_to_255_packets", offsetof(struct e1000_hw_stats, prc255)},
+	{"rx_size_256_to_511_packets", offsetof(struct e1000_hw_stats, prc511)},
+	{"rx_size_512_to_1023_packets", offsetof(struct e1000_hw_stats,
+		prc1023)},
+	{"rx_size_1024_to_max_packets", offsetof(struct e1000_hw_stats,
+		prc1522)},
+	{"rx_broadcast_packets", offsetof(struct e1000_hw_stats, bprc)},
+	{"rx_multicast_packets", offsetof(struct e1000_hw_stats, mprc)},
+	{"rx_no_buffer_errors", offsetof(struct e1000_hw_stats, rnbc)},
+	{"rx_undersize_packets", offsetof(struct e1000_hw_stats, ruc)},
+	{"rx_fragment_packets", offsetof(struct e1000_hw_stats, rfc)},
+	{"rx_oversize_packets", offsetof(struct e1000_hw_stats, roc)},
+	{"rx_jabber_packets", offsetof(struct e1000_hw_stats, rjc)},
+	{"rx_management_packets", offsetof(struct e1000_hw_stats, mgprc)},
+	{"rx_management_dropped", offsetof(struct e1000_hw_stats, mgpdc)},
+	{"tx_management_packets", offsetof(struct e1000_hw_stats, mgptc)},
+	{"rx_total_packets", offsetof(struct e1000_hw_stats, tpr)},
+	{"tx_total_packets", offsetof(struct e1000_hw_stats, tpt)},
+	{"rx_total_bytes", offsetof(struct e1000_hw_stats, tor)},
+	{"tx_total_bytes", offsetof(struct e1000_hw_stats, tot)},
+	{"tx_size_64_packets", offsetof(struct e1000_hw_stats, ptc64)},
+	{"tx_size_65_to_127_packets", offsetof(struct e1000_hw_stats, ptc127)},
+	{"tx_size_128_to_255_packets", offsetof(struct e1000_hw_stats, ptc255)},
+	{"tx_size_256_to_511_packets", offsetof(struct e1000_hw_stats, ptc511)},
+	{"tx_size_512_to_1023_packets", offsetof(struct e1000_hw_stats,
+		ptc1023)},
+	{"tx_size_1023_to_max_packets", offsetof(struct e1000_hw_stats,
+		ptc1522)},
+	{"tx_multicast_packets", offsetof(struct e1000_hw_stats, mptc)},
+	{"tx_broadcast_packets", offsetof(struct e1000_hw_stats, bptc)},
+	{"tx_tso_packets", offsetof(struct e1000_hw_stats, tsctc)},
+	{"tx_tso_errors", offsetof(struct e1000_hw_stats, tsctfc)},
+	{"rx_sent_to_host_packets", offsetof(struct e1000_hw_stats, rpthc)},
+	{"tx_sent_by_host_packets", offsetof(struct e1000_hw_stats, hgptc)},
+	{"rx_code_violation_packets", offsetof(struct e1000_hw_stats, scvpc)},
+
+	{"interrupt_assert_count", offsetof(struct e1000_hw_stats, iac)},
+};
+
+#define IGB_NB_XSTATS (sizeof(rte_igb_stats_strings) / \
+		sizeof(rte_igb_stats_strings[0]))
+
 /**
  * Atomically reads the link status information from global
  * structure rte_eth_dev.
@@ -1257,11 +1333,8 @@ igb_hardware_init(struct e1000_hw *hw)
 
 /* This function is based on igb_update_stats_counters() in igb/if_igb.c */
 static void
-eth_igb_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
+igb_read_stats_registers(struct e1000_hw *hw, struct e1000_hw_stats *stats)
 {
-	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	struct e1000_hw_stats *stats =
-			E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
 	int pause_frames;
 
 	if(hw->phy.media_type == e1000_media_type_copper ||
@@ -1367,6 +1440,16 @@ eth_igb_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
 	stats->cexterr += E1000_READ_REG(hw, E1000_CEXTERR);
 	stats->tsctc += E1000_READ_REG(hw, E1000_TSCTC);
 	stats->tsctfc += E1000_READ_REG(hw, E1000_TSCTFC);
+}
+
+static void
+eth_igb_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_hw_stats *stats =
+			E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+
+	igb_read_stats_registers(hw, stats);
 
 	if (rte_stats == NULL)
 		return;
@@ -1409,6 +1492,50 @@ eth_igb_stats_reset(struct rte_eth_dev *dev)
 }
 
 static void
+eth_igb_xstats_reset(struct rte_eth_dev *dev)
+{
+	struct e1000_hw_stats *stats =
+			E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+
+	/* HW registers are cleared on read */
+	eth_igb_xstats_get(dev, NULL, IGB_NB_XSTATS);
+
+	/* Reset software totals */
+	memset(stats, 0, sizeof(*stats));
+}
+
+static int
+eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		   unsigned n)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_hw_stats *hw_stats =
+			E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+	unsigned i;
+
+	if(n < IGB_NB_XSTATS)
+		return IGB_NB_XSTATS;
+
+	igb_read_stats_registers(hw, hw_stats);
+
+	/* If this is a reset xstats is NULL, and we have cleared the
+	 * registers by reading them.
+	 */
+	if (!xstats)
+		return 0;
+
+	/* Extended stats */
+	for (i = 0; i < IGB_NB_XSTATS; i++) {
+		snprintf(xstats[i].name, sizeof(xstats[i].name),
+			 "%s", rte_igb_stats_strings[i].name);
+		xstats[i].value = *(uint64_t *)(((char *)hw_stats) +
+			rte_igb_stats_strings[i].offset);
+	}
+
+	return IGB_NB_XSTATS;
+}
+
+static void
 eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -1463,7 +1590,6 @@ eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
 	rte_stats->ilbbytes = hw_stats->gorlbc;
 	rte_stats->olbpackets = hw_stats->gptlbc;
 	rte_stats->olbbytes = hw_stats->gotlbc;
-
 }
 
 static void
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v3 06/11] igbvf: add xstats() implementation
  2015-10-22 15:48   ` [dpdk-dev] [PATCH v3 00/11] Port XStats Harry van Haaren
                       ` (4 preceding siblings ...)
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 05/11] igb: " Harry van Haaren
@ 2015-10-22 15:48     ` Harry van Haaren
  2015-10-28 12:17       ` Tahhan, Maryam
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 07/11] ixgbe: update statistic strings to scheme Harry van Haaren
                       ` (5 subsequent siblings)
  11 siblings, 1 reply; 77+ messages in thread
From: Harry van Haaren @ 2015-10-22 15:48 UTC (permalink / raw)
  To: dev

Add xstats functionality to igbvf PMD, adding
necessary statistic strings.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/e1000/igb_ethdev.c | 62 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 55 insertions(+), 7 deletions(-)

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index afa4cb4..1a92caf 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -152,7 +152,10 @@ static int igbvf_dev_start(struct rte_eth_dev *dev);
 static void igbvf_dev_stop(struct rte_eth_dev *dev);
 static void igbvf_dev_close(struct rte_eth_dev *dev);
 static int eth_igbvf_link_update(struct e1000_hw *hw);
-static void eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats);
+static void eth_igbvf_stats_get(struct rte_eth_dev *dev,
+				struct rte_eth_stats *rte_stats);
+static int eth_igbvf_xstats_get(struct rte_eth_dev *dev,
+				struct rte_eth_xstats *xstats, unsigned n);
 static void eth_igbvf_stats_reset(struct rte_eth_dev *dev);
 static int igbvf_vlan_filter_set(struct rte_eth_dev *dev,
 		uint16_t vlan_id, int on);
@@ -346,7 +349,9 @@ static const struct eth_dev_ops igbvf_eth_dev_ops = {
 	.dev_close            = igbvf_dev_close,
 	.link_update          = eth_igb_link_update,
 	.stats_get            = eth_igbvf_stats_get,
+	.xstats_get           = eth_igbvf_xstats_get,
 	.stats_reset          = eth_igbvf_stats_reset,
+	.xstats_reset         = eth_igbvf_stats_reset,
 	.vlan_filter_set      = igbvf_vlan_filter_set,
 	.dev_infos_get        = eth_igbvf_infos_get,
 	.rx_queue_setup       = eth_igb_rx_queue_setup,
@@ -430,6 +435,17 @@ static const struct rte_igb_xstats_name_off rte_igb_stats_strings[] = {
 #define IGB_NB_XSTATS (sizeof(rte_igb_stats_strings) / \
 		sizeof(rte_igb_stats_strings[0]))
 
+static const struct rte_igb_xstats_name_off rte_igbvf_stats_strings[] = {
+	{"rx_multicast_packets", offsetof(struct e1000_vf_stats, mprc)},
+	{"rx_good_loopback_packets", offsetof(struct e1000_vf_stats, gprlbc)},
+	{"tx_good_loopback_packets", offsetof(struct e1000_vf_stats, gptlbc)},
+	{"rx_good_loopback_bytes", offsetof(struct e1000_vf_stats, gorlbc)},
+	{"tx_good_loopback_bytes", offsetof(struct e1000_vf_stats, gotlbc)},
+};
+
+#define IGBVF_NB_XSTATS (sizeof(rte_igbvf_stats_strings) / \
+		sizeof(rte_igbvf_stats_strings[0]))
+
 /**
  * Atomically reads the link status information from global
  * structure rte_eth_dev.
@@ -1536,12 +1552,8 @@ eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
 }
 
 static void
-eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
+igbvf_read_stats_registers(struct e1000_hw *hw, struct e1000_vf_stats *hw_stats)
 {
-	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	struct e1000_vf_stats *hw_stats = (struct e1000_vf_stats*)
-			  E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
-
 	/* Good Rx packets, include VF loopback */
 	UPDATE_VF_STAT(E1000_VFGPRC,
 	    hw_stats->last_gprc, hw_stats->gprc);
@@ -1577,6 +1589,43 @@ eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
 	/* Good Tx loopback octets */
 	UPDATE_VF_STAT(E1000_VFGOTLBC,
 	    hw_stats->last_gotlbc, hw_stats->gotlbc);
+}
+
+static int
+eth_igbvf_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		     unsigned n)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_vf_stats *hw_stats = (struct e1000_vf_stats *)
+			E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+	unsigned i;
+
+	if(n < IGBVF_NB_XSTATS)
+		return IGBVF_NB_XSTATS;
+
+	igbvf_read_stats_registers(hw, hw_stats);
+
+	if(!xstats)
+		return 0;
+
+	for(i = 0; i < IGBVF_NB_XSTATS; i++) {
+		snprintf(xstats[i].name, sizeof(xstats[i].name), "%s",
+			 rte_igbvf_stats_strings[i].name);
+		xstats[i].value = *(uint64_t *)(((char *)hw_stats) +
+			rte_igbvf_stats_strings[i].offset);
+	}
+
+	return IGBVF_NB_XSTATS;
+}
+
+static void
+eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_vf_stats *hw_stats = (struct e1000_vf_stats *)
+			  E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+
+	igbvf_read_stats_registers(hw, hw_stats);
 
 	if (rte_stats == NULL)
 		return;
@@ -1604,7 +1653,6 @@ eth_igbvf_stats_reset(struct rte_eth_dev *dev)
 	/* reset HW current stats*/
 	memset(&hw_stats->gprc, 0, sizeof(*hw_stats) -
 	       offsetof(struct e1000_vf_stats, gprc));
-
 }
 
 static void
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v3 07/11] ixgbe: update statistic strings to scheme
  2015-10-22 15:48   ` [dpdk-dev] [PATCH v3 00/11] Port XStats Harry van Haaren
                       ` (5 preceding siblings ...)
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 06/11] igbvf: " Harry van Haaren
@ 2015-10-22 15:48     ` Harry van Haaren
  2015-10-23 14:41       ` Tahhan, Maryam
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 08/11] ixgbevf: add xstats() functions to VF Harry van Haaren
                       ` (4 subsequent siblings)
  11 siblings, 1 reply; 77+ messages in thread
From: Harry van Haaren @ 2015-10-22 15:48 UTC (permalink / raw)
  To: dev

Updated and add statistic strings as used by xstats_get().

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 295 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 273 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 1e5ffbf..2e9e260 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -506,29 +506,280 @@ struct rte_ixgbe_xstats_name_off {
 };
 
 static const struct rte_ixgbe_xstats_name_off rte_ixgbe_stats_strings[] = {
-	{"rx_illegal_byte_err", offsetof(struct ixgbe_hw_stats, errbc)},
-	{"rx_len_err", offsetof(struct ixgbe_hw_stats, rlec)},
-	{"rx_undersize_count", offsetof(struct ixgbe_hw_stats, ruc)},
-	{"rx_oversize_count", offsetof(struct ixgbe_hw_stats, roc)},
-	{"rx_fragment_count", offsetof(struct ixgbe_hw_stats, rfc)},
-	{"rx_jabber_count", offsetof(struct ixgbe_hw_stats, rjc)},
-	{"l3_l4_xsum_error", offsetof(struct ixgbe_hw_stats, xec)},
-	{"mac_local_fault", offsetof(struct ixgbe_hw_stats, mlfc)},
-	{"mac_remote_fault", offsetof(struct ixgbe_hw_stats, mrfc)},
-	{"mac_short_pkt_discard", offsetof(struct ixgbe_hw_stats, mspdc)},
-	{"fccrc_error", offsetof(struct ixgbe_hw_stats, fccrc)},
-	{"fcoe_drop", offsetof(struct ixgbe_hw_stats, fcoerpdc)},
-	{"fc_last_error", offsetof(struct ixgbe_hw_stats, fclast)},
-	{"rx_broadcast_packets", offsetof(struct ixgbe_hw_stats, bprc)},
-	{"rx_phy_multicast_packets", offsetof(struct ixgbe_hw_stats, mprc)},
-	{"mgmt_pkts_dropped", offsetof(struct ixgbe_hw_stats, mngpdc)},
 	{"rx_crc_errors", offsetof(struct ixgbe_hw_stats, crcerrs)},
-	{"fdir_match", offsetof(struct ixgbe_hw_stats, fdirmatch)},
-	{"fdir_miss", offsetof(struct ixgbe_hw_stats, fdirmiss)},
-	{"tx_flow_control_xon", offsetof(struct ixgbe_hw_stats, lxontxc)},
-	{"rx_flow_control_xon", offsetof(struct ixgbe_hw_stats, lxonrxc)},
-	{"tx_flow_control_xoff", offsetof(struct ixgbe_hw_stats, lxofftxc)},
-	{"rx_flow_control_xoff", offsetof(struct ixgbe_hw_stats, lxoffrxc)},
+	{"rx_illegal_byte_errors", offsetof(struct ixgbe_hw_stats, illerrc)},
+	{"rx_error_bytes", offsetof(struct ixgbe_hw_stats, errbc)},
+	{"mac_local_errors", offsetof(struct ixgbe_hw_stats, mlfc)},
+	{"mac_remote_errors", offsetof(struct ixgbe_hw_stats, mrfc)},
+	{"rx_length_errors", offsetof(struct ixgbe_hw_stats, rlec)},
+	{"tx_xon_packets", offsetof(struct ixgbe_hw_stats, lxontxc)},
+	{"rx_xon_packets", offsetof(struct ixgbe_hw_stats, lxonrxc)},
+	{"tx_xoff_packets", offsetof(struct ixgbe_hw_stats, lxofftxc)},
+	{"rx_xoff_packets", offsetof(struct ixgbe_hw_stats, lxoffrxc)},
+	{"rx_size_64_packets", offsetof(struct ixgbe_hw_stats, prc64)},
+	{"rx_size_65_to_127_packets", offsetof(struct ixgbe_hw_stats, prc127)},
+	{"rx_size_128_to_255_packets", offsetof(struct ixgbe_hw_stats, prc255)},
+	{"rx_size_256_to_511_packets", offsetof(struct ixgbe_hw_stats, prc511)},
+	{"rx_size_512_to_1023_packets", offsetof(struct ixgbe_hw_stats,
+		prc1023)},
+	{"rx_size_1024_to_max_packets", offsetof(struct ixgbe_hw_stats,
+		prc1522)},
+	{"rx_broadcast_packets", offsetof(struct ixgbe_hw_stats, bprc)},
+	{"rx_multicast_packets", offsetof(struct ixgbe_hw_stats, mprc)},
+	{"rx_fragment_errors", offsetof(struct ixgbe_hw_stats, rfc)},
+	{"rx_undersize_errors", offsetof(struct ixgbe_hw_stats, ruc)},
+	{"rx_oversize_errors", offsetof(struct ixgbe_hw_stats, roc)},
+	{"rx_jabber_errors", offsetof(struct ixgbe_hw_stats, rjc)},
+	{"rx_managment_packets", offsetof(struct ixgbe_hw_stats, mngprc)},
+	{"rx_managment_dropped", offsetof(struct ixgbe_hw_stats, mngpdc)},
+	{"tx_managment_packets", offsetof(struct ixgbe_hw_stats, mngptc)},
+	{"rx_total_packets", offsetof(struct ixgbe_hw_stats, tpr)},
+	{"rx_total_bytes", offsetof(struct ixgbe_hw_stats, tor)},
+	{"tx_total_packets", offsetof(struct ixgbe_hw_stats, tpt)},
+	{"tx_size_64_packets", offsetof(struct ixgbe_hw_stats, ptc64)},
+	{"tx_size_65_to_127_packets", offsetof(struct ixgbe_hw_stats, ptc127)},
+	{"tx_size_128_to_255_packets", offsetof(struct ixgbe_hw_stats, ptc255)},
+	{"tx_size_256_to_511_packets", offsetof(struct ixgbe_hw_stats, ptc511)},
+	{"tx_size_512_to_1023_packets", offsetof(struct ixgbe_hw_stats,
+		ptc1023)},
+	{"tx_size_1024_to_max_packets", offsetof(struct ixgbe_hw_stats,
+		ptc1522)},
+	{"tx_multicast_packets", offsetof(struct ixgbe_hw_stats, mptc)},
+	{"tx_broadcast_packets", offsetof(struct ixgbe_hw_stats, bptc)},
+	{"rx_mac_short_packet_discard", offsetof(struct ixgbe_hw_stats, mspdc)},
+	{"rx_l3_l4_xsum_error", offsetof(struct ixgbe_hw_stats, xec)},
+
+	{"flow_director_added_filters", offsetof(struct ixgbe_hw_stats,
+		fdirustat_add)},
+	{"flow_director_removed_filters", offsetof(struct ixgbe_hw_stats,
+		fdirustat_remove)},
+	{"flow_director_filter_add_errors", offsetof(struct ixgbe_hw_stats,
+		fdirfstat_fadd)},
+	{"flow_director_filter_remove_errors", offsetof(struct ixgbe_hw_stats,
+		fdirfstat_fremove)},
+	{"flow_director_matched_filters", offsetof(struct ixgbe_hw_stats,
+		fdirmatch)},
+	{"flow_director_missed_filters", offsetof(struct ixgbe_hw_stats,
+		fdirmiss)},
+
+	{"rx_fcoe_crc_errors", offsetof(struct ixgbe_hw_stats, fccrc)},
+	{"rx_fcoe_dropped", offsetof(struct ixgbe_hw_stats, fcoerpdc)},
+	{"rx_fcoe_mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats,
+		fclast)},
+	{"rx_fcoe_packets", offsetof(struct ixgbe_hw_stats, fcoeprc)},
+	{"tx_fcoe_packets", offsetof(struct ixgbe_hw_stats, fcoeptc)},
+	{"rx_fcoe_bytes", offsetof(struct ixgbe_hw_stats, fcoedwrc)},
+	{"tx_fcoe_bytes", offsetof(struct ixgbe_hw_stats, fcoedwtc)},
+	{"rx_fcoe_no_direct_data_placement", offsetof(struct ixgbe_hw_stats,
+		fcoe_noddp)},
+	{"rx_fcoe_no_direct_data_placement_ext_buff",
+		offsetof(struct ixgbe_hw_stats, fcoe_noddp_ext_buff)},
+
+	{"tx_flow_control_xon_packets", offsetof(struct ixgbe_hw_stats,
+		lxontxc)},
+	{"rx_flow_control_xon_packets", offsetof(struct ixgbe_hw_stats,
+		lxonrxc)},
+	{"tx_flow_control_xoff_packets", offsetof(struct ixgbe_hw_stats,
+		lxofftxc)},
+	{"rx_flow_control_xoff_packets", offsetof(struct ixgbe_hw_stats,
+		lxoffrxc)},
+	{"rx_total_missed_packets", offsetof(struct ixgbe_hw_stats, mpctotal)},
+
+	{"rx_q0_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[0])},
+	{"rx_q1_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[1])},
+	{"rx_q2_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[2])},
+	{"rx_q3_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[3])},
+	{"rx_q4_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[4])},
+	{"rx_q5_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[5])},
+	{"rx_q6_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[6])},
+	{"rx_q7_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[7])},
+
+	{"rx_q0_mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats,
+		rnbc[0])},
+	{"rx_q1_mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats,
+		rnbc[1])},
+	{"rx_q2_mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats,
+		rnbc[2])},
+	{"rx_q3_mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats,
+		rnbc[3])},
+	{"rx_q4_mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats,
+		rnbc[4])},
+	{"rx_q5_mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats,
+		rnbc[5])},
+	{"rx_q6_mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats,
+		rnbc[6])},
+	{"rx_q7_mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats,
+		rnbc[7])},
+
+	{"tx_q0_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxontxc[0])},
+	{"tx_q1_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxontxc[1])},
+	{"tx_q2_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxontxc[2])},
+	{"tx_q3_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxontxc[3])},
+	{"tx_q4_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxontxc[4])},
+	{"tx_q5_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxontxc[5])},
+	{"tx_q6_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxontxc[6])},
+	{"tx_q7_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxontxc[7])},
+
+	{"rx_q0_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxonrxc[0])},
+	{"rx_q1_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxonrxc[1])},
+	{"rx_q2_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxonrxc[2])},
+	{"rx_q3_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxonrxc[3])},
+	{"rx_q4_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxonrxc[4])},
+	{"rx_q5_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxonrxc[5])},
+	{"rx_q6_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxonrxc[6])},
+	{"rx_q7_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxonrxc[7])},
+
+	{"tx_q0_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxofftxc[0])},
+	{"tx_q1_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxofftxc[1])},
+	{"tx_q2_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxofftxc[2])},
+	{"tx_q3_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxofftxc[3])},
+	{"tx_q4_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxofftxc[4])},
+	{"tx_q5_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxofftxc[5])},
+	{"tx_q6_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxofftxc[6])},
+	{"tx_q7_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxofftxc[7])},
+
+	{"rx_q0_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxoffrxc[0])},
+	{"rx_q1_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxoffrxc[1])},
+	{"rx_q2_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxoffrxc[2])},
+	{"rx_q3_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxoffrxc[3])},
+	{"rx_q4_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxoffrxc[4])},
+	{"rx_q5_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxoffrxc[5])},
+	{"rx_q6_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxoffrxc[6])},
+	{"rx_q7_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxoffrxc[7])},
+
+	{"xx_q0_xon_to_off_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxon2offc[0])},
+	{"xx_q1_xon_to_off_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxon2offc[1])},
+	{"xx_q2_xon_to_off_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxon2offc[2])},
+	{"xx_q3_xon_to_off_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxon2offc[3])},
+	{"xx_q4_xon_to_off_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxon2offc[4])},
+	{"xx_q5_xon_to_off_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxon2offc[5])},
+	{"xx_q6_xon_to_off_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxon2offc[6])},
+	{"xx_q7_xon_to_off_priority_packets", offsetof(struct ixgbe_hw_stats,
+		pxon2offc[7])},
+
+	{"rx_q0_packets", offsetof(struct ixgbe_hw_stats, qprc[0])},
+	{"rx_q1_packets", offsetof(struct ixgbe_hw_stats, qprc[1])},
+	{"rx_q2_packets", offsetof(struct ixgbe_hw_stats, qprc[2])},
+	{"rx_q3_packets", offsetof(struct ixgbe_hw_stats, qprc[3])},
+	{"rx_q4_packets", offsetof(struct ixgbe_hw_stats, qprc[4])},
+	{"rx_q5_packets", offsetof(struct ixgbe_hw_stats, qprc[5])},
+	{"rx_q6_packets", offsetof(struct ixgbe_hw_stats, qprc[6])},
+	{"rx_q7_packets", offsetof(struct ixgbe_hw_stats, qprc[7])},
+	{"rx_q8_packets", offsetof(struct ixgbe_hw_stats, qprc[8])},
+	{"rx_q9_packets", offsetof(struct ixgbe_hw_stats, qprc[9])},
+	{"rx_q10_packets", offsetof(struct ixgbe_hw_stats, qprc[10])},
+	{"rx_q11_packets", offsetof(struct ixgbe_hw_stats, qprc[11])},
+	{"rx_q12_packets", offsetof(struct ixgbe_hw_stats, qprc[12])},
+	{"rx_q13_packets", offsetof(struct ixgbe_hw_stats, qprc[13])},
+	{"rx_q14_packets", offsetof(struct ixgbe_hw_stats, qprc[14])},
+	{"rx_q15_packets", offsetof(struct ixgbe_hw_stats, qprc[15])},
+
+	{"tx_q0_packets", offsetof(struct ixgbe_hw_stats, qptc[0])},
+	{"tx_q1_packets", offsetof(struct ixgbe_hw_stats, qptc[1])},
+	{"tx_q2_packets", offsetof(struct ixgbe_hw_stats, qptc[2])},
+	{"tx_q3_packets", offsetof(struct ixgbe_hw_stats, qptc[3])},
+	{"tx_q4_packets", offsetof(struct ixgbe_hw_stats, qptc[4])},
+	{"tx_q5_packets", offsetof(struct ixgbe_hw_stats, qptc[5])},
+	{"tx_q6_packets", offsetof(struct ixgbe_hw_stats, qptc[6])},
+	{"tx_q7_packets", offsetof(struct ixgbe_hw_stats, qptc[7])},
+	{"tx_q8_packets", offsetof(struct ixgbe_hw_stats, qptc[8])},
+	{"tx_q9_packets", offsetof(struct ixgbe_hw_stats, qptc[9])},
+	{"tx_q10_packets", offsetof(struct ixgbe_hw_stats, qptc[10])},
+	{"tx_q11_packets", offsetof(struct ixgbe_hw_stats, qptc[11])},
+	{"tx_q12_packets", offsetof(struct ixgbe_hw_stats, qptc[12])},
+	{"tx_q13_packets", offsetof(struct ixgbe_hw_stats, qptc[13])},
+	{"tx_q14_packets", offsetof(struct ixgbe_hw_stats, qptc[14])},
+	{"tx_q15_packets", offsetof(struct ixgbe_hw_stats, qptc[15])},
+
+	{"rx_q0_bytes", offsetof(struct ixgbe_hw_stats, qbrc[0])},
+	{"rx_q1_bytes", offsetof(struct ixgbe_hw_stats, qbrc[1])},
+	{"rx_q2_bytes", offsetof(struct ixgbe_hw_stats, qbrc[2])},
+	{"rx_q3_bytes", offsetof(struct ixgbe_hw_stats, qbrc[3])},
+	{"rx_q4_bytes", offsetof(struct ixgbe_hw_stats, qbrc[4])},
+	{"rx_q5_bytes", offsetof(struct ixgbe_hw_stats, qbrc[5])},
+	{"rx_q6_bytes", offsetof(struct ixgbe_hw_stats, qbrc[6])},
+	{"rx_q7_bytes", offsetof(struct ixgbe_hw_stats, qbrc[7])},
+	{"rx_q8_bytes", offsetof(struct ixgbe_hw_stats, qbrc[8])},
+	{"rx_q9_bytes", offsetof(struct ixgbe_hw_stats, qbrc[9])},
+	{"rx_q10_bytes", offsetof(struct ixgbe_hw_stats, qbrc[10])},
+	{"rx_q11_bytes", offsetof(struct ixgbe_hw_stats, qbrc[11])},
+	{"rx_q12_bytes", offsetof(struct ixgbe_hw_stats, qbrc[12])},
+	{"rx_q13_bytes", offsetof(struct ixgbe_hw_stats, qbrc[13])},
+	{"rx_q14_bytes", offsetof(struct ixgbe_hw_stats, qbrc[14])},
+	{"rx_q15_bytes", offsetof(struct ixgbe_hw_stats, qbrc[15])},
+
+	{"tx_q0_bytes", offsetof(struct ixgbe_hw_stats, qbtc[0])},
+	{"tx_q1_bytes", offsetof(struct ixgbe_hw_stats, qbtc[1])},
+	{"tx_q2_bytes", offsetof(struct ixgbe_hw_stats, qbtc[2])},
+	{"tx_q3_bytes", offsetof(struct ixgbe_hw_stats, qbtc[3])},
+	{"tx_q4_bytes", offsetof(struct ixgbe_hw_stats, qbtc[4])},
+	{"tx_q5_bytes", offsetof(struct ixgbe_hw_stats, qbtc[5])},
+	{"tx_q6_bytes", offsetof(struct ixgbe_hw_stats, qbtc[6])},
+	{"tx_q7_bytes", offsetof(struct ixgbe_hw_stats, qbtc[7])},
+	{"tx_q8_bytes", offsetof(struct ixgbe_hw_stats, qbtc[8])},
+	{"tx_q9_bytes", offsetof(struct ixgbe_hw_stats, qbtc[9])},
+	{"tx_q10_bytes", offsetof(struct ixgbe_hw_stats, qbtc[10])},
+	{"tx_q11_bytes", offsetof(struct ixgbe_hw_stats, qbtc[11])},
+	{"tx_q12_bytes", offsetof(struct ixgbe_hw_stats, qbtc[12])},
+	{"tx_q13_bytes", offsetof(struct ixgbe_hw_stats, qbtc[13])},
+	{"tx_q14_bytes", offsetof(struct ixgbe_hw_stats, qbtc[14])},
+	{"tx_q15_bytes", offsetof(struct ixgbe_hw_stats, qbtc[15])},
+
+	{"rx_q0_dropped", offsetof(struct ixgbe_hw_stats, qprdc[0])},
+	{"rx_q1_dropped", offsetof(struct ixgbe_hw_stats, qprdc[1])},
+	{"rx_q2_dropped", offsetof(struct ixgbe_hw_stats, qprdc[2])},
+	{"rx_q3_dropped", offsetof(struct ixgbe_hw_stats, qprdc[3])},
+	{"rx_q4_dropped", offsetof(struct ixgbe_hw_stats, qprdc[4])},
+	{"rx_q5_dropped", offsetof(struct ixgbe_hw_stats, qprdc[5])},
+	{"rx_q6_dropped", offsetof(struct ixgbe_hw_stats, qprdc[6])},
+	{"rx_q7_dropped", offsetof(struct ixgbe_hw_stats, qprdc[7])},
+	{"rx_q8_dropped", offsetof(struct ixgbe_hw_stats, qprdc[8])},
+	{"rx_q9_dropped", offsetof(struct ixgbe_hw_stats, qprdc[9])},
+	{"rx_q10_dropped", offsetof(struct ixgbe_hw_stats, qprdc[10])},
+	{"rx_q11_dropped", offsetof(struct ixgbe_hw_stats, qprdc[11])},
+	{"rx_q12_dropped", offsetof(struct ixgbe_hw_stats, qprdc[12])},
+	{"rx_q13_dropped", offsetof(struct ixgbe_hw_stats, qprdc[13])},
+	{"rx_q14_dropped", offsetof(struct ixgbe_hw_stats, qprdc[14])},
+	{"rx_q15_dropped", offsetof(struct ixgbe_hw_stats, qprdc[15])},
 };
 
 #define IXGBE_NB_XSTATS (sizeof(rte_ixgbe_stats_strings) /	\
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v3 08/11] ixgbevf: add xstats() functions to VF
  2015-10-22 15:48   ` [dpdk-dev] [PATCH v3 00/11] Port XStats Harry van Haaren
                       ` (6 preceding siblings ...)
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 07/11] ixgbe: update statistic strings to scheme Harry van Haaren
@ 2015-10-22 15:48     ` Harry van Haaren
  2015-10-28 12:16       ` Tahhan, Maryam
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 09/11] i40e: add xstats() implementation Harry van Haaren
                       ` (3 subsequent siblings)
  11 siblings, 1 reply; 77+ messages in thread
From: Harry van Haaren @ 2015-10-22 15:48 UTC (permalink / raw)
  To: dev

Add xstats() functions and stat strings as necessary to ixgbevf PMD.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 51 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 49 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 2e9e260..127d168 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -149,6 +149,8 @@ static void ixgbe_dev_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *stats);
 static int ixgbe_dev_xstats_get(struct rte_eth_dev *dev,
 				struct rte_eth_xstats *xstats, unsigned n);
+static int ixgbevf_dev_xstats_get(struct rte_eth_dev *dev,
+				  struct rte_eth_xstats *xstats, unsigned n);
 static void ixgbe_dev_stats_reset(struct rte_eth_dev *dev);
 static void ixgbe_dev_xstats_reset(struct rte_eth_dev *dev);
 static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
@@ -477,7 +479,9 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
 	.dev_stop             = ixgbevf_dev_stop,
 	.link_update          = ixgbe_dev_link_update,
 	.stats_get            = ixgbevf_dev_stats_get,
+	.xstats_get           = ixgbevf_dev_xstats_get,
 	.stats_reset          = ixgbevf_dev_stats_reset,
+	.xstats_reset         = ixgbevf_dev_stats_reset,
 	.dev_close            = ixgbevf_dev_close,
 	.dev_infos_get        = ixgbevf_dev_info_get,
 	.mtu_set              = ixgbevf_dev_set_mtu,
@@ -785,6 +789,13 @@ static const struct rte_ixgbe_xstats_name_off rte_ixgbe_stats_strings[] = {
 #define IXGBE_NB_XSTATS (sizeof(rte_ixgbe_stats_strings) /	\
 		sizeof(rte_ixgbe_stats_strings[0]))
 
+static const struct rte_ixgbe_xstats_name_off rte_ixgbevf_stats_strings[] = {
+	{"rx_multicast_packets", offsetof(struct ixgbevf_hw_stats, vfmprc)},
+};
+
+#define IXGBEVF_NB_XSTATS (sizeof(rte_ixgbevf_stats_strings) /	\
+		sizeof(rte_ixgbevf_stats_strings[0]))
+
 /**
  * Atomically reads the link status information from global
  * structure rte_eth_dev.
@@ -2536,7 +2547,7 @@ ixgbe_dev_xstats_reset(struct rte_eth_dev *dev)
 }
 
 static void
-ixgbevf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+ixgbevf_update_stats(struct rte_eth_dev *dev)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct ixgbevf_hw_stats *hw_stats = (struct ixgbevf_hw_stats*)
@@ -2561,8 +2572,44 @@ ixgbevf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	/* Rx Multicst Packet */
 	UPDATE_VF_STAT(IXGBE_VFMPRC,
 	    hw_stats->last_vfmprc, hw_stats->vfmprc);
+}
 
-	if (stats == NULL)
+static int
+ixgbevf_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		       unsigned n)
+{
+	struct ixgbevf_hw_stats *hw_stats = (struct ixgbevf_hw_stats *)
+			IXGBE_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+	unsigned i;
+
+	if(n < IXGBEVF_NB_XSTATS)
+		return IXGBEVF_NB_XSTATS;
+
+	ixgbevf_update_stats(dev);
+
+	if (!xstats)
+		return 0;
+
+	/* Extended stats */
+	for (i = 0; i < IXGBEVF_NB_XSTATS; i++) {
+		snprintf(xstats[i].name, sizeof(xstats[i].name),
+			 "%s", rte_ixgbevf_stats_strings[i].name);
+		xstats[i].value = *(uint64_t *)(((char *)hw_stats) +
+			rte_ixgbevf_stats_strings[i].offset);
+	}
+
+	return IXGBEVF_NB_XSTATS;
+}
+
+static void
+ixgbevf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+	struct ixgbevf_hw_stats *hw_stats = (struct ixgbevf_hw_stats *)
+			  IXGBE_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+
+	ixgbevf_update_stats(dev);
+
+	if(stats == NULL)
 		return;
 
 	stats->ipackets = hw_stats->vfgprc;
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v3 09/11] i40e: add xstats() implementation
  2015-10-22 15:48   ` [dpdk-dev] [PATCH v3 00/11] Port XStats Harry van Haaren
                       ` (7 preceding siblings ...)
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 08/11] ixgbevf: add xstats() functions to VF Harry van Haaren
@ 2015-10-22 15:48     ` Harry van Haaren
  2015-10-23 15:11       ` Tahhan, Maryam
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 10/11] i40evf: " Harry van Haaren
                       ` (2 subsequent siblings)
  11 siblings, 1 reply; 77+ messages in thread
From: Harry van Haaren @ 2015-10-22 15:48 UTC (permalink / raw)
  To: dev

Add xstats functions to i40e PMD, allowing extended statistics
to be retrieved from the NIC and exposed to the DPDK.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 265 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 258 insertions(+), 7 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 2dd9fdc..cf0199d 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -127,7 +127,10 @@ static int i40e_dev_set_link_up(struct rte_eth_dev *dev);
 static int i40e_dev_set_link_down(struct rte_eth_dev *dev);
 static void i40e_dev_stats_get(struct rte_eth_dev *dev,
 			       struct rte_eth_stats *stats);
+static int i40e_dev_xstats_get(struct rte_eth_dev *dev,
+			       struct rte_eth_xstats *xstats, unsigned n);
 static void i40e_dev_stats_reset(struct rte_eth_dev *dev);
+static void i40e_dev_xstats_reset(struct rte_eth_dev *dev);
 static int i40e_dev_queue_stats_mapping_set(struct rte_eth_dev *dev,
 					    uint16_t queue_id,
 					    uint8_t stat_idx,
@@ -232,6 +235,8 @@ static int i40e_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
 					   uint32_t flags);
 static int i40e_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
 					   struct timespec *timestamp);
+static void i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw);
+
 
 static const struct rte_pci_id pci_id_i40e_map[] = {
 #define RTE_PCI_DEV_ID_DECL_I40E(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
@@ -252,7 +257,9 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
 	.dev_set_link_down            = i40e_dev_set_link_down,
 	.link_update                  = i40e_dev_link_update,
 	.stats_get                    = i40e_dev_stats_get,
+	.xstats_get                   = i40e_dev_xstats_get,
 	.stats_reset                  = i40e_dev_stats_reset,
+	.xstats_reset                 = i40e_dev_xstats_reset,
 	.queue_stats_mapping_set      = i40e_dev_queue_stats_mapping_set,
 	.dev_infos_get                = i40e_dev_info_get,
 	.vlan_filter_set              = i40e_vlan_filter_set,
@@ -291,6 +298,187 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
 	.timesync_read_tx_timestamp   = i40e_timesync_read_tx_timestamp,
 };
 
+/* store statistics names and its offset in stats structure */
+struct rte_i40e_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	unsigned offset;
+};
+
+static const struct rte_i40e_xstats_name_off rte_i40e_stats_strings[] = {
+	{"rx_unicast_packets", offsetof(struct i40e_eth_stats, rx_unicast)},
+	{"rx_multicast_packets", offsetof(struct i40e_eth_stats, rx_multicast)},
+	{"rx_broadcast_packets", offsetof(struct i40e_eth_stats, rx_broadcast)},
+	{"rx_dropped", offsetof(struct i40e_eth_stats, rx_discards)},
+	{"rx_unknown_protocol_packets", offsetof(struct i40e_eth_stats,
+		rx_unknown_protocol)},
+	{"tx_unicast_packets", offsetof(struct i40e_eth_stats, tx_unicast)},
+	{"tx_multicast_packets", offsetof(struct i40e_eth_stats, tx_multicast)},
+	{"tx_broadcast_packets", offsetof(struct i40e_eth_stats, tx_broadcast)},
+	{"tx_dropped", offsetof(struct i40e_eth_stats, tx_discards)},
+};
+
+static const struct rte_i40e_xstats_name_off rte_i40e_hw_port_strings[] = {
+	{"tx_link_down_dropped", offsetof(struct i40e_hw_port_stats,
+		tx_dropped_link_down)},
+	{"rx_crc_errors", offsetof(struct i40e_hw_port_stats, crc_errors)},
+	{"rx_illegal_bytes", offsetof(struct i40e_hw_port_stats,
+		illegal_bytes)},
+	{"rx_error_bytes", offsetof(struct i40e_hw_port_stats, error_bytes)},
+	{"mac_local_errors", offsetof(struct i40e_hw_port_stats,
+		mac_local_faults)},
+	{"mac_remote_errors", offsetof(struct i40e_hw_port_stats,
+		mac_remote_faults)},
+	{"rx_length_errors", offsetof(struct i40e_hw_port_stats,
+		rx_length_errors)},
+	{"tx_xon_packets", offsetof(struct i40e_hw_port_stats, link_xon_tx)},
+	{"rx_xon_packets", offsetof(struct i40e_hw_port_stats, link_xon_rx)},
+	{"tx_xoff_packets", offsetof(struct i40e_hw_port_stats, link_xoff_tx)},
+	{"rx_xoff_packets", offsetof(struct i40e_hw_port_stats, link_xoff_rx)},
+	{"rx_size_64_packets", offsetof(struct i40e_hw_port_stats, rx_size_64)},
+	{"rx_size_65_to_127_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_127)},
+	{"rx_size_128_to_255_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_255)},
+	{"rx_size_256_to_511_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_511)},
+	{"rx_size_512_to_1023_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_1023)},
+	{"rx_size_1024_to_1522_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_1522)},
+	{"rx_size_1523_to_max_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_big)},
+	{"rx_undersized_packets", offsetof(struct i40e_hw_port_stats,
+		rx_undersize)},
+	{"rx_oversize_packets", offsetof(struct i40e_hw_port_stats,
+		rx_oversize)},
+	{"rx_mac_short_dropped", offsetof(struct i40e_hw_port_stats,
+		mac_short_packet_dropped)},
+	{"rx_fragmented_packets", offsetof(struct i40e_hw_port_stats,
+		rx_fragments)},
+	{"rx_jabber_packets", offsetof(struct i40e_hw_port_stats, rx_jabber)},
+	{"tx_size_64_packets", offsetof(struct i40e_hw_port_stats, tx_size_64)},
+	{"tx_size_65_to_127_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_127)},
+	{"tx_size_128_to_255_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_255)},
+	{"tx_size_256_to_511_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_511)},
+	{"tx_size_512_to_1023_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_1023)},
+	{"tx_size_1024_to_1522_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_1522)},
+	{"tx_size_1523_to_max_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_big)},
+	{"rx_flow_director_atr_match_packets",
+		offsetof(struct i40e_hw_port_stats, fd_atr_match)},
+	{"rx_flow_director_sb_match_packets",
+		offsetof(struct i40e_hw_port_stats, fd_sb_match)},
+	{"tx_low_power_idle_status", offsetof(struct i40e_hw_port_stats,
+		tx_lpi_status)},
+	{"rx_low_power_idle_status", offsetof(struct i40e_hw_port_stats,
+		rx_lpi_status)},
+	{"tx_low_power_idle_count", offsetof(struct i40e_hw_port_stats,
+		tx_lpi_count)},
+	{"rx_low_power_idle_count", offsetof(struct i40e_hw_port_stats,
+		rx_lpi_count)},
+
+	/* priority_xon_rx[8] */
+	{"tx_q0_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_tx[0])},
+	{"tx_q1_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_tx[1])},
+	{"tx_q2_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_tx[2])},
+	{"tx_q3_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_tx[3])},
+	{"tx_q4_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_tx[4])},
+	{"tx_q5_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_tx[5])},
+	{"tx_q6_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_tx[6])},
+	{"tx_q7_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_tx[7])},
+
+	/* priority_xon_rx[8] */
+	{"rx_q0_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_rx[0])},
+	{"rx_q1_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_rx[1])},
+	{"rx_q2_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_rx[2])},
+	{"rx_q3_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_rx[3])},
+	{"rx_q4_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_rx[4])},
+	{"rx_q5_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_rx[5])},
+	{"rx_q6_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_rx[6])},
+	{"rx_q7_xon_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xon_rx[7])},
+
+	/* priority_xoff_tx[8] */
+	{"tx_q0_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_tx[0])},
+	{"tx_q1_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_tx[1])},
+	{"tx_q2_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_tx[2])},
+	{"tx_q3_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_tx[3])},
+	{"tx_q4_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_tx[4])},
+	{"tx_q5_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_tx[5])},
+	{"tx_q6_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_tx[6])},
+	{"tx_q7_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_tx[7])},
+
+	/* priority_xoff_rx[8] */
+	{"rx_q0_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_rx[0])},
+	{"rx_q1_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_rx[1])},
+	{"rx_q2_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_rx[2])},
+	{"rx_q3_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_rx[3])},
+	{"rx_q4_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_rx[4])},
+	{"rx_q5_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_rx[5])},
+	{"rx_q6_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_rx[6])},
+	{"rx_q7_xoff_priority_packets", offsetof(struct i40e_hw_port_stats,
+		priority_xoff_rx[7])},
+
+	/* priority_xon_2_xoff[8] */
+	{"xx_q0_xon_to_xoff_priority_packets",
+		offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[0])},
+	{"xx_q1_xon_to_xoff_priority_packets",
+		offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[1])},
+	{"xx_q2_xon_to_xoff_priority_packets",
+		offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[2])},
+	{"xx_q3_xon_to_xoff_priority_packets",
+		offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[3])},
+	{"xx_q4_xon_to_xoff_priority_packets",
+		offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[4])},
+	{"xx_q5_xon_to_xoff_priority_packets",
+		offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[5])},
+	{"xx_q6_xon_to_xoff_priority_packets",
+		offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[6])},
+	{"xx_q7_xon_to_xoff_priority_packets",
+		offsetof(struct i40e_hw_port_stats, priority_xon_2_xoff[7])},
+};
+
+#define I40E_NB_ETH_XSTATS (sizeof(rte_i40e_stats_strings) / \
+		sizeof(rte_i40e_stats_strings[0]))
+#define I40E_NB_HW_PORT_XSTATS (sizeof(rte_i40e_hw_port_strings) / \
+		sizeof(rte_i40e_hw_port_strings[0]))
+#define I40E_NB_XSTATS (I40E_NB_ETH_XSTATS + I40E_NB_HW_PORT_XSTATS)
+
 static struct eth_driver rte_i40e_pmd = {
 	.pci_drv = {
 		.name = "rte_i40e_pmd",
@@ -1322,16 +1510,12 @@ i40e_update_vsi_stats(struct i40e_vsi *vsi)
 		    vsi->vsi_id);
 }
 
-/* Get all statistics of a port */
 static void
-i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw)
 {
-	uint32_t i;
-	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	unsigned int i;
 	struct i40e_hw_port_stats *ns = &pf->stats; /* new stats */
 	struct i40e_hw_port_stats *os = &pf->stats_offset; /* old stats */
-
 	/* Get statistics of struct i40e_eth_stats */
 	i40e_stat_update_48(hw, I40E_GLPRT_GORCH(hw->port),
 			    I40E_GLPRT_GORCL(hw->port),
@@ -1508,8 +1692,21 @@ i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 
 	pf->offset_loaded = true;
 
-	if (pf->main_vsi)
+	if(pf->main_vsi)
 		i40e_update_vsi_stats(pf->main_vsi);
+}
+
+/* Get all statistics of a port */
+static void
+i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct i40e_hw_port_stats *ns = &pf->stats; /* new stats */
+	unsigned i;
+
+	/* call read registers - updates values, now write them to struct */
+	i40e_read_stats_registers(pf, hw);
 
 	stats->ipackets = ns->eth.rx_unicast + ns->eth.rx_multicast +
 						ns->eth.rx_broadcast;
@@ -1599,6 +1796,60 @@ i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	PMD_DRV_LOG(DEBUG, "***************** PF stats end ********************");
 }
 
+static void
+i40e_dev_xstats_reset(struct rte_eth_dev *dev)
+{
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct i40e_hw_port_stats *hw_stats = &pf->stats;
+
+	/* The hw registers are cleared on read */
+	pf->offset_loaded = false;
+	i40e_read_stats_registers(pf, hw);
+
+	/* reset software counters */
+	memset(hw_stats, 0, sizeof(*hw_stats));
+}
+
+static int
+i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		    unsigned n)
+{
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	unsigned i, count = 0;
+	struct i40e_hw_port_stats *hw_stats = &pf->stats;
+
+	if(n < I40E_NB_XSTATS)
+		return I40E_NB_XSTATS;
+
+	i40e_read_stats_registers(pf, hw);
+
+	/* Reset */
+	if(xstats == NULL)
+		return 0;
+
+	/* copy from i40e_eth_stats struct */
+	for(i = 0; i < I40E_NB_ETH_XSTATS; i++) {
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "%s", rte_i40e_stats_strings[i].name);
+		xstats[count].value = *(uint64_t *)(((char *)&hw_stats->eth) +
+			rte_i40e_stats_strings[i].offset);
+		count++;
+	}
+
+	/* copy from i40e_hw_port struct */
+	for(i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) {
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "%s", rte_i40e_hw_port_strings[i].name);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				rte_i40e_hw_port_strings[i].offset);
+		count++;
+	}
+
+	return I40E_NB_XSTATS;
+}
+
 /* Reset the statistics */
 static void
 i40e_dev_stats_reset(struct rte_eth_dev *dev)
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v3 10/11] i40evf: add xstats() implementation
  2015-10-22 15:48   ` [dpdk-dev] [PATCH v3 00/11] Port XStats Harry van Haaren
                       ` (8 preceding siblings ...)
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 09/11] i40e: add xstats() implementation Harry van Haaren
@ 2015-10-22 15:48     ` Harry van Haaren
  2015-10-28 12:15       ` Tahhan, Maryam
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 11/11] fm10k: " Harry van Haaren
  2015-10-28 17:35     ` [dpdk-dev] [PATCH v3 00/11] Port XStats Tom Crugnale
  11 siblings, 1 reply; 77+ messages in thread
From: Harry van Haaren @ 2015-10-22 15:48 UTC (permalink / raw)
  To: dev

Add implementation of xstats() functions in i40evf PMD.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/i40e/i40e_ethdev_vf.c | 89 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 86 insertions(+), 3 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index b694400..3181400 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -112,6 +112,9 @@ static int i40evf_dev_link_update(struct rte_eth_dev *dev,
 				  __rte_unused int wait_to_complete);
 static void i40evf_dev_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *stats);
+static int i40evf_dev_xstats_get(struct rte_eth_dev *dev,
+				 struct rte_eth_xstats *xstats, unsigned n);
+static void i40evf_dev_xstats_reset(struct rte_eth_dev *dev);
 static int i40evf_vlan_filter_set(struct rte_eth_dev *dev,
 				  uint16_t vlan_id, int on);
 static void i40evf_vlan_offload_set(struct rte_eth_dev *dev, int mask);
@@ -148,6 +151,30 @@ static int i40evf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 /* Default hash key buffer for RSS */
 static uint32_t rss_key_default[I40E_VFQF_HKEY_MAX_INDEX + 1];
 
+struct rte_i40evf_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	unsigned offset;
+};
+
+static const struct rte_i40evf_xstats_name_off rte_i40evf_stats_strings[] = {
+	{"rx_bytes", offsetof(struct i40e_eth_stats, rx_bytes)},
+	{"rx_unicast_packets", offsetof(struct i40e_eth_stats, rx_unicast)},
+	{"rx_multicast_packets", offsetof(struct i40e_eth_stats, rx_multicast)},
+	{"rx_broadcast_packets", offsetof(struct i40e_eth_stats, rx_broadcast)},
+	{"rx_dropped_packets", offsetof(struct i40e_eth_stats, rx_discards)},
+	{"rx_unknown_protocol_packets", offsetof(struct i40e_eth_stats,
+		rx_unknown_protocol)},
+	{"tx_bytes", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_unicast_packets", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_multicast_packets", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_broadcast_packets", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_dropped_packets", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_error_packets", offsetof(struct i40e_eth_stats, tx_bytes)},
+};
+
+#define I40EVF_NB_XSTATS (sizeof(rte_i40evf_stats_strings) / \
+		sizeof(rte_i40evf_stats_strings[0]))
+
 static const struct eth_dev_ops i40evf_eth_dev_ops = {
 	.dev_configure        = i40evf_dev_configure,
 	.dev_start            = i40evf_dev_start,
@@ -158,6 +185,8 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = {
 	.allmulticast_disable = i40evf_dev_allmulticast_disable,
 	.link_update          = i40evf_dev_link_update,
 	.stats_get            = i40evf_dev_stats_get,
+	.xstats_get           = i40evf_dev_xstats_get,
+	.xstats_reset         = i40evf_dev_xstats_reset,
 	.dev_close            = i40evf_dev_close,
 	.dev_infos_get        = i40evf_dev_info_get,
 	.vlan_filter_set      = i40evf_vlan_filter_set,
@@ -888,11 +917,10 @@ i40evf_del_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 }
 
 static int
-i40evf_get_statics(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+i40evf_update_stats(struct rte_eth_dev *dev, struct i40e_eth_stats **pstats)
 {
 	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 	struct i40e_virtchnl_queue_select q_stats;
-	struct i40e_eth_stats *pstats;
 	int err;
 	struct vf_cmd_info args;
 
@@ -907,9 +935,23 @@ i40evf_get_statics(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	err = i40evf_execute_vf_cmd(dev, &args);
 	if (err) {
 		PMD_DRV_LOG(ERR, "fail to execute command OP_GET_STATS");
+		*pstats = NULL;
 		return err;
 	}
-	pstats = (struct i40e_eth_stats *)args.out_buffer;
+	*pstats = (struct i40e_eth_stats *)args.out_buffer;
+	return 0;
+}
+
+static int
+i40evf_get_statics(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+	int ret;
+	struct i40e_eth_stats *pstats = NULL;
+
+	ret = i40evf_update_stats(dev, &pstats);
+	if(ret != 0)
+		return 0;
+
 	stats->ipackets = pstats->rx_unicast + pstats->rx_multicast +
 						pstats->rx_broadcast;
 	stats->opackets = pstats->tx_broadcast + pstats->tx_multicast +
@@ -922,6 +964,47 @@ i40evf_get_statics(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	return 0;
 }
 
+static void
+i40evf_dev_xstats_reset(struct rte_eth_dev *dev)
+{
+	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+	struct i40e_eth_stats *pstats = NULL;
+
+	/* read stat values to clear hardware registers */
+	i40evf_update_stats(dev, &pstats);
+
+	/* set stats offset base on current values */
+	vf->vsi.eth_stats_offset = vf->vsi.eth_stats;
+}
+
+static int i40evf_dev_xstats_get(struct rte_eth_dev *dev,
+				 struct rte_eth_xstats *xstats, unsigned n)
+{
+	int ret;
+	unsigned i;
+	struct i40e_eth_stats *pstats = NULL;
+
+	if(n < I40EVF_NB_XSTATS)
+		return I40EVF_NB_XSTATS;
+
+	ret = i40evf_update_stats(dev, &pstats);
+	if(ret != 0)
+		return 0;
+
+	if(!xstats)
+		return 0;
+
+	/* loop over xstats array and values from pstats */
+	for(i = 0; i < I40EVF_NB_XSTATS; i++) {
+		snprintf(xstats[i].name, sizeof(xstats[i].name),
+			 "%s", rte_i40evf_stats_strings[i].name);
+		xstats[i].value = *(uint64_t *)(((char *)pstats) +
+			rte_i40evf_stats_strings[i].offset);
+	}
+
+	return I40EVF_NB_XSTATS;
+}
+
 static int
 i40evf_add_vlan(struct rte_eth_dev *dev, uint16_t vlanid)
 {
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v3 11/11] fm10k: add xstats() implementation
  2015-10-22 15:48   ` [dpdk-dev] [PATCH v3 00/11] Port XStats Harry van Haaren
                       ` (9 preceding siblings ...)
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 10/11] i40evf: " Harry van Haaren
@ 2015-10-22 15:48     ` Harry van Haaren
  2015-10-29 16:41       ` Tahhan, Maryam
  2015-10-28 17:35     ` [dpdk-dev] [PATCH v3 00/11] Port XStats Tom Crugnale
  11 siblings, 1 reply; 77+ messages in thread
From: Harry van Haaren @ 2015-10-22 15:48 UTC (permalink / raw)
  To: dev

Add xstats() functions and statistic strings.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/fm10k/fm10k_ethdev.c | 87 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 87 insertions(+)

diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index a69c990..acd663c 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -68,6 +68,46 @@ fm10k_MACVLAN_remove_all(struct rte_eth_dev *dev);
 static void fm10k_tx_queue_release(void *queue);
 static void fm10k_rx_queue_release(void *queue);
 
+struct fm10k_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	unsigned offset;
+};
+
+struct fm10k_xstats_name_off fm10k_hw_stats_strings[] = {
+	{"completion_timeout_count", offsetof(struct fm10k_hw_stats, timeout)},
+	{"unsupported_requests_count", offsetof(struct fm10k_hw_stats, ur)},
+	{"completer_abort_count", offsetof(struct fm10k_hw_stats, ca)},
+	{"unsupported_message_count", offsetof(struct fm10k_hw_stats, um)},
+	{"checksum_error_count", offsetof(struct fm10k_hw_stats, xec)},
+	{"vlan_dropped", offsetof(struct fm10k_hw_stats, vlan_drop)},
+	{"loopback_dropped", offsetof(struct fm10k_hw_stats, loopback_drop)},
+	{"rx_mbuf_allocation_errors", offsetof(struct fm10k_hw_stats,
+		nodesc_drop)},
+};
+
+#define FM10K_NB_HW_XSTATS (sizeof(fm10k_hw_stats_strings) / \
+		sizeof(fm10k_hw_stats_strings[0]))
+
+struct fm10k_xstats_name_off fm10k_hw_stats_rx_q_strings[] = {
+	{"packets", offsetof(struct fm10k_hw_stats_q, rx_packets)},
+	{"bytes", offsetof(struct fm10k_hw_stats_q, rx_bytes)},
+	{"dropped", offsetof(struct fm10k_hw_stats_q, rx_drops)},
+};
+
+#define FM10K_NB_RX_Q_XSTATS (sizeof(fm10k_hw_stats_rx_q_strings) / \
+		sizeof(fm10k_hw_stats_rx_q_strings[0]))
+
+struct fm10k_xstats_name_off fm10k_hw_stats_tx_q_strings[] = {
+	{"packets", offsetof(struct fm10k_hw_stats_q, tx_packets)},
+	{"bytes", offsetof(struct fm10k_hw_stats_q, tx_bytes)},
+};
+
+#define FM10K_NB_TX_Q_XSTATS (sizeof(fm10k_hw_stats_tx_q_strings) / \
+		sizeof(fm10k_hw_stats_tx_q_strings[0]))
+
+#define FM10K_NB_XSTATS (FM10K_NB_HW_XSTATS + FM10K_MAX_QUEUES_PF * \
+		(FM10K_NB_RX_Q_XSTATS + FM10K_NB_TX_Q_XSTATS))
+
 static void
 fm10k_mbx_initlock(struct fm10k_hw *hw)
 {
@@ -867,6 +907,51 @@ fm10k_link_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static int
+fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		 unsigned n)
+{
+	struct fm10k_hw_stats *hw_stats =
+		FM10K_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+	unsigned i, q, count = 0;
+
+	if(n < FM10K_NB_XSTATS)
+		return FM10K_NB_XSTATS;
+
+	/* Global stats */
+	for(i = 0; i < FM10K_NB_HW_XSTATS; i++) {
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "%s", fm10k_hw_stats_strings[count].name);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+			fm10k_hw_stats_strings[count].offset);
+		count++;
+	}
+
+	/* PF queue stats */
+	for(q = 0; q < FM10K_MAX_QUEUES_PF; q++) {
+		for(i = 0; i < FM10K_NB_RX_Q_XSTATS; i++) {
+			snprintf(xstats[count].name, sizeof(xstats[count].name),
+				 "rx_q%u_%s", q,
+				 fm10k_hw_stats_rx_q_strings[i].name);
+			xstats[count].value =
+				*(uint64_t *)(((char *)&hw_stats->q[q]) +
+				fm10k_hw_stats_rx_q_strings[i].offset);
+			count++;
+		}
+		for(i = 0; i < FM10K_NB_TX_Q_XSTATS; i++) {
+			snprintf(xstats[count].name, sizeof(xstats[count].name),
+				 "tx_q%u_%s", q,
+				 fm10k_hw_stats_tx_q_strings[i].name);
+			xstats[count].value =
+				*(uint64_t *)(((char *)&hw_stats->q[q]) +
+				fm10k_hw_stats_tx_q_strings[i].offset);
+			count++;
+		}
+	}
+
+	return FM10K_NB_XSTATS;
+}
+
 static void
 fm10k_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 {
@@ -2034,7 +2119,9 @@ static const struct eth_dev_ops fm10k_eth_dev_ops = {
 	.allmulticast_enable    = fm10k_dev_allmulticast_enable,
 	.allmulticast_disable   = fm10k_dev_allmulticast_disable,
 	.stats_get		= fm10k_stats_get,
+	.xstats_get		= fm10k_xstats_get,
 	.stats_reset		= fm10k_stats_reset,
+	.xstats_reset		= fm10k_stats_reset,
 	.link_update		= fm10k_link_update,
 	.dev_infos_get		= fm10k_dev_infos_get,
 	.vlan_filter_set	= fm10k_vlan_filter_set,
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 02/11] doc: add extended statistics to prog_guide
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 02/11] doc: add extended statistics to prog_guide Harry van Haaren
@ 2015-10-23 14:29       ` Tahhan, Maryam
  0 siblings, 0 replies; 77+ messages in thread
From: Tahhan, Maryam @ 2015-10-23 14:29 UTC (permalink / raw)
  To: Van Haaren, Harry, dev

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Harry van Haaren
> Sent: Thursday, October 22, 2015 4:48 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v3 02/11] doc: add extended statistics to
> prog_guide
> 
> Add extended statistic section to the programmers guide, poll mode driver
> section. This section describes how the strings stats are formatted, and how
> the client code can use this to gather information about the stat.
> 
> Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
> ---
>  doc/guides/prog_guide/poll_mode_drv.rst | 51
> ++++++++++++++++++++++++++++++++-
>  1 file changed, 50 insertions(+), 1 deletion(-)
> 
> diff --git a/doc/guides/prog_guide/poll_mode_drv.rst
> b/doc/guides/prog_guide/poll_mode_drv.rst
> index 8780ba3..44cc9ce 100644
> --- a/doc/guides/prog_guide/poll_mode_drv.rst
> +++ b/doc/guides/prog_guide/poll_mode_drv.rst
> @@ -1,5 +1,5 @@
>  ..  BSD LICENSE
> -    Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> +    Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
>      All rights reserved.
> 
>      Redistribution and use in source and binary forms, with or without @@ -
> 294,3 +294,52 @@ Ethernet Device API  ~~~~~~~~~~~~~~~~~~~
> 
>  The Ethernet device API exported by the Ethernet PMDs is described in the
> *DPDK API Reference*.
> +
> +Extended Statistics API
> +~~~~~~~~~~~~~~~~~~~~~~~
> +
> +The extended statistics API allows each individual PMD to expose a
> +unique set of statistics. The client of the API provides an array of
> +``struct rte_eth_xstats`` type. Each ``struct rte_eth_xstats`` contains
> +a string and value pair. The amount of xstats exposed, and position of
> +the statistic in the array must remain constant during runtime.
> +
> +A naming scheme exists for the strings exposed to clients of the API.
> +This is to allow scraping of the API for statistics of interest. The
> +naming scheme uses strings split by a single underscore ``_``. The scheme is
> as follows:
> +
> +* direction
> +* detail 1
> +* detail 2
> +* detail n
> +* unit
> +
> +Examples of common statistics xstats strings, formatted to comply to
> +the scheme proposed above:
> +
> +* ``rx_bytes``
> +* ``rx_crc_errors``
> +* ``tx_multicast_packets``
> +
> +The scheme, although quite simple, allows flexibility in presenting and
> +reading information from the statistic strings. The following example
> +illustrates the naming scheme:``rx_packets``. In this example, the
> +string is split into two components. The first component ``rx``
> +indicates that the statistic is associated with the receive side of the
> +NIC.  The second component ``packets`` indicates that the unit of measure is
> packets.
> +
> +A more complicated example: ``tx_size_128_to_255_packets``. In this
> +example, ``tx`` indicates transmission, ``size``  is the first detail,
> +``128`` etc are more details, and ``packets`` indicates that this is a packet
> counter.
> +
> +Some additions in the metadata scheme are as follows:
> +
> +* If the first part does not match ``rx`` or ``tx``, the statistic does
> +not
> +  have an affinity with either recieve of transmit.
> +
> +* If the first letter of the second part is ``q`` and this ``q`` is
> +followed
> +  by a number, this statistic is part of a specific queue.
> +
> +An example where queue numbers are used is as follows: ``tx_q7_bytes``
> +which indicates this statistic applies to queue number 7, and
> +represents the number of transmitted bytes on that queue.
> --
> 1.9.1
Acked-by: Maryam Tahhan <maryam.tahhan@intel.com>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 03/11] ethdev: update xstats_get() strings and Q handling
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 03/11] ethdev: update xstats_get() strings and Q handling Harry van Haaren
@ 2015-10-23 14:35       ` Tahhan, Maryam
  2015-10-23 15:28         ` Tahhan, Maryam
  2015-10-23 15:28       ` Tahhan, Maryam
  1 sibling, 1 reply; 77+ messages in thread
From: Tahhan, Maryam @ 2015-10-23 14:35 UTC (permalink / raw)
  To: Van Haaren, Harry, dev

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Harry van Haaren
> Sent: Thursday, October 22, 2015 4:48 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v3 03/11] ethdev: update xstats_get() strings and
> Q handling
> 
> Update the strings used for presenting stats to adhere to the scheme
> previously presented. Updated xstats_get() function to handle Q information
> only if xstats() is not implemented in the PMD, providing the PMD with the
> needed flexibility to expose its extended Q stats.
> 
> Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
> ---
>  lib/librte_ether/rte_ethdev.c | 38 +++++++++++++++++++++++---------------
>  1 file changed, 23 insertions(+), 15 deletions(-)
> 
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index f593f6e..07f0c26 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -137,27 +137,30 @@ struct rte_eth_xstats_name_off {  };
> 
>  static const struct rte_eth_xstats_name_off rte_stats_strings[] = {
> -	{"rx_packets", offsetof(struct rte_eth_stats, ipackets)},
> -	{"tx_packets", offsetof(struct rte_eth_stats, opackets)},
> -	{"rx_bytes", offsetof(struct rte_eth_stats, ibytes)},
> -	{"tx_bytes", offsetof(struct rte_eth_stats, obytes)},
> -	{"tx_errors", offsetof(struct rte_eth_stats, oerrors)},
> +	{"rx_good_packets", offsetof(struct rte_eth_stats, ipackets)},
> +	{"tx_good_packets", offsetof(struct rte_eth_stats, opackets)},
> +	{"rx_good_bytes", offsetof(struct rte_eth_stats, ibytes)},
> +	{"tx_good_bytes", offsetof(struct rte_eth_stats, obytes)},

Hi Harry
If there are any apps today scraping the existing stats this will cause an issue.
I think the "good" description breaks the meaning of the various stats defined in the header. For example rx_packets is Total number of successfully received packets rather than the "good" packets.

BR
Maryam
>  	{"rx_errors", offsetof(struct rte_eth_stats, ierrors)},
> -	{"alloc_rx_buff_failed", offsetof(struct rte_eth_stats, rx_nombuf)},
> +	{"tx_errors", offsetof(struct rte_eth_stats, oerrors)},
> +	{"rx_mbuf_allocation_errors", offsetof(struct rte_eth_stats,
> +		rx_nombuf)},
>  };
> +
>  #define RTE_NB_STATS (sizeof(rte_stats_strings) / sizeof(rte_stats_strings[0]))
> 
>  static const struct rte_eth_xstats_name_off rte_rxq_stats_strings[] = {
> -	{"rx_packets", offsetof(struct rte_eth_stats, q_ipackets)},
> -	{"rx_bytes", offsetof(struct rte_eth_stats, q_ibytes)},
> +	{"packets", offsetof(struct rte_eth_stats, q_ipackets)},
> +	{"bytes", offsetof(struct rte_eth_stats, q_ibytes)},
> +	{"errors", offsetof(struct rte_eth_stats, q_errors)},
>  };
> +
>  #define RTE_NB_RXQ_STATS (sizeof(rte_rxq_stats_strings) /	\
>  		sizeof(rte_rxq_stats_strings[0]))
> 
>  static const struct rte_eth_xstats_name_off rte_txq_stats_strings[] = {
> -	{"tx_packets", offsetof(struct rte_eth_stats, q_opackets)},
> -	{"tx_bytes", offsetof(struct rte_eth_stats, q_obytes)},
> -	{"tx_errors", offsetof(struct rte_eth_stats, q_errors)},
> +	{"packets", offsetof(struct rte_eth_stats, q_opackets)},
> +	{"bytes", offsetof(struct rte_eth_stats, q_obytes)},
>  };
>  #define RTE_NB_TXQ_STATS (sizeof(rte_txq_stats_strings) /	\
>  		sizeof(rte_txq_stats_strings[0]))
> @@ -1666,8 +1669,6 @@ rte_eth_xstats_get(uint8_t port_id, struct
> rte_eth_xstats *xstats,
> 
>  	/* Return generic statistics */
>  	count = RTE_NB_STATS;
> -	count += dev->data->nb_rx_queues * RTE_NB_RXQ_STATS;
> -	count += dev->data->nb_tx_queues * RTE_NB_TXQ_STATS;
> 
>  	/* implemented by the driver */
>  	if (dev->dev_ops->xstats_get != NULL) { @@ -1679,6 +1680,9 @@
> rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
> 
>  		if (xcount < 0)
>  			return xcount;
> +	} else {
> +		count += dev->data->nb_rx_queues * RTE_NB_RXQ_STATS;
> +		count += dev->data->nb_tx_queues * RTE_NB_TXQ_STATS;
>  	}
> 
>  	if (n < count + xcount)
> @@ -1698,6 +1702,10 @@ rte_eth_xstats_get(uint8_t port_id, struct
> rte_eth_xstats *xstats,
>  		xstats[count++].value = val;
>  	}
> 
> +	/* if xstats_get() is implemented by the PMD, the Q stats are done */
> +	if (dev->dev_ops->xstats_get != NULL)
> +		return count + xcount;
> +
>  	/* per-rxq stats */
>  	for (q = 0; q < dev->data->nb_rx_queues; q++) {
>  		for (i = 0; i < RTE_NB_RXQ_STATS; i++) { @@ -1706,7 +1714,7
> @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
>  					q * sizeof(uint64_t));
>  			val = *stats_ptr;
>  			snprintf(xstats[count].name,
> sizeof(xstats[count].name),
> -				"rx_queue_%u_%s", q,
> +				"rx_q%u_%s", q,
>  				rte_rxq_stats_strings[i].name);
>  			xstats[count++].value = val;
>  		}
> @@ -1720,7 +1728,7 @@ rte_eth_xstats_get(uint8_t port_id, struct
> rte_eth_xstats *xstats,
>  					q * sizeof(uint64_t));
>  			val = *stats_ptr;
>  			snprintf(xstats[count].name,
> sizeof(xstats[count].name),
> -				"tx_queue_%u_%s", q,
> +				"tx_q%u_%s", q,
>  				rte_txq_stats_strings[i].name);
>  			xstats[count++].value = val;
>  		}
> --
> 1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 07/11] ixgbe: update statistic strings to scheme
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 07/11] ixgbe: update statistic strings to scheme Harry van Haaren
@ 2015-10-23 14:41       ` Tahhan, Maryam
  0 siblings, 0 replies; 77+ messages in thread
From: Tahhan, Maryam @ 2015-10-23 14:41 UTC (permalink / raw)
  To: Van Haaren, Harry, dev

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Harry van Haaren
> Sent: Thursday, October 22, 2015 4:49 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v3 07/11] ixgbe: update statistic strings to
> scheme
> 
> Updated and add statistic strings as used by xstats_get().
> 
> Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
> ---
>  drivers/net/ixgbe/ixgbe_ethdev.c | 295
> ++++++++++++++++++++++++++++++++++++---
>  1 file changed, 273 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c
> b/drivers/net/ixgbe/ixgbe_ethdev.c
> index 1e5ffbf..2e9e260 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -506,29 +506,280 @@ struct rte_ixgbe_xstats_name_off {  };
> 
>  static const struct rte_ixgbe_xstats_name_off rte_ixgbe_stats_strings[] = {
> -	{"rx_illegal_byte_err", offsetof(struct ixgbe_hw_stats, errbc)},
> -	{"rx_len_err", offsetof(struct ixgbe_hw_stats, rlec)},
> -	{"rx_undersize_count", offsetof(struct ixgbe_hw_stats, ruc)},
> -	{"rx_oversize_count", offsetof(struct ixgbe_hw_stats, roc)},
> -	{"rx_fragment_count", offsetof(struct ixgbe_hw_stats, rfc)},
> -	{"rx_jabber_count", offsetof(struct ixgbe_hw_stats, rjc)},
> -	{"l3_l4_xsum_error", offsetof(struct ixgbe_hw_stats, xec)},
> -	{"mac_local_fault", offsetof(struct ixgbe_hw_stats, mlfc)},
> -	{"mac_remote_fault", offsetof(struct ixgbe_hw_stats, mrfc)},
> -	{"mac_short_pkt_discard", offsetof(struct ixgbe_hw_stats, mspdc)},
> -	{"fccrc_error", offsetof(struct ixgbe_hw_stats, fccrc)},
> -	{"fcoe_drop", offsetof(struct ixgbe_hw_stats, fcoerpdc)},
> -	{"fc_last_error", offsetof(struct ixgbe_hw_stats, fclast)},
> -	{"rx_broadcast_packets", offsetof(struct ixgbe_hw_stats, bprc)},
> -	{"rx_phy_multicast_packets", offsetof(struct ixgbe_hw_stats, mprc)},
> -	{"mgmt_pkts_dropped", offsetof(struct ixgbe_hw_stats, mngpdc)},
>  	{"rx_crc_errors", offsetof(struct ixgbe_hw_stats, crcerrs)},
> -	{"fdir_match", offsetof(struct ixgbe_hw_stats, fdirmatch)},
> -	{"fdir_miss", offsetof(struct ixgbe_hw_stats, fdirmiss)},
> -	{"tx_flow_control_xon", offsetof(struct ixgbe_hw_stats, lxontxc)},
> -	{"rx_flow_control_xon", offsetof(struct ixgbe_hw_stats, lxonrxc)},
> -	{"tx_flow_control_xoff", offsetof(struct ixgbe_hw_stats, lxofftxc)},
> -	{"rx_flow_control_xoff", offsetof(struct ixgbe_hw_stats, lxoffrxc)},
> +	{"rx_illegal_byte_errors", offsetof(struct ixgbe_hw_stats, illerrc)},
> +	{"rx_error_bytes", offsetof(struct ixgbe_hw_stats, errbc)},
> +	{"mac_local_errors", offsetof(struct ixgbe_hw_stats, mlfc)},
> +	{"mac_remote_errors", offsetof(struct ixgbe_hw_stats, mrfc)},
> +	{"rx_length_errors", offsetof(struct ixgbe_hw_stats, rlec)},
> +	{"tx_xon_packets", offsetof(struct ixgbe_hw_stats, lxontxc)},
> +	{"rx_xon_packets", offsetof(struct ixgbe_hw_stats, lxonrxc)},
> +	{"tx_xoff_packets", offsetof(struct ixgbe_hw_stats, lxofftxc)},
> +	{"rx_xoff_packets", offsetof(struct ixgbe_hw_stats, lxoffrxc)},
> +	{"rx_size_64_packets", offsetof(struct ixgbe_hw_stats, prc64)},
> +	{"rx_size_65_to_127_packets", offsetof(struct ixgbe_hw_stats,
> prc127)},
> +	{"rx_size_128_to_255_packets", offsetof(struct ixgbe_hw_stats,
> prc255)},
> +	{"rx_size_256_to_511_packets", offsetof(struct ixgbe_hw_stats,
> prc511)},
> +	{"rx_size_512_to_1023_packets", offsetof(struct ixgbe_hw_stats,
> +		prc1023)},
> +	{"rx_size_1024_to_max_packets", offsetof(struct ixgbe_hw_stats,
> +		prc1522)},
> +	{"rx_broadcast_packets", offsetof(struct ixgbe_hw_stats, bprc)},
> +	{"rx_multicast_packets", offsetof(struct ixgbe_hw_stats, mprc)},
> +	{"rx_fragment_errors", offsetof(struct ixgbe_hw_stats, rfc)},
> +	{"rx_undersize_errors", offsetof(struct ixgbe_hw_stats, ruc)},
> +	{"rx_oversize_errors", offsetof(struct ixgbe_hw_stats, roc)},
> +	{"rx_jabber_errors", offsetof(struct ixgbe_hw_stats, rjc)},
> +	{"rx_managment_packets", offsetof(struct ixgbe_hw_stats, mngprc)},
> +	{"rx_managment_dropped", offsetof(struct ixgbe_hw_stats, mngpdc)},
> +	{"tx_managment_packets", offsetof(struct ixgbe_hw_stats, mngptc)},
> +	{"rx_total_packets", offsetof(struct ixgbe_hw_stats, tpr)},
> +	{"rx_total_bytes", offsetof(struct ixgbe_hw_stats, tor)},
> +	{"tx_total_packets", offsetof(struct ixgbe_hw_stats, tpt)},
> +	{"tx_size_64_packets", offsetof(struct ixgbe_hw_stats, ptc64)},
> +	{"tx_size_65_to_127_packets", offsetof(struct ixgbe_hw_stats,
> ptc127)},
> +	{"tx_size_128_to_255_packets", offsetof(struct ixgbe_hw_stats,
> ptc255)},
> +	{"tx_size_256_to_511_packets", offsetof(struct ixgbe_hw_stats,
> ptc511)},
> +	{"tx_size_512_to_1023_packets", offsetof(struct ixgbe_hw_stats,
> +		ptc1023)},
> +	{"tx_size_1024_to_max_packets", offsetof(struct ixgbe_hw_stats,
> +		ptc1522)},
> +	{"tx_multicast_packets", offsetof(struct ixgbe_hw_stats, mptc)},
> +	{"tx_broadcast_packets", offsetof(struct ixgbe_hw_stats, bptc)},
> +	{"rx_mac_short_packet_discard", offsetof(struct ixgbe_hw_stats,
> mspdc)},
> +	{"rx_l3_l4_xsum_error", offsetof(struct ixgbe_hw_stats, xec)},
> +
> +	{"flow_director_added_filters", offsetof(struct ixgbe_hw_stats,
> +		fdirustat_add)},
> +	{"flow_director_removed_filters", offsetof(struct ixgbe_hw_stats,
> +		fdirustat_remove)},
> +	{"flow_director_filter_add_errors", offsetof(struct ixgbe_hw_stats,
> +		fdirfstat_fadd)},
> +	{"flow_director_filter_remove_errors", offsetof(struct
> ixgbe_hw_stats,
> +		fdirfstat_fremove)},
> +	{"flow_director_matched_filters", offsetof(struct ixgbe_hw_stats,
> +		fdirmatch)},
> +	{"flow_director_missed_filters", offsetof(struct ixgbe_hw_stats,
> +		fdirmiss)},
> +
> +	{"rx_fcoe_crc_errors", offsetof(struct ixgbe_hw_stats, fccrc)},
> +	{"rx_fcoe_dropped", offsetof(struct ixgbe_hw_stats, fcoerpdc)},
> +	{"rx_fcoe_mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats,
> +		fclast)},
> +	{"rx_fcoe_packets", offsetof(struct ixgbe_hw_stats, fcoeprc)},
> +	{"tx_fcoe_packets", offsetof(struct ixgbe_hw_stats, fcoeptc)},
> +	{"rx_fcoe_bytes", offsetof(struct ixgbe_hw_stats, fcoedwrc)},
> +	{"tx_fcoe_bytes", offsetof(struct ixgbe_hw_stats, fcoedwtc)},
> +	{"rx_fcoe_no_direct_data_placement", offsetof(struct
> ixgbe_hw_stats,
> +		fcoe_noddp)},
> +	{"rx_fcoe_no_direct_data_placement_ext_buff",
> +		offsetof(struct ixgbe_hw_stats, fcoe_noddp_ext_buff)},
> +
> +	{"tx_flow_control_xon_packets", offsetof(struct ixgbe_hw_stats,
> +		lxontxc)},
> +	{"rx_flow_control_xon_packets", offsetof(struct ixgbe_hw_stats,
> +		lxonrxc)},
> +	{"tx_flow_control_xoff_packets", offsetof(struct ixgbe_hw_stats,
> +		lxofftxc)},
> +	{"rx_flow_control_xoff_packets", offsetof(struct ixgbe_hw_stats,
> +		lxoffrxc)},
> +	{"rx_total_missed_packets", offsetof(struct ixgbe_hw_stats,
> +mpctotal)},
> +
> +	{"rx_q0_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[0])},
> +	{"rx_q1_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[1])},
> +	{"rx_q2_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[2])},
> +	{"rx_q3_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[3])},
> +	{"rx_q4_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[4])},
> +	{"rx_q5_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[5])},
> +	{"rx_q6_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[6])},
> +	{"rx_q7_missed_packets", offsetof(struct ixgbe_hw_stats, mpc[7])},
> +
> +	{"rx_q0_mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats,
> +		rnbc[0])},
> +	{"rx_q1_mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats,
> +		rnbc[1])},
> +	{"rx_q2_mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats,
> +		rnbc[2])},
> +	{"rx_q3_mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats,
> +		rnbc[3])},
> +	{"rx_q4_mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats,
> +		rnbc[4])},
> +	{"rx_q5_mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats,
> +		rnbc[5])},
> +	{"rx_q6_mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats,
> +		rnbc[6])},
> +	{"rx_q7_mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats,
> +		rnbc[7])},
> +
> +	{"tx_q0_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxontxc[0])},
> +	{"tx_q1_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxontxc[1])},
> +	{"tx_q2_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxontxc[2])},
> +	{"tx_q3_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxontxc[3])},
> +	{"tx_q4_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxontxc[4])},
> +	{"tx_q5_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxontxc[5])},
> +	{"tx_q6_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxontxc[6])},
> +	{"tx_q7_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxontxc[7])},
> +
> +	{"rx_q0_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxonrxc[0])},
> +	{"rx_q1_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxonrxc[1])},
> +	{"rx_q2_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxonrxc[2])},
> +	{"rx_q3_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxonrxc[3])},
> +	{"rx_q4_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxonrxc[4])},
> +	{"rx_q5_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxonrxc[5])},
> +	{"rx_q6_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxonrxc[6])},
> +	{"rx_q7_xon_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxonrxc[7])},
> +
> +	{"tx_q0_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxofftxc[0])},
> +	{"tx_q1_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxofftxc[1])},
> +	{"tx_q2_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxofftxc[2])},
> +	{"tx_q3_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxofftxc[3])},
> +	{"tx_q4_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxofftxc[4])},
> +	{"tx_q5_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxofftxc[5])},
> +	{"tx_q6_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxofftxc[6])},
> +	{"tx_q7_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxofftxc[7])},
> +
> +	{"rx_q0_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxoffrxc[0])},
> +	{"rx_q1_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxoffrxc[1])},
> +	{"rx_q2_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxoffrxc[2])},
> +	{"rx_q3_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxoffrxc[3])},
> +	{"rx_q4_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxoffrxc[4])},
> +	{"rx_q5_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxoffrxc[5])},
> +	{"rx_q6_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxoffrxc[6])},
> +	{"rx_q7_xoff_priority_packets", offsetof(struct ixgbe_hw_stats,
> +		pxoffrxc[7])},
> +
> +	{"xx_q0_xon_to_off_priority_packets", offsetof(struct
> ixgbe_hw_stats,
> +		pxon2offc[0])},
> +	{"xx_q1_xon_to_off_priority_packets", offsetof(struct
> ixgbe_hw_stats,
> +		pxon2offc[1])},
> +	{"xx_q2_xon_to_off_priority_packets", offsetof(struct
> ixgbe_hw_stats,
> +		pxon2offc[2])},
> +	{"xx_q3_xon_to_off_priority_packets", offsetof(struct
> ixgbe_hw_stats,
> +		pxon2offc[3])},
> +	{"xx_q4_xon_to_off_priority_packets", offsetof(struct
> ixgbe_hw_stats,
> +		pxon2offc[4])},
> +	{"xx_q5_xon_to_off_priority_packets", offsetof(struct
> ixgbe_hw_stats,
> +		pxon2offc[5])},
> +	{"xx_q6_xon_to_off_priority_packets", offsetof(struct
> ixgbe_hw_stats,
> +		pxon2offc[6])},
> +	{"xx_q7_xon_to_off_priority_packets", offsetof(struct
> ixgbe_hw_stats,
> +		pxon2offc[7])},
> +
> +	{"rx_q0_packets", offsetof(struct ixgbe_hw_stats, qprc[0])},
> +	{"rx_q1_packets", offsetof(struct ixgbe_hw_stats, qprc[1])},
> +	{"rx_q2_packets", offsetof(struct ixgbe_hw_stats, qprc[2])},
> +	{"rx_q3_packets", offsetof(struct ixgbe_hw_stats, qprc[3])},
> +	{"rx_q4_packets", offsetof(struct ixgbe_hw_stats, qprc[4])},
> +	{"rx_q5_packets", offsetof(struct ixgbe_hw_stats, qprc[5])},
> +	{"rx_q6_packets", offsetof(struct ixgbe_hw_stats, qprc[6])},
> +	{"rx_q7_packets", offsetof(struct ixgbe_hw_stats, qprc[7])},
> +	{"rx_q8_packets", offsetof(struct ixgbe_hw_stats, qprc[8])},
> +	{"rx_q9_packets", offsetof(struct ixgbe_hw_stats, qprc[9])},
> +	{"rx_q10_packets", offsetof(struct ixgbe_hw_stats, qprc[10])},
> +	{"rx_q11_packets", offsetof(struct ixgbe_hw_stats, qprc[11])},
> +	{"rx_q12_packets", offsetof(struct ixgbe_hw_stats, qprc[12])},
> +	{"rx_q13_packets", offsetof(struct ixgbe_hw_stats, qprc[13])},
> +	{"rx_q14_packets", offsetof(struct ixgbe_hw_stats, qprc[14])},
> +	{"rx_q15_packets", offsetof(struct ixgbe_hw_stats, qprc[15])},
> +
> +	{"tx_q0_packets", offsetof(struct ixgbe_hw_stats, qptc[0])},
> +	{"tx_q1_packets", offsetof(struct ixgbe_hw_stats, qptc[1])},
> +	{"tx_q2_packets", offsetof(struct ixgbe_hw_stats, qptc[2])},
> +	{"tx_q3_packets", offsetof(struct ixgbe_hw_stats, qptc[3])},
> +	{"tx_q4_packets", offsetof(struct ixgbe_hw_stats, qptc[4])},
> +	{"tx_q5_packets", offsetof(struct ixgbe_hw_stats, qptc[5])},
> +	{"tx_q6_packets", offsetof(struct ixgbe_hw_stats, qptc[6])},
> +	{"tx_q7_packets", offsetof(struct ixgbe_hw_stats, qptc[7])},
> +	{"tx_q8_packets", offsetof(struct ixgbe_hw_stats, qptc[8])},
> +	{"tx_q9_packets", offsetof(struct ixgbe_hw_stats, qptc[9])},
> +	{"tx_q10_packets", offsetof(struct ixgbe_hw_stats, qptc[10])},
> +	{"tx_q11_packets", offsetof(struct ixgbe_hw_stats, qptc[11])},
> +	{"tx_q12_packets", offsetof(struct ixgbe_hw_stats, qptc[12])},
> +	{"tx_q13_packets", offsetof(struct ixgbe_hw_stats, qptc[13])},
> +	{"tx_q14_packets", offsetof(struct ixgbe_hw_stats, qptc[14])},
> +	{"tx_q15_packets", offsetof(struct ixgbe_hw_stats, qptc[15])},
> +
> +	{"rx_q0_bytes", offsetof(struct ixgbe_hw_stats, qbrc[0])},
> +	{"rx_q1_bytes", offsetof(struct ixgbe_hw_stats, qbrc[1])},
> +	{"rx_q2_bytes", offsetof(struct ixgbe_hw_stats, qbrc[2])},
> +	{"rx_q3_bytes", offsetof(struct ixgbe_hw_stats, qbrc[3])},
> +	{"rx_q4_bytes", offsetof(struct ixgbe_hw_stats, qbrc[4])},
> +	{"rx_q5_bytes", offsetof(struct ixgbe_hw_stats, qbrc[5])},
> +	{"rx_q6_bytes", offsetof(struct ixgbe_hw_stats, qbrc[6])},
> +	{"rx_q7_bytes", offsetof(struct ixgbe_hw_stats, qbrc[7])},
> +	{"rx_q8_bytes", offsetof(struct ixgbe_hw_stats, qbrc[8])},
> +	{"rx_q9_bytes", offsetof(struct ixgbe_hw_stats, qbrc[9])},
> +	{"rx_q10_bytes", offsetof(struct ixgbe_hw_stats, qbrc[10])},
> +	{"rx_q11_bytes", offsetof(struct ixgbe_hw_stats, qbrc[11])},
> +	{"rx_q12_bytes", offsetof(struct ixgbe_hw_stats, qbrc[12])},
> +	{"rx_q13_bytes", offsetof(struct ixgbe_hw_stats, qbrc[13])},
> +	{"rx_q14_bytes", offsetof(struct ixgbe_hw_stats, qbrc[14])},
> +	{"rx_q15_bytes", offsetof(struct ixgbe_hw_stats, qbrc[15])},
> +
> +	{"tx_q0_bytes", offsetof(struct ixgbe_hw_stats, qbtc[0])},
> +	{"tx_q1_bytes", offsetof(struct ixgbe_hw_stats, qbtc[1])},
> +	{"tx_q2_bytes", offsetof(struct ixgbe_hw_stats, qbtc[2])},
> +	{"tx_q3_bytes", offsetof(struct ixgbe_hw_stats, qbtc[3])},
> +	{"tx_q4_bytes", offsetof(struct ixgbe_hw_stats, qbtc[4])},
> +	{"tx_q5_bytes", offsetof(struct ixgbe_hw_stats, qbtc[5])},
> +	{"tx_q6_bytes", offsetof(struct ixgbe_hw_stats, qbtc[6])},
> +	{"tx_q7_bytes", offsetof(struct ixgbe_hw_stats, qbtc[7])},
> +	{"tx_q8_bytes", offsetof(struct ixgbe_hw_stats, qbtc[8])},
> +	{"tx_q9_bytes", offsetof(struct ixgbe_hw_stats, qbtc[9])},
> +	{"tx_q10_bytes", offsetof(struct ixgbe_hw_stats, qbtc[10])},
> +	{"tx_q11_bytes", offsetof(struct ixgbe_hw_stats, qbtc[11])},
> +	{"tx_q12_bytes", offsetof(struct ixgbe_hw_stats, qbtc[12])},
> +	{"tx_q13_bytes", offsetof(struct ixgbe_hw_stats, qbtc[13])},
> +	{"tx_q14_bytes", offsetof(struct ixgbe_hw_stats, qbtc[14])},
> +	{"tx_q15_bytes", offsetof(struct ixgbe_hw_stats, qbtc[15])},
> +
> +	{"rx_q0_dropped", offsetof(struct ixgbe_hw_stats, qprdc[0])},
> +	{"rx_q1_dropped", offsetof(struct ixgbe_hw_stats, qprdc[1])},
> +	{"rx_q2_dropped", offsetof(struct ixgbe_hw_stats, qprdc[2])},
> +	{"rx_q3_dropped", offsetof(struct ixgbe_hw_stats, qprdc[3])},
> +	{"rx_q4_dropped", offsetof(struct ixgbe_hw_stats, qprdc[4])},
> +	{"rx_q5_dropped", offsetof(struct ixgbe_hw_stats, qprdc[5])},
> +	{"rx_q6_dropped", offsetof(struct ixgbe_hw_stats, qprdc[6])},
> +	{"rx_q7_dropped", offsetof(struct ixgbe_hw_stats, qprdc[7])},
> +	{"rx_q8_dropped", offsetof(struct ixgbe_hw_stats, qprdc[8])},
> +	{"rx_q9_dropped", offsetof(struct ixgbe_hw_stats, qprdc[9])},
> +	{"rx_q10_dropped", offsetof(struct ixgbe_hw_stats, qprdc[10])},
> +	{"rx_q11_dropped", offsetof(struct ixgbe_hw_stats, qprdc[11])},
> +	{"rx_q12_dropped", offsetof(struct ixgbe_hw_stats, qprdc[12])},
> +	{"rx_q13_dropped", offsetof(struct ixgbe_hw_stats, qprdc[13])},
> +	{"rx_q14_dropped", offsetof(struct ixgbe_hw_stats, qprdc[14])},
> +	{"rx_q15_dropped", offsetof(struct ixgbe_hw_stats, qprdc[15])},
>  };
> 
>  #define IXGBE_NB_XSTATS (sizeof(rte_ixgbe_stats_strings) /	\
> --
> 1.9.1

Acked-by: Maryam Tahhan <maryam.tahhan@intel.com>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 05/11] igb: add xstats() implementation
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 05/11] igb: " Harry van Haaren
@ 2015-10-23 14:56       ` Tahhan, Maryam
  0 siblings, 0 replies; 77+ messages in thread
From: Tahhan, Maryam @ 2015-10-23 14:56 UTC (permalink / raw)
  To: Van Haaren, Harry, dev

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Harry van Haaren
> Sent: Thursday, October 22, 2015 4:48 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v3 05/11] igb: add xstats() implementation
> 
> Add xstats_get() and xstats_reset() functions to igb driver, and the neccessary
> strings to expose these NIC statistics.
> 
> Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>

Acked-by: Maryam Tahhan <maryam.tahhan@intel.com>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 09/11] i40e: add xstats() implementation
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 09/11] i40e: add xstats() implementation Harry van Haaren
@ 2015-10-23 15:11       ` Tahhan, Maryam
  0 siblings, 0 replies; 77+ messages in thread
From: Tahhan, Maryam @ 2015-10-23 15:11 UTC (permalink / raw)
  To: Van Haaren, Harry, dev

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Harry van Haaren
> Sent: Thursday, October 22, 2015 4:49 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v3 09/11] i40e: add xstats() implementation
> 
> Add xstats functions to i40e PMD, allowing extended statistics to be retrieved
> from the NIC and exposed to the DPDK.
> 
> Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>

Acked-by: Maryam Tahhan <maryam.tahhan@intel.com>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 03/11] ethdev: update xstats_get() strings and Q handling
  2015-10-23 14:35       ` Tahhan, Maryam
@ 2015-10-23 15:28         ` Tahhan, Maryam
  0 siblings, 0 replies; 77+ messages in thread
From: Tahhan, Maryam @ 2015-10-23 15:28 UTC (permalink / raw)
  To: Van Haaren, Harry, dev

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Tahhan, Maryam
> Sent: Friday, October 23, 2015 3:35 PM
> To: Van Haaren, Harry <harry.van.haaren@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v3 03/11] ethdev: update xstats_get() strings
> and Q handling
> 
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Harry van Haaren
> > Sent: Thursday, October 22, 2015 4:48 PM
> > To: dev@dpdk.org
> > Subject: [dpdk-dev] [PATCH v3 03/11] ethdev: update xstats_get()
> > strings and Q handling
> >
> > Update the strings used for presenting stats to adhere to the scheme
> > previously presented. Updated xstats_get() function to handle Q
> > information only if xstats() is not implemented in the PMD, providing
> > the PMD with the needed flexibility to expose its extended Q stats.
> >
> > Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
> > ---
> >  lib/librte_ether/rte_ethdev.c | 38
> > +++++++++++++++++++++++---------------
> >  1 file changed, 23 insertions(+), 15 deletions(-)
> >
> > diff --git a/lib/librte_ether/rte_ethdev.c
> > b/lib/librte_ether/rte_ethdev.c index f593f6e..07f0c26 100644
> > --- a/lib/librte_ether/rte_ethdev.c
> > +++ b/lib/librte_ether/rte_ethdev.c
> > @@ -137,27 +137,30 @@ struct rte_eth_xstats_name_off {  };
> >
> >  static const struct rte_eth_xstats_name_off rte_stats_strings[] = {
> > -	{"rx_packets", offsetof(struct rte_eth_stats, ipackets)},
> > -	{"tx_packets", offsetof(struct rte_eth_stats, opackets)},
> > -	{"rx_bytes", offsetof(struct rte_eth_stats, ibytes)},
> > -	{"tx_bytes", offsetof(struct rte_eth_stats, obytes)},
> > -	{"tx_errors", offsetof(struct rte_eth_stats, oerrors)},
> > +	{"rx_good_packets", offsetof(struct rte_eth_stats, ipackets)},
> > +	{"tx_good_packets", offsetof(struct rte_eth_stats, opackets)},
> > +	{"rx_good_bytes", offsetof(struct rte_eth_stats, ibytes)},
> > +	{"tx_good_bytes", offsetof(struct rte_eth_stats, obytes)},
> 
> Hi Harry
> If there are any apps today scraping the existing stats this will cause an issue.
> I think the "good" description breaks the meaning of the various stats defined
> in the header. For example rx_packets is Total number of successfully
> received packets rather than the "good" packets.
> 
> BR
> Maryam
> >  	{"rx_errors", offsetof(struct rte_eth_stats, ierrors)},

My bad, was quoting the wrong stats register... I'm happy with this change

<snip>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 03/11] ethdev: update xstats_get() strings and Q handling
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 03/11] ethdev: update xstats_get() strings and Q handling Harry van Haaren
  2015-10-23 14:35       ` Tahhan, Maryam
@ 2015-10-23 15:28       ` Tahhan, Maryam
  1 sibling, 0 replies; 77+ messages in thread
From: Tahhan, Maryam @ 2015-10-23 15:28 UTC (permalink / raw)
  To: Van Haaren, Harry, dev

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Harry van Haaren
> Sent: Thursday, October 22, 2015 4:48 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v3 03/11] ethdev: update xstats_get() strings and
> Q handling
> 
> Update the strings used for presenting stats to adhere to the scheme
> previously presented. Updated xstats_get() function to handle Q information
> only if xstats() is not implemented in the PMD, providing the PMD with the
> needed flexibility to expose its extended Q stats.
> 
> Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>

Acked-by: Maryam Tahhan <maryam.tahhan@intel.com>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 10/11] i40evf: add xstats() implementation
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 10/11] i40evf: " Harry van Haaren
@ 2015-10-28 12:15       ` Tahhan, Maryam
  0 siblings, 0 replies; 77+ messages in thread
From: Tahhan, Maryam @ 2015-10-28 12:15 UTC (permalink / raw)
  To: Van Haaren, Harry, dev

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Harry van Haaren
> Sent: Thursday, October 22, 2015 4:49 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v3 10/11] i40evf: add xstats() implementation
> 
> Add implementation of xstats() functions in i40evf PMD.
> 
> Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
> ---

Acked-by: Maryam Tahhan <maryam.tahhan@intel.com>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 08/11] ixgbevf: add xstats() functions to VF
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 08/11] ixgbevf: add xstats() functions to VF Harry van Haaren
@ 2015-10-28 12:16       ` Tahhan, Maryam
  0 siblings, 0 replies; 77+ messages in thread
From: Tahhan, Maryam @ 2015-10-28 12:16 UTC (permalink / raw)
  To: Van Haaren, Harry, dev

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Harry van Haaren
> Sent: Thursday, October 22, 2015 4:49 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v3 08/11] ixgbevf: add xstats() functions to VF
> 
> Add xstats() functions and stat strings as necessary to ixgbevf PMD.
> 
> Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
> ---

Acked-by: Maryam Tahhan <maryam.tahhan@intel.com>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 06/11] igbvf: add xstats() implementation
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 06/11] igbvf: " Harry van Haaren
@ 2015-10-28 12:17       ` Tahhan, Maryam
  0 siblings, 0 replies; 77+ messages in thread
From: Tahhan, Maryam @ 2015-10-28 12:17 UTC (permalink / raw)
  To: Van Haaren, Harry, dev

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Harry van Haaren
> Sent: Thursday, October 22, 2015 4:48 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v3 06/11] igbvf: add xstats() implementation
> 
> Add xstats functionality to igbvf PMD, adding necessary statistic strings.
> 
> Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
> ---

Acked-by: Maryam Tahhan <maryam.tahhan@intel.com>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 00/11] Port XStats
  2015-10-22 15:48   ` [dpdk-dev] [PATCH v3 00/11] Port XStats Harry van Haaren
                       ` (10 preceding siblings ...)
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 11/11] fm10k: " Harry van Haaren
@ 2015-10-28 17:35     ` Tom Crugnale
  2015-10-28 21:32       ` Stephen Hemminger
  11 siblings, 1 reply; 77+ messages in thread
From: Tom Crugnale @ 2015-10-28 17:35 UTC (permalink / raw)
  To: Harry van Haaren, dev

Hi Harry,

We are planning on using the xstats API for periodic stats collection through a polling thread.  This would be done in a generic NIC agnostic manner, which would require that the xstats identifiers have consistent naming amongst all of the NIC types.  It would likely be polled several times per second and would only gather a subset of all available xstats types.  

I have reviewed your patches and am interested in providing some API enhancements and bugfixes.  Are you willing to provide feedback on such changes?

Thank you,
Tom

-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Harry van Haaren
Sent: Thursday, October 22, 2015 11:48 AM
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH v3 00/11] Port XStats

This patchset adds an implementation of the xstats_get() and xstats_reset() API to the following PMDs: virtio, igb, igbvf, ixgbe, ixgbevf, i40e, i40evf and fm10k.

The xstats API allows DPDK apps to gain access to extended statistics from each port on a NIC. These statistics are structured as per a scheme detailed in the patch for the doc/prog_guide.


Harry van Haaren (11):
  doc: add extended statistics notes
  doc: add extended statistics to prog_guide
  ethdev: update xstats_get() strings and Q handling
  virtio: add xstats() implementation
  igb: add xstats() implementation
  igbvf: add xstats() implementation
  ixgbe: update statistic strings to scheme
  ixgbevf: add xstats() functions to VF
  i40e: add xstats() implementation
  i40evf: add xstats() implementation
  fm10k: add xstats() implementation

 doc/guides/prog_guide/poll_mode_drv.rst |  51 ++++-
 doc/guides/rel_notes/release_2_2.rst    |  12 ++
 drivers/net/e1000/igb_ethdev.c          | 194 +++++++++++++++++-
 drivers/net/fm10k/fm10k_ethdev.c        |  87 ++++++++
 drivers/net/i40e/i40e_ethdev.c          | 265 +++++++++++++++++++++++-
 drivers/net/i40e/i40e_ethdev_vf.c       |  89 +++++++-
 drivers/net/ixgbe/ixgbe_ethdev.c        | 346 +++++++++++++++++++++++++++++---
 drivers/net/virtio/virtio_ethdev.c      |  98 ++++++++-
 drivers/net/virtio/virtio_rxtx.c        |  32 +++
 drivers/net/virtio/virtqueue.h          |   4 +
 lib/librte_ether/rte_ethdev.c           |  38 ++--
 11 files changed, 1154 insertions(+), 62 deletions(-)

--
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 00/11] Port XStats
  2015-10-28 17:35     ` [dpdk-dev] [PATCH v3 00/11] Port XStats Tom Crugnale
@ 2015-10-28 21:32       ` Stephen Hemminger
  2015-10-29  0:55         ` Tom Crugnale
  0 siblings, 1 reply; 77+ messages in thread
From: Stephen Hemminger @ 2015-10-28 21:32 UTC (permalink / raw)
  To: Tom Crugnale; +Cc: dev

On Wed, 28 Oct 2015 17:35:09 +0000
Tom Crugnale <tcrugnale@sandvine.com> wrote:

> Hi Harry,
> 
> We are planning on using the xstats API for periodic stats collection through a polling thread.  This would be done in a generic NIC agnostic manner, which would require that the xstats identifiers have consistent naming amongst all of the NIC types.  It would likely be polled several times per second and would only gather a subset of all available xstats types.  
> 
> I have reviewed your patches and am interested in providing some API enhancements and bugfixes.  Are you willing to provide feedback on such changes?
> 
> Thank you,
> Tom

The whole point of xstats is to allow device specific statistics.
Consistent use of names is good from a user interface point of view, but probably
not a hard requirement.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 00/11] Port XStats
  2015-10-28 21:32       ` Stephen Hemminger
@ 2015-10-29  0:55         ` Tom Crugnale
  2015-10-29 12:55           ` Kyle Larose
  0 siblings, 1 reply; 77+ messages in thread
From: Tom Crugnale @ 2015-10-29  0:55 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

I understand.  Is this the reason that that strings were used to identify the xstat types?  An enum type would be much more efficient instead of doing string copies when retrieving the stats, but the number of enum entries would quickly grow out of control as device specific stats were added.

In this case, I'm actually referring to the stats that are common to all NICs.  For example, for the received fragmented packets counter, there are three strings that identify this value: rx_fragment_packets (igb), rx_fragment_errors (ixgbe), rx_fragmented_packets (i40e).
I was thinking of making those names consistent.  Perhaps the reason why they were different in the first place is that each of the device datasheets refers to these exact names.

Tom

-----Original Message-----
From: Stephen Hemminger [mailto:stephen@networkplumber.org] 
Sent: Wednesday, October 28, 2015 5:32 PM
To: Tom Crugnale
Cc: Harry van Haaren; dev@dpdk.org
Subject: Re: [dpdk-dev] [PATCH v3 00/11] Port XStats

On Wed, 28 Oct 2015 17:35:09 +0000
Tom Crugnale <tcrugnale@sandvine.com> wrote:

> Hi Harry,
> 
> We are planning on using the xstats API for periodic stats collection through a polling thread.  This would be done in a generic NIC agnostic manner, which would require that the xstats identifiers have consistent naming amongst all of the NIC types.  It would likely be polled several times per second and would only gather a subset of all available xstats types.  
> 
> I have reviewed your patches and am interested in providing some API enhancements and bugfixes.  Are you willing to provide feedback on such changes?
> 
> Thank you,
> Tom

The whole point of xstats is to allow device specific statistics.
Consistent use of names is good from a user interface point of view, but probably not a hard requirement.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 00/11] Port XStats
  2015-10-29  0:55         ` Tom Crugnale
@ 2015-10-29 12:55           ` Kyle Larose
  2015-10-29 13:10             ` Thomas Monjalon
  2015-10-29 13:17             ` Van Haaren, Harry
  0 siblings, 2 replies; 77+ messages in thread
From: Kyle Larose @ 2015-10-29 12:55 UTC (permalink / raw)
  To: Tom Crugnale, Stephen Hemminger; +Cc: dev

Stephen,

Ultimately the issue we are trying to solve is that there is no device
independent way to get any detailed statistics from NICs controlled by
DPDK. These statistics are quite useful, not just for diagnostics, but
for long term reporting. People using DPDK-based NFV products in a
production environment are not going to be happy that they cannot, for
example, see how the packet size bucket counters varied over time
using some sort of monitoring tool.

The only alternative I can see to providing an API within DPDK is to
build our own abstraction layer triggered off the driver name/pci
ids/etc. I expect other people would end up doing this as well. This
seems like a waste of effort when an abstraction layer already exists
within DPDK.

So, let's consider solving the problem within DPDK. One option is to
use well-defined names for a given xstat that has the same semantics
across NICs, while continuing to allow NICs to expose any stats that
don't fall into this category.

Another option is to provide an API with a well-defined set of stats,
perhaps using an enum. In order for a stat to be added to this list,
it needs to be part of a standard (such as
http://tools.ietf.org/html/rfc2819).

Does anybody else see the need for something like this? We're more
than willing to do the work. We'd like to make sure we have the right
API, though.

Thanks,

Kyle

On Wed, Oct 28, 2015 at 8:55 PM, Tom Crugnale <tcrugnale@sandvine.com> wrote:
> I understand.  Is this the reason that that strings were used to identify the xstat types?  An enum type would be much more efficient instead of doing string copies when retrieving the stats, but the number of enum entries would quickly grow out of control as device specific stats were added.
>
> In this case, I'm actually referring to the stats that are common to all NICs.  For example, for the received fragmented packets counter, there are three strings that identify this value: rx_fragment_packets (igb), rx_fragment_errors (ixgbe), rx_fragmented_packets (i40e).
> I was thinking of making those names consistent.  Perhaps the reason why they were different in the first place is that each of the device datasheets refers to these exact names.
>
> Tom
>
> -----Original Message-----
> From: Stephen Hemminger [mailto:stephen@networkplumber.org]
> Sent: Wednesday, October 28, 2015 5:32 PM
> To: Tom Crugnale
> Cc: Harry van Haaren; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v3 00/11] Port XStats
>
> On Wed, 28 Oct 2015 17:35:09 +0000
> Tom Crugnale <tcrugnale@sandvine.com> wrote:
>
>> Hi Harry,
>>
>> We are planning on using the xstats API for periodic stats collection through a polling thread.  This would be done in a generic NIC agnostic manner, which would require that the xstats identifiers have consistent naming amongst all of the NIC types.  It would likely be polled several times per second and would only gather a subset of all available xstats types.
>>
>> I have reviewed your patches and am interested in providing some API enhancements and bugfixes.  Are you willing to provide feedback on such changes?
>>
>> Thank you,
>> Tom
>
> The whole point of xstats is to allow device specific statistics.
> Consistent use of names is good from a user interface point of view, but probably not a hard requirement.
>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 00/11] Port XStats
  2015-10-29 12:55           ` Kyle Larose
@ 2015-10-29 13:10             ` Thomas Monjalon
  2015-10-29 13:57               ` Kyle Larose
  2015-10-29 13:17             ` Van Haaren, Harry
  1 sibling, 1 reply; 77+ messages in thread
From: Thomas Monjalon @ 2015-10-29 13:10 UTC (permalink / raw)
  To: Kyle Larose; +Cc: dev

2015-10-29 08:55, Kyle Larose:
> Ultimately the issue we are trying to solve is that there is no device
> independent way to get any detailed statistics from NICs controlled by
> DPDK. These statistics are quite useful, not just for diagnostics, but
> for long term reporting. People using DPDK-based NFV products in a
> production environment are not going to be happy that they cannot, for
> example, see how the packet size bucket counters varied over time
> using some sort of monitoring tool.

I don't understand.
The basic statistics are provided in a common API.
The other ones are not available in every NICs and can only be interpreted
while knowing the device. So what is the need exactly?
Do you know an example of a networking layer having this kind of API?

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 00/11] Port XStats
  2015-10-29 12:55           ` Kyle Larose
  2015-10-29 13:10             ` Thomas Monjalon
@ 2015-10-29 13:17             ` Van Haaren, Harry
  1 sibling, 0 replies; 77+ messages in thread
From: Van Haaren, Harry @ 2015-10-29 13:17 UTC (permalink / raw)
  To: Kyle Larose, Tom Crugnale, Stephen Hemminger, Thomas Monjalon; +Cc: dev

Hi All,

(Please keep everyone on To/CC - a few people were dropped)


Note: During my writing a reply to Kyle, Thomas has also replied to Kyle.


> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Kyle Larose
> Sent: Thursday, October 29, 2015 12:55 PM
> To: Tom Crugnale; Stephen Hemminger
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v3 00/11] Port XStats

> Ultimately the issue we are trying to solve is that there is no device
> independent way to get any detailed statistics from NICs controlled by
> DPDK. These statistics are quite useful, not just for diagnostics, but
> for long term reporting. People using DPDK-based NFV products in a
> production environment are not going to be happy that they cannot, for
> example, see how the packet size bucket counters varied over time
> using some sort of monitoring tool.

Agreed, and that's what the xstats solves.


> So, let's consider solving the problem within DPDK. One option is to
> use well-defined names for a given xstat that has the same semantics
> across NICs, while continuing to allow NICs to expose any stats that
> don't fall into this category.

Yes, this is the aim of the current xstats also. As Tom Crugnale pointed
out, the current implementation has some variation in string names, however
the end-goal is to have consistent naming across NICs.

The scheme for naming stats is described in a doc patch, which was part
of my patchset: http://dpdk.org/dev/patchwork/patch/7906/

Ideally a script will automatically checks stats names against those of
other NICs, allowing switching of NICs and stats remaining consistent.

Given that each NIC is unique, this will require some organization work,
but it seems possible with some collaboration.


> Another option is to provide an API with a well-defined set of stats,
> perhaps using an enum. In order for a stat to be added to this list,
> it needs to be part of a standard (such as
> http://tools.ietf.org/html/rfc2819).

I would prefer see xstats gain wider support instead of discussing other
options. 


> Does anybody else see the need for something like this?
Yes.


Cheers, -Harry

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 00/11] Port XStats
  2015-10-29 13:10             ` Thomas Monjalon
@ 2015-10-29 13:57               ` Kyle Larose
  2015-10-29 14:01                 ` Thomas Monjalon
  0 siblings, 1 reply; 77+ messages in thread
From: Kyle Larose @ 2015-10-29 13:57 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

On Thu, Oct 29, 2015 at 9:10 AM, Thomas Monjalon
<thomas.monjalon@6wind.com> wrote:

> I don't understand.
> The basic statistics are provided in a common API.
> The other ones are not available in every NICs and can only be interpreted
> while knowing the device. So what is the need exactly?

The need is to provide information to users about what sort of traffic
is being seen by the device, and why the hardware is behaving the way
it is, leveraging as much as possible the capabilities of the hardware
with minimal effort (i.e. not implementing an abstraction layer at a
higher level).

These are quite useful for diagnosing wider network issues
(configuration, misbehaving devices, dirty fibers/etc). The common API
doesn't expose the more detailed information requested by the various
ethernet mibs. Of course, not all stats are applicable to all devices
(e.g. collisions), but those that are available are still invaluable.

> Do you know an example of a networking layer having this kind of API?

I have worked with SDKs for a few different physical switches and
NPUs. They all provide this sort of API. I think it is quite common
with networking equipment such as routers or switches. These stats
tend to be exposed over SNMP at the very least, and often within local
utilities on the devices themselves.

Thanks,

Kyle

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 00/11] Port XStats
  2015-10-29 13:57               ` Kyle Larose
@ 2015-10-29 14:01                 ` Thomas Monjalon
  2015-10-29 14:10                   ` Kyle Larose
  0 siblings, 1 reply; 77+ messages in thread
From: Thomas Monjalon @ 2015-10-29 14:01 UTC (permalink / raw)
  To: Kyle Larose; +Cc: dev

2015-10-29 09:57, Kyle Larose:
> On Thu, Oct 29, 2015 at 9:10 AM, Thomas Monjalon
> <thomas.monjalon@6wind.com> wrote:
> 
> > I don't understand.
> > The basic statistics are provided in a common API.
> > The other ones are not available in every NICs and can only be interpreted
> > while knowing the device. So what is the need exactly?
> 
> The need is to provide information to users about what sort of traffic
> is being seen by the device, and why the hardware is behaving the way
> it is, leveraging as much as possible the capabilities of the hardware
> with minimal effort (i.e. not implementing an abstraction layer at a
> higher level).
> 
> These are quite useful for diagnosing wider network issues
> (configuration, misbehaving devices, dirty fibers/etc). The common API
> doesn't expose the more detailed information requested by the various
> ethernet mibs. Of course, not all stats are applicable to all devices
> (e.g. collisions), but those that are available are still invaluable.

Thanks for the explanation.

> > Do you know an example of a networking layer having this kind of API?
> 
> I have worked with SDKs for a few different physical switches and
> NPUs. They all provide this sort of API. I think it is quite common
> with networking equipment such as routers or switches. These stats
> tend to be exposed over SNMP at the very least, and often within local
> utilities on the devices themselves.

So what is missing currently? Just having a consistent naming of
similar counters?

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 00/11] Port XStats
  2015-10-29 14:01                 ` Thomas Monjalon
@ 2015-10-29 14:10                   ` Kyle Larose
  0 siblings, 0 replies; 77+ messages in thread
From: Kyle Larose @ 2015-10-29 14:10 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

On Thu, Oct 29, 2015 at 10:01 AM, Thomas Monjalon
<thomas.monjalon@6wind.com> wrote:

> So what is missing currently? Just having a consistent naming of
> similar counters?

A consistent naming scheme would certainly solve the problem.

Thanks again,

Kyle

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 04/11] virtio: add xstats() implementation
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 04/11] virtio: add xstats() implementation Harry van Haaren
@ 2015-10-29 16:19       ` Tahhan, Maryam
  0 siblings, 0 replies; 77+ messages in thread
From: Tahhan, Maryam @ 2015-10-29 16:19 UTC (permalink / raw)
  To: Van Haaren, Harry, dev

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Harry van Haaren
> Sent: Thursday, October 22, 2015 4:48 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v3 04/11] virtio: add xstats() implementation
> 
> Add xstats() functions and statistic strings to virtio PMD.
> 
> Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
> ---

Acked-by: Maryam Tahhan <maryam.tahhan@intel.com>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v3 11/11] fm10k: add xstats() implementation
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 11/11] fm10k: " Harry van Haaren
@ 2015-10-29 16:41       ` Tahhan, Maryam
  0 siblings, 0 replies; 77+ messages in thread
From: Tahhan, Maryam @ 2015-10-29 16:41 UTC (permalink / raw)
  To: Van Haaren, Harry, dev

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Harry van Haaren
> Sent: Thursday, October 22, 2015 4:49 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v3 11/11] fm10k: add xstats() implementation
> 
> Add xstats() functions and statistic strings.
> 
> Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
> ---

Acked-by: Maryam Tahhan <maryam.tahhan@intel.com>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v4 00/10] Port XStats
  2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 01/11] doc: add extended statistics notes Harry van Haaren
@ 2015-10-30 11:36       ` Harry van Haaren
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 01/10] doc: add extended statistics to prog_guide Harry van Haaren
                           ` (11 more replies)
  0 siblings, 12 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-10-30 11:36 UTC (permalink / raw)
  To: dev

This patchset adds an implementation of the xstats_get() and xstats_reset() API
to the following PMDs: virtio, igb, igbvf, ixgbe, ixgbevf, i40e, i40evf and
fm10k.

The xstats API allows DPDK apps to gain access to extended statistics from each
port on a NIC. These statistics are structured as per a scheme detailed in the
patch for the doc/prog_guide.

v4: Consistency of names, refactored Q stat code
v3: Added more stats to PMDs
v2: Send correct patchset

Harry van Haaren (10):
  doc: add extended statistics to prog_guide
  ethdev: update xstats_get() strings and Q handling
  virtio: add xstats() implementation
  igb: add xstats() implementation
  igbvf: add xstats() implementation
  ixgbe: add extended statistic strings
  ixgbevf: add xstats() implementation
  i40e: add xstats() implementation
  i40evf: add xstats() implementation
  fm10k: add xstats() implementation

 doc/guides/prog_guide/poll_mode_drv.rst |  51 ++++++-
 doc/guides/rel_notes/release_2_2.rst    |  14 ++
 drivers/net/e1000/igb_ethdev.c          | 193 ++++++++++++++++++++++--
 drivers/net/fm10k/fm10k_ethdev.c        |  87 +++++++++++
 drivers/net/i40e/i40e_ethdev.c          | 217 ++++++++++++++++++++++++++-
 drivers/net/i40e/i40e_ethdev_vf.c       |  89 ++++++++++-
 drivers/net/ixgbe/ixgbe_ethdev.c        | 254 +++++++++++++++++++++++++++-----
 drivers/net/virtio/virtio_ethdev.c      |  98 +++++++++++-
 drivers/net/virtio/virtio_rxtx.c        |  32 ++++
 drivers/net/virtio/virtqueue.h          |   4 +
 lib/librte_ether/rte_ethdev.c           |  38 +++--
 11 files changed, 1006 insertions(+), 71 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v4 01/10] doc: add extended statistics to prog_guide
  2015-10-30 11:36       ` [dpdk-dev] [PATCH v4 00/10] Port XStats Harry van Haaren
@ 2015-10-30 11:36         ` Harry van Haaren
  2015-11-02 10:18           ` [dpdk-dev] [PATCH v5 00/10] Port XStats Harry van Haaren
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 02/10] ethdev: update xstats_get() strings and Q handling Harry van Haaren
                           ` (10 subsequent siblings)
  11 siblings, 1 reply; 77+ messages in thread
From: Harry van Haaren @ 2015-10-30 11:36 UTC (permalink / raw)
  To: dev

Add extended statistic section to the programmers
guide, poll mode driver section. This section describes
how the strings stats are formatted, and how the client
code can use this to gather information about the stat.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 doc/guides/prog_guide/poll_mode_drv.rst | 51 ++++++++++++++++++++++++++++++++-
 doc/guides/rel_notes/release_2_2.rst    | 14 +++++++++
 2 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/doc/guides/prog_guide/poll_mode_drv.rst b/doc/guides/prog_guide/poll_mode_drv.rst
index 8780ba3..44cc9ce 100644
--- a/doc/guides/prog_guide/poll_mode_drv.rst
+++ b/doc/guides/prog_guide/poll_mode_drv.rst
@@ -1,5 +1,5 @@
 ..  BSD LICENSE
-    Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+    Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
     All rights reserved.
 
     Redistribution and use in source and binary forms, with or without
@@ -294,3 +294,52 @@ Ethernet Device API
 ~~~~~~~~~~~~~~~~~~~
 
 The Ethernet device API exported by the Ethernet PMDs is described in the *DPDK API Reference*.
+
+Extended Statistics API
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The extended statistics API allows each individual PMD to expose a unique set
+of statistics. The client of the API provides an array of
+``struct rte_eth_xstats`` type. Each ``struct rte_eth_xstats`` contains a
+string and value pair. The amount of xstats exposed, and position of the
+statistic in the array must remain constant during runtime.
+
+A naming scheme exists for the strings exposed to clients of the API. This is
+to allow scraping of the API for statistics of interest. The naming scheme uses
+strings split by a single underscore ``_``. The scheme is as follows:
+
+* direction
+* detail 1
+* detail 2
+* detail n
+* unit
+
+Examples of common statistics xstats strings, formatted to comply to the scheme
+proposed above:
+
+* ``rx_bytes``
+* ``rx_crc_errors``
+* ``tx_multicast_packets``
+
+The scheme, although quite simple, allows flexibility in presenting and reading
+information from the statistic strings. The following example illustrates the
+naming scheme:``rx_packets``. In this example, the string is split into two
+components. The first component ``rx`` indicates that the statistic is
+associated with the receive side of the NIC.  The second component ``packets``
+indicates that the unit of measure is packets.
+
+A more complicated example: ``tx_size_128_to_255_packets``. In this example,
+``tx`` indicates transmission, ``size``  is the first detail, ``128`` etc are
+more details, and ``packets`` indicates that this is a packet counter.
+
+Some additions in the metadata scheme are as follows:
+
+* If the first part does not match ``rx`` or ``tx``, the statistic does not
+  have an affinity with either recieve of transmit.
+
+* If the first letter of the second part is ``q`` and this ``q`` is followed
+  by a number, this statistic is part of a specific queue.
+
+An example where queue numbers are used is as follows: ``tx_q7_bytes`` which
+indicates this statistic applies to queue number 7, and represents the number
+of transmitted bytes on that queue.
diff --git a/doc/guides/rel_notes/release_2_2.rst b/doc/guides/rel_notes/release_2_2.rst
index 89e4d58..8e29ec3 100644
--- a/doc/guides/rel_notes/release_2_2.rst
+++ b/doc/guides/rel_notes/release_2_2.rst
@@ -31,6 +31,20 @@ New Features
 
 * **Added vhost-user multiple queue support.**
 
+* **Extended Statistics**
+
+  Define extended statistics naming scheme to store metadata in the name
+  string name of each statistic, refer to the Extended Statistics section
+  of the programmers guide. Implemented the extended stats API for these
+  PMDs:
+
+  * igb
+  * igbvf
+  * i40e
+  * i40evf
+  * fm10k
+  * virtio
+
 Resolved Issues
 ---------------
 
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v4 02/10] ethdev: update xstats_get() strings and Q handling
  2015-10-30 11:36       ` [dpdk-dev] [PATCH v4 00/10] Port XStats Harry van Haaren
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 01/10] doc: add extended statistics to prog_guide Harry van Haaren
@ 2015-10-30 11:36         ` Harry van Haaren
  2015-11-02  7:59           ` Thomas Monjalon
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 03/10] virtio: add xstats() implementation Harry van Haaren
                           ` (9 subsequent siblings)
  11 siblings, 1 reply; 77+ messages in thread
From: Harry van Haaren @ 2015-10-30 11:36 UTC (permalink / raw)
  To: dev

Update the strings used for presenting stats to adhere
to the scheme previously presented. Updated xstats_get()
function to handle Q information only if xstats() is not
implemented in the PMD, providing the PMD with the needed
flexibility to expose its extended Q stats.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 lib/librte_ether/rte_ethdev.c | 38 +++++++++++++++++++++++---------------
 1 file changed, 23 insertions(+), 15 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index f593f6e..07f0c26 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -137,27 +137,30 @@ struct rte_eth_xstats_name_off {
 };
 
 static const struct rte_eth_xstats_name_off rte_stats_strings[] = {
-	{"rx_packets", offsetof(struct rte_eth_stats, ipackets)},
-	{"tx_packets", offsetof(struct rte_eth_stats, opackets)},
-	{"rx_bytes", offsetof(struct rte_eth_stats, ibytes)},
-	{"tx_bytes", offsetof(struct rte_eth_stats, obytes)},
-	{"tx_errors", offsetof(struct rte_eth_stats, oerrors)},
+	{"rx_good_packets", offsetof(struct rte_eth_stats, ipackets)},
+	{"tx_good_packets", offsetof(struct rte_eth_stats, opackets)},
+	{"rx_good_bytes", offsetof(struct rte_eth_stats, ibytes)},
+	{"tx_good_bytes", offsetof(struct rte_eth_stats, obytes)},
 	{"rx_errors", offsetof(struct rte_eth_stats, ierrors)},
-	{"alloc_rx_buff_failed", offsetof(struct rte_eth_stats, rx_nombuf)},
+	{"tx_errors", offsetof(struct rte_eth_stats, oerrors)},
+	{"rx_mbuf_allocation_errors", offsetof(struct rte_eth_stats,
+		rx_nombuf)},
 };
+
 #define RTE_NB_STATS (sizeof(rte_stats_strings) / sizeof(rte_stats_strings[0]))
 
 static const struct rte_eth_xstats_name_off rte_rxq_stats_strings[] = {
-	{"rx_packets", offsetof(struct rte_eth_stats, q_ipackets)},
-	{"rx_bytes", offsetof(struct rte_eth_stats, q_ibytes)},
+	{"packets", offsetof(struct rte_eth_stats, q_ipackets)},
+	{"bytes", offsetof(struct rte_eth_stats, q_ibytes)},
+	{"errors", offsetof(struct rte_eth_stats, q_errors)},
 };
+
 #define RTE_NB_RXQ_STATS (sizeof(rte_rxq_stats_strings) /	\
 		sizeof(rte_rxq_stats_strings[0]))
 
 static const struct rte_eth_xstats_name_off rte_txq_stats_strings[] = {
-	{"tx_packets", offsetof(struct rte_eth_stats, q_opackets)},
-	{"tx_bytes", offsetof(struct rte_eth_stats, q_obytes)},
-	{"tx_errors", offsetof(struct rte_eth_stats, q_errors)},
+	{"packets", offsetof(struct rte_eth_stats, q_opackets)},
+	{"bytes", offsetof(struct rte_eth_stats, q_obytes)},
 };
 #define RTE_NB_TXQ_STATS (sizeof(rte_txq_stats_strings) /	\
 		sizeof(rte_txq_stats_strings[0]))
@@ -1666,8 +1669,6 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 
 	/* Return generic statistics */
 	count = RTE_NB_STATS;
-	count += dev->data->nb_rx_queues * RTE_NB_RXQ_STATS;
-	count += dev->data->nb_tx_queues * RTE_NB_TXQ_STATS;
 
 	/* implemented by the driver */
 	if (dev->dev_ops->xstats_get != NULL) {
@@ -1679,6 +1680,9 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 
 		if (xcount < 0)
 			return xcount;
+	} else {
+		count += dev->data->nb_rx_queues * RTE_NB_RXQ_STATS;
+		count += dev->data->nb_tx_queues * RTE_NB_TXQ_STATS;
 	}
 
 	if (n < count + xcount)
@@ -1698,6 +1702,10 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 		xstats[count++].value = val;
 	}
 
+	/* if xstats_get() is implemented by the PMD, the Q stats are done */
+	if (dev->dev_ops->xstats_get != NULL)
+		return count + xcount;
+
 	/* per-rxq stats */
 	for (q = 0; q < dev->data->nb_rx_queues; q++) {
 		for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
@@ -1706,7 +1714,7 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 					q * sizeof(uint64_t));
 			val = *stats_ptr;
 			snprintf(xstats[count].name, sizeof(xstats[count].name),
-				"rx_queue_%u_%s", q,
+				"rx_q%u_%s", q,
 				rte_rxq_stats_strings[i].name);
 			xstats[count++].value = val;
 		}
@@ -1720,7 +1728,7 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 					q * sizeof(uint64_t));
 			val = *stats_ptr;
 			snprintf(xstats[count].name, sizeof(xstats[count].name),
-				"tx_queue_%u_%s", q,
+				"tx_q%u_%s", q,
 				rte_txq_stats_strings[i].name);
 			xstats[count++].value = val;
 		}
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v4 03/10] virtio: add xstats() implementation
  2015-10-30 11:36       ` [dpdk-dev] [PATCH v4 00/10] Port XStats Harry van Haaren
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 01/10] doc: add extended statistics to prog_guide Harry van Haaren
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 02/10] ethdev: update xstats_get() strings and Q handling Harry van Haaren
@ 2015-10-30 11:36         ` Harry van Haaren
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 04/10] igb: " Harry van Haaren
                           ` (8 subsequent siblings)
  11 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-10-30 11:36 UTC (permalink / raw)
  To: dev

Add xstats() functions and statistic strings to virtio PMD.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 98 +++++++++++++++++++++++++++++++++++++-
 drivers/net/virtio/virtio_rxtx.c   | 32 +++++++++++++
 drivers/net/virtio/virtqueue.h     |  4 ++
 3 files changed, 132 insertions(+), 2 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 12fcc23..4cf7a79 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -80,7 +80,10 @@ static int virtio_dev_link_update(struct rte_eth_dev *dev,
 static void virtio_set_hwaddr(struct virtio_hw *hw);
 static void virtio_get_hwaddr(struct virtio_hw *hw);
 
-static void virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats);
+static void virtio_dev_stats_get(struct rte_eth_dev *dev,
+				 struct rte_eth_stats *stats);
+static int virtio_dev_xstats_get(struct rte_eth_dev *dev,
+				 struct rte_eth_xstats *xstats, unsigned n);
 static void virtio_dev_stats_reset(struct rte_eth_dev *dev);
 static void virtio_dev_free_mbufs(struct rte_eth_dev *dev);
 static int virtio_vlan_filter_set(struct rte_eth_dev *dev,
@@ -109,6 +112,31 @@ static const struct rte_pci_id pci_id_virtio_map[] = {
 { .vendor_id = 0, /* sentinel */ },
 };
 
+struct rte_virtio_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	unsigned offset;
+};
+
+/* [rt]x_qX_ is prepended to the name string here */
+static const struct rte_virtio_xstats_name_off rte_virtio_q_stat_strings[] = {
+	{"good_packets",           offsetof(struct virtqueue, packets)},
+	{"good_bytes",             offsetof(struct virtqueue, bytes)},
+	{"errors",                 offsetof(struct virtqueue, errors)},
+	{"multicast_packets",      offsetof(struct virtqueue, multicast)},
+	{"broadcast_packets",      offsetof(struct virtqueue, broadcast)},
+	{"undersize_packets",      offsetof(struct virtqueue, size_bins[0])},
+	{"size_64_packets",        offsetof(struct virtqueue, size_bins[1])},
+	{"size_65_127_packets",    offsetof(struct virtqueue, size_bins[2])},
+	{"size_128_255_packets",   offsetof(struct virtqueue, size_bins[3])},
+	{"size_256_511_packets",   offsetof(struct virtqueue, size_bins[4])},
+	{"size_512_1023_packets",  offsetof(struct virtqueue, size_bins[5])},
+	{"size_1024_1517_packets", offsetof(struct virtqueue, size_bins[6])},
+	{"size_1518_max_packets",  offsetof(struct virtqueue, size_bins[7])},
+};
+
+#define VIRTIO_NB_Q_XSTATS (sizeof(rte_virtio_q_stat_strings) / \
+			    sizeof(rte_virtio_q_stat_strings[0]))
+
 static int
 virtio_send_command(struct virtqueue *vq, struct virtio_pmd_ctrl *ctrl,
 		int *dlen, int pkt_num)
@@ -568,7 +596,9 @@ static const struct eth_dev_ops virtio_eth_dev_ops = {
 
 	.dev_infos_get           = virtio_dev_info_get,
 	.stats_get               = virtio_dev_stats_get,
+	.xstats_get              = virtio_dev_xstats_get,
 	.stats_reset             = virtio_dev_stats_reset,
+	.xstats_reset            = virtio_dev_stats_reset,
 	.link_update             = virtio_dev_link_update,
 	.rx_queue_setup          = virtio_dev_rx_queue_setup,
 	.rx_queue_release        = virtio_dev_rx_queue_release,
@@ -623,7 +653,7 @@ virtio_dev_atomic_write_link_status(struct rte_eth_dev *dev,
 }
 
 static void
-virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+virtio_update_stats(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 {
 	unsigned i;
 
@@ -660,6 +690,64 @@ virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed;
 }
 
+static int
+virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		      unsigned n)
+{
+	unsigned i;
+	unsigned count = 0;
+
+	unsigned nstats = dev->data->nb_tx_queues * VIRTIO_NB_Q_XSTATS +
+		dev->data->nb_rx_queues * VIRTIO_NB_Q_XSTATS;
+
+	if(n < nstats)
+		return nstats;
+
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		struct virtqueue *rxvq = dev->data->rx_queues[i];
+
+		if(rxvq == NULL)
+			continue;
+
+		unsigned t;
+
+		for(t = 0; t < VIRTIO_NB_Q_XSTATS; t++) {
+			snprintf(xstats[count].name, sizeof(xstats[count].name),
+				 "rx_q%u_%s", i,
+				 rte_virtio_q_stat_strings[t].name);
+			xstats[count].value = *(uint64_t *)(((char *)rxvq) +
+				rte_virtio_q_stat_strings[t].offset);
+			count++;
+		}
+	}
+
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
+		struct virtqueue *txvq = dev->data->tx_queues[i];
+
+		if(txvq == NULL)
+			continue;
+
+		unsigned t;
+
+		for(t = 0; t < VIRTIO_NB_Q_XSTATS; t++) {
+			snprintf(xstats[count].name, sizeof(xstats[count].name),
+				 "tx_q%u_%s", i,
+				 rte_virtio_q_stat_strings[t].name);
+			xstats[count].value = *(uint64_t *)(((char *)txvq) +
+				rte_virtio_q_stat_strings[t].offset);
+			count++;
+		}
+	}
+
+	return count;
+}
+
+static void
+virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+	virtio_update_stats(dev, stats);
+}
+
 static void
 virtio_dev_stats_reset(struct rte_eth_dev *dev)
 {
@@ -673,6 +761,9 @@ virtio_dev_stats_reset(struct rte_eth_dev *dev)
 		txvq->packets = 0;
 		txvq->bytes = 0;
 		txvq->errors = 0;
+		txvq->multicast = 0;
+		txvq->broadcast = 0;
+		memset(txvq->size_bins, 0, sizeof(txvq->size_bins[0]) * 8);
 	}
 
 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
@@ -683,6 +774,9 @@ virtio_dev_stats_reset(struct rte_eth_dev *dev)
 		rxvq->packets = 0;
 		rxvq->bytes = 0;
 		rxvq->errors = 0;
+		rxvq->multicast = 0;
+		rxvq->broadcast = 0;
+		memset(rxvq->size_bins, 0, sizeof(rxvq->size_bins[0]) * 8);
 	}
 
 	dev->data->rx_mbuf_alloc_failed = 0;
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index d35c5f9..a615916 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -482,6 +482,34 @@ virtio_discard_rxbuf(struct virtqueue *vq, struct rte_mbuf *m)
 	}
 }
 
+static void
+virtio_update_packet_stats(struct virtqueue *vq, struct rte_mbuf *mbuf)
+{
+	uint32_t s = mbuf->pkt_len;
+	struct ether_addr *ea;
+
+	if(s == 64) {
+		vq->size_bins[1]++;
+	} else if(s > 64 && s < 1024) {
+		uint32_t bin;
+
+		/* count zeros, and offset into correct bin */
+		bin = (sizeof(s) * 8) - __builtin_clz(s) - 5;
+		vq->size_bins[bin]++;
+	} else {
+		if(s < 64)
+			vq->size_bins[0]++;
+		else if(s < 1519)
+			vq->size_bins[6]++;
+		else if(s >= 1519)
+			vq->size_bins[7]++;
+	}
+
+	ea = rte_pktmbuf_mtod(mbuf, struct ether_addr *);
+	vq->multicast += is_multicast_ether_addr(ea);
+	vq->broadcast += is_broadcast_ether_addr(ea);
+}
+
 #define VIRTIO_MBUF_BURST_SZ 64
 #define DESC_PER_CACHELINE (RTE_CACHE_LINE_SIZE / sizeof(struct vring_desc))
 uint16_t
@@ -543,7 +571,9 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 		VIRTIO_DUMP_PACKET(rxm, rxm->data_len);
 
 		rx_pkts[nb_rx++] = rxm;
+
 		rxvq->bytes += rx_pkts[nb_rx - 1]->pkt_len;
+		virtio_update_packet_stats(rxvq, rxm);
 	}
 
 	rxvq->packets += nb_rx;
@@ -706,6 +736,7 @@ virtio_recv_mergeable_pkts(void *rx_queue,
 			rx_pkts[nb_rx]->data_len);
 
 		rxvq->bytes += rx_pkts[nb_rx]->pkt_len;
+		virtio_update_packet_stats(rxvq, rx_pkts[nb_rx]);
 		nb_rx++;
 	}
 
@@ -806,6 +837,7 @@ virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 			}
 			nb_tx++;
 			txvq->bytes += txm->pkt_len;
+			virtio_update_packet_stats(txvq, txm);
 		} else {
 			PMD_TX_LOG(ERR, "No free tx descriptors to transmit");
 			break;
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 7789411..9032e6d 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -194,6 +194,10 @@ struct virtqueue {
 	uint64_t	packets;
 	uint64_t	bytes;
 	uint64_t	errors;
+	uint64_t	multicast;
+	uint64_t	broadcast;
+	/* Size bins in array as RFC 2819, undersized [0], 64 [1], etc */
+	uint64_t	size_bins[8];
 
 	struct vq_desc_extra {
 		void              *cookie;
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v4 04/10] igb: add xstats() implementation
  2015-10-30 11:36       ` [dpdk-dev] [PATCH v4 00/10] Port XStats Harry van Haaren
                           ` (2 preceding siblings ...)
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 03/10] virtio: add xstats() implementation Harry van Haaren
@ 2015-10-30 11:36         ` Harry van Haaren
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 05/10] igbvf: " Harry van Haaren
                           ` (7 subsequent siblings)
  11 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-10-30 11:36 UTC (permalink / raw)
  To: dev

Add xstats_get() and xstats_reset() functions to igb
driver, and the neccessary strings to expose these
NIC statistics.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/e1000/igb_ethdev.c | 135 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 130 insertions(+), 5 deletions(-)

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 3ab082e..7f2162d 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -96,7 +96,10 @@ static int  eth_igb_link_update(struct rte_eth_dev *dev,
 				int wait_to_complete);
 static void eth_igb_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *rte_stats);
+static int eth_igb_xstats_get(struct rte_eth_dev *dev,
+			      struct rte_eth_xstats *xstats, unsigned n);
 static void eth_igb_stats_reset(struct rte_eth_dev *dev);
+static void eth_igb_xstats_reset(struct rte_eth_dev *dev);
 static void eth_igb_infos_get(struct rte_eth_dev *dev,
 			      struct rte_eth_dev_info *dev_info);
 static void eth_igbvf_infos_get(struct rte_eth_dev *dev,
@@ -291,7 +294,9 @@ static const struct eth_dev_ops eth_igb_ops = {
 	.allmulticast_disable = eth_igb_allmulticast_disable,
 	.link_update          = eth_igb_link_update,
 	.stats_get            = eth_igb_stats_get,
+	.xstats_get           = eth_igb_xstats_get,
 	.stats_reset          = eth_igb_stats_reset,
+	.xstats_reset         = eth_igb_xstats_reset,
 	.dev_infos_get        = eth_igb_infos_get,
 	.mtu_set              = eth_igb_mtu_set,
 	.vlan_filter_set      = eth_igb_vlan_filter_set,
@@ -353,6 +358,76 @@ static const struct eth_dev_ops igbvf_eth_dev_ops = {
 	.get_reg              = igbvf_get_regs,
 };
 
+/* store statistics names and its offset in stats structure */
+struct rte_igb_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	unsigned offset;
+};
+
+static const struct rte_igb_xstats_name_off rte_igb_stats_strings[] = {
+	{"rx_crc_errors", offsetof(struct e1000_hw_stats, crcerrs)},
+	{"rx_align_errors", offsetof(struct e1000_hw_stats, algnerrc)},
+	{"rx_symbol_errors", offsetof(struct e1000_hw_stats, symerrs)},
+	{"rx_missed_packets", offsetof(struct e1000_hw_stats, mpc)},
+	{"tx_single_collision_packets", offsetof(struct e1000_hw_stats, scc)},
+	{"tx_multiple_collision_packets", offsetof(struct e1000_hw_stats, mcc)},
+	{"tx_excessive_collision_packets", offsetof(struct e1000_hw_stats,
+		ecol)},
+	{"tx_late_collisions", offsetof(struct e1000_hw_stats, latecol)},
+	{"tx_total_collisions", offsetof(struct e1000_hw_stats, colc)},
+	{"tx_deferred_packets", offsetof(struct e1000_hw_stats, dc)},
+	{"tx_no_carrier_sense_packets", offsetof(struct e1000_hw_stats, tncrs)},
+	{"rx_carrier_ext_errors", offsetof(struct e1000_hw_stats, cexterr)},
+	{"rx_length_errors", offsetof(struct e1000_hw_stats, rlec)},
+	{"rx_xon_packets", offsetof(struct e1000_hw_stats, xonrxc)},
+	{"tx_xon_packets", offsetof(struct e1000_hw_stats, xontxc)},
+	{"rx_xoff_packets", offsetof(struct e1000_hw_stats, xoffrxc)},
+	{"tx_xoff_packets", offsetof(struct e1000_hw_stats, xofftxc)},
+	{"rx_flow_control_unsupported_packets", offsetof(struct e1000_hw_stats,
+		fcruc)},
+	{"rx_size_64_packets", offsetof(struct e1000_hw_stats, prc64)},
+	{"rx_size_65_to_127_packets", offsetof(struct e1000_hw_stats, prc127)},
+	{"rx_size_128_to_255_packets", offsetof(struct e1000_hw_stats, prc255)},
+	{"rx_size_256_to_511_packets", offsetof(struct e1000_hw_stats, prc511)},
+	{"rx_size_512_to_1023_packets", offsetof(struct e1000_hw_stats,
+		prc1023)},
+	{"rx_size_1024_to_max_packets", offsetof(struct e1000_hw_stats,
+		prc1522)},
+	{"rx_broadcast_packets", offsetof(struct e1000_hw_stats, bprc)},
+	{"rx_multicast_packets", offsetof(struct e1000_hw_stats, mprc)},
+	{"rx_undersize_errors", offsetof(struct e1000_hw_stats, ruc)},
+	{"rx_fragment_errors", offsetof(struct e1000_hw_stats, rfc)},
+	{"rx_oversize_errors", offsetof(struct e1000_hw_stats, roc)},
+	{"rx_jabber_errors", offsetof(struct e1000_hw_stats, rjc)},
+	{"rx_management_packets", offsetof(struct e1000_hw_stats, mgprc)},
+	{"rx_management_dropped", offsetof(struct e1000_hw_stats, mgpdc)},
+	{"tx_management_packets", offsetof(struct e1000_hw_stats, mgptc)},
+	{"rx_total_packets", offsetof(struct e1000_hw_stats, tpr)},
+	{"tx_total_packets", offsetof(struct e1000_hw_stats, tpt)},
+	{"rx_total_bytes", offsetof(struct e1000_hw_stats, tor)},
+	{"tx_total_bytes", offsetof(struct e1000_hw_stats, tot)},
+	{"tx_size_64_packets", offsetof(struct e1000_hw_stats, ptc64)},
+	{"tx_size_65_to_127_packets", offsetof(struct e1000_hw_stats, ptc127)},
+	{"tx_size_128_to_255_packets", offsetof(struct e1000_hw_stats, ptc255)},
+	{"tx_size_256_to_511_packets", offsetof(struct e1000_hw_stats, ptc511)},
+	{"tx_size_512_to_1023_packets", offsetof(struct e1000_hw_stats,
+		ptc1023)},
+	{"tx_size_1023_to_max_packets", offsetof(struct e1000_hw_stats,
+		ptc1522)},
+	{"tx_multicast_packets", offsetof(struct e1000_hw_stats, mptc)},
+	{"tx_broadcast_packets", offsetof(struct e1000_hw_stats, bptc)},
+	{"tx_tso_packets", offsetof(struct e1000_hw_stats, tsctc)},
+	{"tx_tso_errors", offsetof(struct e1000_hw_stats, tsctfc)},
+	{"rx_sent_to_host_packets", offsetof(struct e1000_hw_stats, rpthc)},
+	{"tx_sent_by_host_packets", offsetof(struct e1000_hw_stats, hgptc)},
+	{"rx_code_violation_packets", offsetof(struct e1000_hw_stats, scvpc)},
+
+	{"interrupt_assert_count", offsetof(struct e1000_hw_stats, iac)},
+};
+
+#define IGB_NB_XSTATS (sizeof(rte_igb_stats_strings) / \
+		sizeof(rte_igb_stats_strings[0]))
+
 /**
  * Atomically reads the link status information from global
  * structure rte_eth_dev.
@@ -1256,11 +1331,8 @@ igb_hardware_init(struct e1000_hw *hw)
 
 /* This function is based on igb_update_stats_counters() in igb/if_igb.c */
 static void
-eth_igb_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
+igb_read_stats_registers(struct e1000_hw *hw, struct e1000_hw_stats *stats)
 {
-	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	struct e1000_hw_stats *stats =
-			E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
 	int pause_frames;
 
 	if(hw->phy.media_type == e1000_media_type_copper ||
@@ -1366,6 +1438,16 @@ eth_igb_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
 	stats->cexterr += E1000_READ_REG(hw, E1000_CEXTERR);
 	stats->tsctc += E1000_READ_REG(hw, E1000_TSCTC);
 	stats->tsctfc += E1000_READ_REG(hw, E1000_TSCTFC);
+}
+
+static void
+eth_igb_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_hw_stats *stats =
+			E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+
+	igb_read_stats_registers(hw, stats);
 
 	if (rte_stats == NULL)
 		return;
@@ -1408,6 +1490,50 @@ eth_igb_stats_reset(struct rte_eth_dev *dev)
 }
 
 static void
+eth_igb_xstats_reset(struct rte_eth_dev *dev)
+{
+	struct e1000_hw_stats *stats =
+			E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+
+	/* HW registers are cleared on read */
+	eth_igb_xstats_get(dev, NULL, IGB_NB_XSTATS);
+
+	/* Reset software totals */
+	memset(stats, 0, sizeof(*stats));
+}
+
+static int
+eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		   unsigned n)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_hw_stats *hw_stats =
+			E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+	unsigned i;
+
+	if(n < IGB_NB_XSTATS)
+		return IGB_NB_XSTATS;
+
+	igb_read_stats_registers(hw, hw_stats);
+
+	/* If this is a reset xstats is NULL, and we have cleared the
+	 * registers by reading them.
+	 */
+	if (!xstats)
+		return 0;
+
+	/* Extended stats */
+	for (i = 0; i < IGB_NB_XSTATS; i++) {
+		snprintf(xstats[i].name, sizeof(xstats[i].name),
+			 "%s", rte_igb_stats_strings[i].name);
+		xstats[i].value = *(uint64_t *)(((char *)hw_stats) +
+			rte_igb_stats_strings[i].offset);
+	}
+
+	return IGB_NB_XSTATS;
+}
+
+static void
 eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -1462,7 +1588,6 @@ eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
 	rte_stats->ilbbytes = hw_stats->gorlbc;
 	rte_stats->olbpackets = hw_stats->gptlbc;
 	rte_stats->olbbytes = hw_stats->gotlbc;
-
 }
 
 static void
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v4 05/10] igbvf: add xstats() implementation
  2015-10-30 11:36       ` [dpdk-dev] [PATCH v4 00/10] Port XStats Harry van Haaren
                           ` (3 preceding siblings ...)
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 04/10] igb: " Harry van Haaren
@ 2015-10-30 11:36         ` Harry van Haaren
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 06/10] ixgbe: add extended statistic strings Harry van Haaren
                           ` (6 subsequent siblings)
  11 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-10-30 11:36 UTC (permalink / raw)
  To: dev

Add xstats functionality to igbvf PMD, adding
necessary statistic strings.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/e1000/igb_ethdev.c | 62 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 55 insertions(+), 7 deletions(-)

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 7f2162d..29d8ece 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -152,7 +152,10 @@ static int igbvf_dev_start(struct rte_eth_dev *dev);
 static void igbvf_dev_stop(struct rte_eth_dev *dev);
 static void igbvf_dev_close(struct rte_eth_dev *dev);
 static int eth_igbvf_link_update(struct e1000_hw *hw);
-static void eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats);
+static void eth_igbvf_stats_get(struct rte_eth_dev *dev,
+				struct rte_eth_stats *rte_stats);
+static int eth_igbvf_xstats_get(struct rte_eth_dev *dev,
+				struct rte_eth_xstats *xstats, unsigned n);
 static void eth_igbvf_stats_reset(struct rte_eth_dev *dev);
 static int igbvf_vlan_filter_set(struct rte_eth_dev *dev,
 		uint16_t vlan_id, int on);
@@ -345,7 +348,9 @@ static const struct eth_dev_ops igbvf_eth_dev_ops = {
 	.dev_close            = igbvf_dev_close,
 	.link_update          = eth_igb_link_update,
 	.stats_get            = eth_igbvf_stats_get,
+	.xstats_get           = eth_igbvf_xstats_get,
 	.stats_reset          = eth_igbvf_stats_reset,
+	.xstats_reset         = eth_igbvf_stats_reset,
 	.vlan_filter_set      = igbvf_vlan_filter_set,
 	.dev_infos_get        = eth_igbvf_infos_get,
 	.rx_queue_setup       = eth_igb_rx_queue_setup,
@@ -428,6 +433,17 @@ static const struct rte_igb_xstats_name_off rte_igb_stats_strings[] = {
 #define IGB_NB_XSTATS (sizeof(rte_igb_stats_strings) / \
 		sizeof(rte_igb_stats_strings[0]))
 
+static const struct rte_igb_xstats_name_off rte_igbvf_stats_strings[] = {
+	{"rx_multicast_packets", offsetof(struct e1000_vf_stats, mprc)},
+	{"rx_good_loopback_packets", offsetof(struct e1000_vf_stats, gprlbc)},
+	{"tx_good_loopback_packets", offsetof(struct e1000_vf_stats, gptlbc)},
+	{"rx_good_loopback_bytes", offsetof(struct e1000_vf_stats, gorlbc)},
+	{"tx_good_loopback_bytes", offsetof(struct e1000_vf_stats, gotlbc)},
+};
+
+#define IGBVF_NB_XSTATS (sizeof(rte_igbvf_stats_strings) / \
+		sizeof(rte_igbvf_stats_strings[0]))
+
 /**
  * Atomically reads the link status information from global
  * structure rte_eth_dev.
@@ -1534,12 +1550,8 @@ eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
 }
 
 static void
-eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
+igbvf_read_stats_registers(struct e1000_hw *hw, struct e1000_vf_stats *hw_stats)
 {
-	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	struct e1000_vf_stats *hw_stats = (struct e1000_vf_stats*)
-			  E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
-
 	/* Good Rx packets, include VF loopback */
 	UPDATE_VF_STAT(E1000_VFGPRC,
 	    hw_stats->last_gprc, hw_stats->gprc);
@@ -1575,6 +1587,43 @@ eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
 	/* Good Tx loopback octets */
 	UPDATE_VF_STAT(E1000_VFGOTLBC,
 	    hw_stats->last_gotlbc, hw_stats->gotlbc);
+}
+
+static int
+eth_igbvf_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		     unsigned n)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_vf_stats *hw_stats = (struct e1000_vf_stats *)
+			E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+	unsigned i;
+
+	if(n < IGBVF_NB_XSTATS)
+		return IGBVF_NB_XSTATS;
+
+	igbvf_read_stats_registers(hw, hw_stats);
+
+	if(!xstats)
+		return 0;
+
+	for(i = 0; i < IGBVF_NB_XSTATS; i++) {
+		snprintf(xstats[i].name, sizeof(xstats[i].name), "%s",
+			 rte_igbvf_stats_strings[i].name);
+		xstats[i].value = *(uint64_t *)(((char *)hw_stats) +
+			rte_igbvf_stats_strings[i].offset);
+	}
+
+	return IGBVF_NB_XSTATS;
+}
+
+static void
+eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_vf_stats *hw_stats = (struct e1000_vf_stats *)
+			  E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+
+	igbvf_read_stats_registers(hw, hw_stats);
 
 	if (rte_stats == NULL)
 		return;
@@ -1602,7 +1651,6 @@ eth_igbvf_stats_reset(struct rte_eth_dev *dev)
 	/* reset HW current stats*/
 	memset(&hw_stats->gprc, 0, sizeof(*hw_stats) -
 	       offsetof(struct e1000_vf_stats, gprc));
-
 }
 
 static void
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v4 06/10] ixgbe: add extended statistic strings
  2015-10-30 11:36       ` [dpdk-dev] [PATCH v4 00/10] Port XStats Harry van Haaren
                           ` (4 preceding siblings ...)
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 05/10] igbvf: " Harry van Haaren
@ 2015-10-30 11:36         ` Harry van Haaren
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 07/10] ixgbevf: add xstats() implementation Harry van Haaren
                           ` (5 subsequent siblings)
  11 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-10-30 11:36 UTC (permalink / raw)
  To: dev

Added and updated statistic strings as used by xstats_get(),
exposed extended queue statistics.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 203 +++++++++++++++++++++++++++++++++------
 1 file changed, 172 insertions(+), 31 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 4373661..c657955 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -510,33 +510,95 @@ struct rte_ixgbe_xstats_name_off {
 };
 
 static const struct rte_ixgbe_xstats_name_off rte_ixgbe_stats_strings[] = {
-	{"rx_illegal_byte_err", offsetof(struct ixgbe_hw_stats, errbc)},
-	{"rx_len_err", offsetof(struct ixgbe_hw_stats, rlec)},
-	{"rx_undersize_count", offsetof(struct ixgbe_hw_stats, ruc)},
-	{"rx_oversize_count", offsetof(struct ixgbe_hw_stats, roc)},
-	{"rx_fragment_count", offsetof(struct ixgbe_hw_stats, rfc)},
-	{"rx_jabber_count", offsetof(struct ixgbe_hw_stats, rjc)},
-	{"l3_l4_xsum_error", offsetof(struct ixgbe_hw_stats, xec)},
-	{"mac_local_fault", offsetof(struct ixgbe_hw_stats, mlfc)},
-	{"mac_remote_fault", offsetof(struct ixgbe_hw_stats, mrfc)},
-	{"mac_short_pkt_discard", offsetof(struct ixgbe_hw_stats, mspdc)},
-	{"fccrc_error", offsetof(struct ixgbe_hw_stats, fccrc)},
-	{"fcoe_drop", offsetof(struct ixgbe_hw_stats, fcoerpdc)},
-	{"fc_last_error", offsetof(struct ixgbe_hw_stats, fclast)},
-	{"rx_broadcast_packets", offsetof(struct ixgbe_hw_stats, bprc)},
-	{"rx_phy_multicast_packets", offsetof(struct ixgbe_hw_stats, mprc)},
-	{"mgmt_pkts_dropped", offsetof(struct ixgbe_hw_stats, mngpdc)},
 	{"rx_crc_errors", offsetof(struct ixgbe_hw_stats, crcerrs)},
-	{"fdir_match", offsetof(struct ixgbe_hw_stats, fdirmatch)},
-	{"fdir_miss", offsetof(struct ixgbe_hw_stats, fdirmiss)},
-	{"tx_flow_control_xon", offsetof(struct ixgbe_hw_stats, lxontxc)},
-	{"rx_flow_control_xon", offsetof(struct ixgbe_hw_stats, lxonrxc)},
-	{"tx_flow_control_xoff", offsetof(struct ixgbe_hw_stats, lxofftxc)},
-	{"rx_flow_control_xoff", offsetof(struct ixgbe_hw_stats, lxoffrxc)},
+	{"rx_illegal_byte_errors", offsetof(struct ixgbe_hw_stats, illerrc)},
+	{"rx_error_bytes", offsetof(struct ixgbe_hw_stats, errbc)},
+	{"mac_local_errors", offsetof(struct ixgbe_hw_stats, mlfc)},
+	{"mac_remote_errors", offsetof(struct ixgbe_hw_stats, mrfc)},
+	{"rx_length_errors", offsetof(struct ixgbe_hw_stats, rlec)},
+	{"tx_xon_packets", offsetof(struct ixgbe_hw_stats, lxontxc)},
+	{"rx_xon_packets", offsetof(struct ixgbe_hw_stats, lxonrxc)},
+	{"tx_xoff_packets", offsetof(struct ixgbe_hw_stats, lxofftxc)},
+	{"rx_xoff_packets", offsetof(struct ixgbe_hw_stats, lxoffrxc)},
+	{"rx_size_64_packets", offsetof(struct ixgbe_hw_stats, prc64)},
+	{"rx_size_65_to_127_packets", offsetof(struct ixgbe_hw_stats, prc127)},
+	{"rx_size_128_to_255_packets", offsetof(struct ixgbe_hw_stats, prc255)},
+	{"rx_size_256_to_511_packets", offsetof(struct ixgbe_hw_stats, prc511)},
+	{"rx_size_512_to_1023_packets", offsetof(struct ixgbe_hw_stats,
+		prc1023)},
+	{"rx_size_1024_to_max_packets", offsetof(struct ixgbe_hw_stats,
+		prc1522)},
+	{"rx_broadcast_packets", offsetof(struct ixgbe_hw_stats, bprc)},
+	{"rx_multicast_packets", offsetof(struct ixgbe_hw_stats, mprc)},
+	{"rx_fragment_errors", offsetof(struct ixgbe_hw_stats, rfc)},
+	{"rx_undersize_errors", offsetof(struct ixgbe_hw_stats, ruc)},
+	{"rx_oversize_errors", offsetof(struct ixgbe_hw_stats, roc)},
+	{"rx_jabber_errors", offsetof(struct ixgbe_hw_stats, rjc)},
+	{"rx_managment_packets", offsetof(struct ixgbe_hw_stats, mngprc)},
+	{"rx_managment_dropped", offsetof(struct ixgbe_hw_stats, mngpdc)},
+	{"tx_managment_packets", offsetof(struct ixgbe_hw_stats, mngptc)},
+	{"rx_total_packets", offsetof(struct ixgbe_hw_stats, tpr)},
+	{"rx_total_bytes", offsetof(struct ixgbe_hw_stats, tor)},
+	{"tx_total_packets", offsetof(struct ixgbe_hw_stats, tpt)},
+	{"tx_size_64_packets", offsetof(struct ixgbe_hw_stats, ptc64)},
+	{"tx_size_65_to_127_packets", offsetof(struct ixgbe_hw_stats, ptc127)},
+	{"tx_size_128_to_255_packets", offsetof(struct ixgbe_hw_stats, ptc255)},
+	{"tx_size_256_to_511_packets", offsetof(struct ixgbe_hw_stats, ptc511)},
+	{"tx_size_512_to_1023_packets", offsetof(struct ixgbe_hw_stats,
+		ptc1023)},
+	{"tx_size_1024_to_max_packets", offsetof(struct ixgbe_hw_stats,
+		ptc1522)},
+	{"tx_multicast_packets", offsetof(struct ixgbe_hw_stats, mptc)},
+	{"tx_broadcast_packets", offsetof(struct ixgbe_hw_stats, bptc)},
+	{"rx_mac_short_packet_dropped", offsetof(struct ixgbe_hw_stats, mspdc)},
+	{"rx_l3_l4_xsum_error", offsetof(struct ixgbe_hw_stats, xec)},
+
+	{"flow_director_added_filters", offsetof(struct ixgbe_hw_stats,
+		fdirustat_add)},
+	{"flow_director_removed_filters", offsetof(struct ixgbe_hw_stats,
+		fdirustat_remove)},
+	{"flow_director_filter_add_errors", offsetof(struct ixgbe_hw_stats,
+		fdirfstat_fadd)},
+	{"flow_director_filter_remove_errors", offsetof(struct ixgbe_hw_stats,
+		fdirfstat_fremove)},
+	{"flow_director_matched_filters", offsetof(struct ixgbe_hw_stats,
+		fdirmatch)},
+	{"flow_director_missed_filters", offsetof(struct ixgbe_hw_stats,
+		fdirmiss)},
+
+	{"rx_fcoe_crc_errors", offsetof(struct ixgbe_hw_stats, fccrc)},
+	{"rx_fcoe_dropped", offsetof(struct ixgbe_hw_stats, fcoerpdc)},
+	{"rx_fcoe_mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats,
+		fclast)},
+	{"rx_fcoe_packets", offsetof(struct ixgbe_hw_stats, fcoeprc)},
+	{"tx_fcoe_packets", offsetof(struct ixgbe_hw_stats, fcoeptc)},
+	{"rx_fcoe_bytes", offsetof(struct ixgbe_hw_stats, fcoedwrc)},
+	{"tx_fcoe_bytes", offsetof(struct ixgbe_hw_stats, fcoedwtc)},
+	{"rx_fcoe_no_direct_data_placement", offsetof(struct ixgbe_hw_stats,
+		fcoe_noddp)},
+	{"rx_fcoe_no_direct_data_placement_ext_buff",
+		offsetof(struct ixgbe_hw_stats, fcoe_noddp_ext_buff)},
+
+	{"tx_flow_control_xon_packets", offsetof(struct ixgbe_hw_stats,
+		lxontxc)},
+	{"rx_flow_control_xon_packets", offsetof(struct ixgbe_hw_stats,
+		lxonrxc)},
+	{"tx_flow_control_xoff_packets", offsetof(struct ixgbe_hw_stats,
+		lxofftxc)},
+	{"rx_flow_control_xoff_packets", offsetof(struct ixgbe_hw_stats,
+		lxoffrxc)},
+	{"rx_total_missed_packets", offsetof(struct ixgbe_hw_stats, mpctotal)},
 };
 
-#define IXGBE_NB_XSTATS (sizeof(rte_ixgbe_stats_strings) /	\
-		sizeof(rte_ixgbe_stats_strings[0]))
+#define IXGBE_NB_HW_STATS (sizeof(rte_ixgbe_stats_strings) / \
+			   sizeof(rte_ixgbe_stats_strings[0]))
+
+/* Per-queue statistics */
+#define IXBGE_NB_8_PER_Q_STATS (8 * 7)
+#define IXBGE_NB_16_PER_Q_STATS (16 * 5)
+#define IXGBE_NB_Q_STATS (IXBGE_NB_8_PER_Q_STATS + IXBGE_NB_16_PER_Q_STATS)
+
+#define IXGBE_NB_XSTATS (IXGBE_NB_HW_STATS + IXGBE_NB_Q_STATS)
 
 /**
  * Atomically reads the link status information from global
@@ -2257,7 +2319,7 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
 	total_qprdc = 0;
 
 	ixgbe_read_stats_registers(hw, hw_stats, &total_missed_rx, &total_qbrc,
-							   &total_qprc, &total_qprdc);
+				   &total_qprc, &total_qprdc);
 
 	/* If this is a reset xstats is NULL, and we have cleared the
 	 * registers by reading them.
@@ -2265,12 +2327,91 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
 	if (!xstats)
 		return 0;
 
-	/* Extended stats */
-	for (i = 0; i < IXGBE_NB_XSTATS; i++) {
-		snprintf(xstats[i].name, sizeof(xstats[i].name),
-				"%s", rte_ixgbe_stats_strings[i].name);
-		xstats[i].value = *(uint64_t *)(((char *)hw_stats) +
-							rte_ixgbe_stats_strings[i].offset);
+	/* Extended stats from ixgbe_hw_stats */
+	count = 0;
+	for (i = 0; i < IXGBE_NB_HW_STATS; i++) {
+		snprintf(xstats[count].name, sizeof(xstats[count].name), "%s",
+			 rte_ixgbe_stats_strings[i].name);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				rte_ixgbe_stats_strings[i].offset);
+		count++;
+	}
+
+	/* Per-Q stats, with 8 queues available */
+	for (i = 0; i < 8; i++) {
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "rx_q%u_mbuf_allocation_errors", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, rnbc[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "rx_q%u_missed_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, mpc[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "rx_q%u_xon_priority_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, pxonrxc[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "tx_q%u_xon_priority_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, pxontxc[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "rx_q%u_xoff_priority_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, pxoffrxc[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "tx_q%u_xoff_priority_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, pxofftxc[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "xx_q%u_xon_to_xoff_priority_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, pxon2offc[i]));
+		count++;
+	}
+
+	for (i = 0; i < 16; i++) {
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "rx_q%u_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, qprc[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "rx_q%u_bytes", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, qbrc[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "tx_q%u_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, qptc[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "tx_q%u_bytes", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, qbtc[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "rx_q%u_dropped", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, qprdc[i]));
+		count++;
 	}
 
 	return count;
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v4 07/10] ixgbevf: add xstats() implementation
  2015-10-30 11:36       ` [dpdk-dev] [PATCH v4 00/10] Port XStats Harry van Haaren
                           ` (5 preceding siblings ...)
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 06/10] ixgbe: add extended statistic strings Harry van Haaren
@ 2015-10-30 11:36         ` Harry van Haaren
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 08/10] i40e: " Harry van Haaren
                           ` (4 subsequent siblings)
  11 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-10-30 11:36 UTC (permalink / raw)
  To: dev

Add xstats() functions and stat strings as necessary to ixgbevf PMD.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 51 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 49 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index c657955..53a646f 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -149,6 +149,8 @@ static void ixgbe_dev_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *stats);
 static int ixgbe_dev_xstats_get(struct rte_eth_dev *dev,
 				struct rte_eth_xstats *xstats, unsigned n);
+static int ixgbevf_dev_xstats_get(struct rte_eth_dev *dev,
+				  struct rte_eth_xstats *xstats, unsigned n);
 static void ixgbe_dev_stats_reset(struct rte_eth_dev *dev);
 static void ixgbe_dev_xstats_reset(struct rte_eth_dev *dev);
 static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
@@ -477,7 +479,9 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
 	.dev_stop             = ixgbevf_dev_stop,
 	.link_update          = ixgbe_dev_link_update,
 	.stats_get            = ixgbevf_dev_stats_get,
+	.xstats_get           = ixgbevf_dev_xstats_get,
 	.stats_reset          = ixgbevf_dev_stats_reset,
+	.xstats_reset         = ixgbevf_dev_stats_reset,
 	.dev_close            = ixgbevf_dev_close,
 	.dev_infos_get        = ixgbevf_dev_info_get,
 	.mtu_set              = ixgbevf_dev_set_mtu,
@@ -600,6 +604,13 @@ static const struct rte_ixgbe_xstats_name_off rte_ixgbe_stats_strings[] = {
 
 #define IXGBE_NB_XSTATS (IXGBE_NB_HW_STATS + IXGBE_NB_Q_STATS)
 
+static const struct rte_ixgbe_xstats_name_off rte_ixgbevf_stats_strings[] = {
+	{"rx_multicast_packets", offsetof(struct ixgbevf_hw_stats, vfmprc)},
+};
+
+#define IXGBEVF_NB_XSTATS (sizeof(rte_ixgbevf_stats_strings) /	\
+		sizeof(rte_ixgbevf_stats_strings[0]))
+
 /**
  * Atomically reads the link status information from global
  * structure rte_eth_dev.
@@ -2431,7 +2442,7 @@ ixgbe_dev_xstats_reset(struct rte_eth_dev *dev)
 }
 
 static void
-ixgbevf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+ixgbevf_update_stats(struct rte_eth_dev *dev)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct ixgbevf_hw_stats *hw_stats = (struct ixgbevf_hw_stats*)
@@ -2456,8 +2467,44 @@ ixgbevf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	/* Rx Multicst Packet */
 	UPDATE_VF_STAT(IXGBE_VFMPRC,
 	    hw_stats->last_vfmprc, hw_stats->vfmprc);
+}
 
-	if (stats == NULL)
+static int
+ixgbevf_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		       unsigned n)
+{
+	struct ixgbevf_hw_stats *hw_stats = (struct ixgbevf_hw_stats *)
+			IXGBE_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+	unsigned i;
+
+	if(n < IXGBEVF_NB_XSTATS)
+		return IXGBEVF_NB_XSTATS;
+
+	ixgbevf_update_stats(dev);
+
+	if (!xstats)
+		return 0;
+
+	/* Extended stats */
+	for (i = 0; i < IXGBEVF_NB_XSTATS; i++) {
+		snprintf(xstats[i].name, sizeof(xstats[i].name),
+			 "%s", rte_ixgbevf_stats_strings[i].name);
+		xstats[i].value = *(uint64_t *)(((char *)hw_stats) +
+			rte_ixgbevf_stats_strings[i].offset);
+	}
+
+	return IXGBEVF_NB_XSTATS;
+}
+
+static void
+ixgbevf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+	struct ixgbevf_hw_stats *hw_stats = (struct ixgbevf_hw_stats *)
+			  IXGBE_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+
+	ixgbevf_update_stats(dev);
+
+	if(stats == NULL)
 		return;
 
 	stats->ipackets = hw_stats->vfgprc;
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v4 08/10] i40e: add xstats() implementation
  2015-10-30 11:36       ` [dpdk-dev] [PATCH v4 00/10] Port XStats Harry van Haaren
                           ` (6 preceding siblings ...)
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 07/10] ixgbevf: add xstats() implementation Harry van Haaren
@ 2015-10-30 11:36         ` Harry van Haaren
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 09/10] i40evf: " Harry van Haaren
                           ` (3 subsequent siblings)
  11 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-10-30 11:36 UTC (permalink / raw)
  To: dev

Add xstats functions to i40e PMD, allowing extended statistics
to be retrieved from the NIC and exposed to the DPDK.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 217 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 210 insertions(+), 7 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 2dd9fdc..f3f2e0c 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -127,7 +127,10 @@ static int i40e_dev_set_link_up(struct rte_eth_dev *dev);
 static int i40e_dev_set_link_down(struct rte_eth_dev *dev);
 static void i40e_dev_stats_get(struct rte_eth_dev *dev,
 			       struct rte_eth_stats *stats);
+static int i40e_dev_xstats_get(struct rte_eth_dev *dev,
+			       struct rte_eth_xstats *xstats, unsigned n);
 static void i40e_dev_stats_reset(struct rte_eth_dev *dev);
+static void i40e_dev_xstats_reset(struct rte_eth_dev *dev);
 static int i40e_dev_queue_stats_mapping_set(struct rte_eth_dev *dev,
 					    uint16_t queue_id,
 					    uint8_t stat_idx,
@@ -232,6 +235,8 @@ static int i40e_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
 					   uint32_t flags);
 static int i40e_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
 					   struct timespec *timestamp);
+static void i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw);
+
 
 static const struct rte_pci_id pci_id_i40e_map[] = {
 #define RTE_PCI_DEV_ID_DECL_I40E(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
@@ -252,7 +257,9 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
 	.dev_set_link_down            = i40e_dev_set_link_down,
 	.link_update                  = i40e_dev_link_update,
 	.stats_get                    = i40e_dev_stats_get,
+	.xstats_get                   = i40e_dev_xstats_get,
 	.stats_reset                  = i40e_dev_stats_reset,
+	.xstats_reset                 = i40e_dev_xstats_reset,
 	.queue_stats_mapping_set      = i40e_dev_queue_stats_mapping_set,
 	.dev_infos_get                = i40e_dev_info_get,
 	.vlan_filter_set              = i40e_vlan_filter_set,
@@ -291,6 +298,101 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
 	.timesync_read_tx_timestamp   = i40e_timesync_read_tx_timestamp,
 };
 
+/* store statistics names and its offset in stats structure */
+struct rte_i40e_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	unsigned offset;
+};
+
+static const struct rte_i40e_xstats_name_off rte_i40e_stats_strings[] = {
+	{"rx_unicast_packets", offsetof(struct i40e_eth_stats, rx_unicast)},
+	{"rx_multicast_packets", offsetof(struct i40e_eth_stats, rx_multicast)},
+	{"rx_broadcast_packets", offsetof(struct i40e_eth_stats, rx_broadcast)},
+	{"rx_dropped", offsetof(struct i40e_eth_stats, rx_discards)},
+	{"rx_unknown_protocol_packets", offsetof(struct i40e_eth_stats,
+		rx_unknown_protocol)},
+	{"tx_unicast_packets", offsetof(struct i40e_eth_stats, tx_unicast)},
+	{"tx_multicast_packets", offsetof(struct i40e_eth_stats, tx_multicast)},
+	{"tx_broadcast_packets", offsetof(struct i40e_eth_stats, tx_broadcast)},
+	{"tx_dropped", offsetof(struct i40e_eth_stats, tx_discards)},
+};
+
+static const struct rte_i40e_xstats_name_off rte_i40e_hw_port_strings[] = {
+	{"tx_link_down_dropped", offsetof(struct i40e_hw_port_stats,
+		tx_dropped_link_down)},
+	{"rx_crc_errors", offsetof(struct i40e_hw_port_stats, crc_errors)},
+	{"rx_illegal_byte_errors", offsetof(struct i40e_hw_port_stats,
+		illegal_bytes)},
+	{"rx_error_bytes", offsetof(struct i40e_hw_port_stats, error_bytes)},
+	{"mac_local_errors", offsetof(struct i40e_hw_port_stats,
+		mac_local_faults)},
+	{"mac_remote_errors", offsetof(struct i40e_hw_port_stats,
+		mac_remote_faults)},
+	{"rx_length_errors", offsetof(struct i40e_hw_port_stats,
+		rx_length_errors)},
+	{"tx_xon_packets", offsetof(struct i40e_hw_port_stats, link_xon_tx)},
+	{"rx_xon_packets", offsetof(struct i40e_hw_port_stats, link_xon_rx)},
+	{"tx_xoff_packets", offsetof(struct i40e_hw_port_stats, link_xoff_tx)},
+	{"rx_xoff_packets", offsetof(struct i40e_hw_port_stats, link_xoff_rx)},
+	{"rx_size_64_packets", offsetof(struct i40e_hw_port_stats, rx_size_64)},
+	{"rx_size_65_to_127_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_127)},
+	{"rx_size_128_to_255_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_255)},
+	{"rx_size_256_to_511_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_511)},
+	{"rx_size_512_to_1023_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_1023)},
+	{"rx_size_1024_to_1522_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_1522)},
+	{"rx_size_1523_to_max_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_big)},
+	{"rx_undersized_errors", offsetof(struct i40e_hw_port_stats,
+		rx_undersize)},
+	{"rx_oversize_errors", offsetof(struct i40e_hw_port_stats,
+		rx_oversize)},
+	{"rx_mac_short_dropped", offsetof(struct i40e_hw_port_stats,
+		mac_short_packet_dropped)},
+	{"rx_fragmented_errors", offsetof(struct i40e_hw_port_stats,
+		rx_fragments)},
+	{"rx_jabber_errors", offsetof(struct i40e_hw_port_stats, rx_jabber)},
+	{"tx_size_64_packets", offsetof(struct i40e_hw_port_stats, tx_size_64)},
+	{"tx_size_65_to_127_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_127)},
+	{"tx_size_128_to_255_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_255)},
+	{"tx_size_256_to_511_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_511)},
+	{"tx_size_512_to_1023_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_1023)},
+	{"tx_size_1024_to_1522_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_1522)},
+	{"tx_size_1523_to_max_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_big)},
+	{"rx_flow_director_atr_match_packets",
+		offsetof(struct i40e_hw_port_stats, fd_atr_match)},
+	{"rx_flow_director_sb_match_packets",
+		offsetof(struct i40e_hw_port_stats, fd_sb_match)},
+	{"tx_low_power_idle_status", offsetof(struct i40e_hw_port_stats,
+		tx_lpi_status)},
+	{"rx_low_power_idle_status", offsetof(struct i40e_hw_port_stats,
+		rx_lpi_status)},
+	{"tx_low_power_idle_count", offsetof(struct i40e_hw_port_stats,
+		tx_lpi_count)},
+	{"rx_low_power_idle_count", offsetof(struct i40e_hw_port_stats,
+		rx_lpi_count)},
+};
+
+/* Q Stats: 5 stats are exposed for each queue, implemented in xstats_get() */
+#define I40E_NB_HW_PORT_Q_STATS (8 * 5)
+
+#define I40E_NB_ETH_XSTATS (sizeof(rte_i40e_stats_strings) / \
+		sizeof(rte_i40e_stats_strings[0]))
+#define I40E_NB_HW_PORT_XSTATS (sizeof(rte_i40e_hw_port_strings) / \
+		sizeof(rte_i40e_hw_port_strings[0]))
+#define I40E_NB_XSTATS (I40E_NB_ETH_XSTATS + I40E_NB_HW_PORT_XSTATS + \
+		I40E_NB_HW_PORT_Q_STATS)
+
 static struct eth_driver rte_i40e_pmd = {
 	.pci_drv = {
 		.name = "rte_i40e_pmd",
@@ -1322,16 +1424,12 @@ i40e_update_vsi_stats(struct i40e_vsi *vsi)
 		    vsi->vsi_id);
 }
 
-/* Get all statistics of a port */
 static void
-i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw)
 {
-	uint32_t i;
-	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	unsigned int i;
 	struct i40e_hw_port_stats *ns = &pf->stats; /* new stats */
 	struct i40e_hw_port_stats *os = &pf->stats_offset; /* old stats */
-
 	/* Get statistics of struct i40e_eth_stats */
 	i40e_stat_update_48(hw, I40E_GLPRT_GORCH(hw->port),
 			    I40E_GLPRT_GORCL(hw->port),
@@ -1508,8 +1606,21 @@ i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 
 	pf->offset_loaded = true;
 
-	if (pf->main_vsi)
+	if(pf->main_vsi)
 		i40e_update_vsi_stats(pf->main_vsi);
+}
+
+/* Get all statistics of a port */
+static void
+i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct i40e_hw_port_stats *ns = &pf->stats; /* new stats */
+	unsigned i;
+
+	/* call read registers - updates values, now write them to struct */
+	i40e_read_stats_registers(pf, hw);
 
 	stats->ipackets = ns->eth.rx_unicast + ns->eth.rx_multicast +
 						ns->eth.rx_broadcast;
@@ -1599,6 +1710,98 @@ i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	PMD_DRV_LOG(DEBUG, "***************** PF stats end ********************");
 }
 
+static void
+i40e_dev_xstats_reset(struct rte_eth_dev *dev)
+{
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct i40e_hw_port_stats *hw_stats = &pf->stats;
+
+	/* The hw registers are cleared on read */
+	pf->offset_loaded = false;
+	i40e_read_stats_registers(pf, hw);
+
+	/* reset software counters */
+	memset(hw_stats, 0, sizeof(*hw_stats));
+}
+
+static int
+i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		    unsigned n)
+{
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	unsigned i, count = 0;
+	struct i40e_hw_port_stats *hw_stats = &pf->stats;
+
+	if (n < I40E_NB_XSTATS)
+		return I40E_NB_XSTATS;
+
+	i40e_read_stats_registers(pf, hw);
+
+	/* Reset */
+	if (xstats == NULL)
+		return 0;
+
+	/* Get stats from i40e_eth_stats struct */
+	for (i = 0; i < I40E_NB_ETH_XSTATS; i++) {
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "%s", rte_i40e_stats_strings[i].name);
+		xstats[count].value = *(uint64_t *)(((char *)&hw_stats->eth) +
+			rte_i40e_stats_strings[i].offset);
+		count++;
+	}
+
+	/* Get individiual stats from i40e_hw_port struct */
+	for (i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) {
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "%s", rte_i40e_hw_port_strings[i].name);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				rte_i40e_hw_port_strings[i].offset);
+		count++;
+	}
+
+	/* Get per-queue stats from i40e_hw_port struct */
+	for (i = 0; i < 8; i++) {
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "rx_q%u_xon_priority_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct i40e_hw_port_stats,
+					 priority_xon_rx[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "rx_q%u_xoff_priority_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct i40e_hw_port_stats,
+					 priority_xoff_rx[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "tx_q%u_xon_priority_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct i40e_hw_port_stats,
+					 priority_xon_tx[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "tx_q%u_xoff_priority_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct i40e_hw_port_stats,
+					 priority_xoff_tx[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "xx_q%u_xon_to_xoff_priority_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct i40e_hw_port_stats,
+					 priority_xon_2_xoff[i]));
+		count++;
+	}
+
+	return I40E_NB_XSTATS;
+}
+
 /* Reset the statistics */
 static void
 i40e_dev_stats_reset(struct rte_eth_dev *dev)
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v4 09/10] i40evf: add xstats() implementation
  2015-10-30 11:36       ` [dpdk-dev] [PATCH v4 00/10] Port XStats Harry van Haaren
                           ` (7 preceding siblings ...)
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 08/10] i40e: " Harry van Haaren
@ 2015-10-30 11:36         ` Harry van Haaren
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 10/10] fm10k: " Harry van Haaren
                           ` (2 subsequent siblings)
  11 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-10-30 11:36 UTC (permalink / raw)
  To: dev

Add implementation of xstats() functions in i40evf PMD.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/i40e/i40e_ethdev_vf.c | 89 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 86 insertions(+), 3 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index b694400..3181400 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -112,6 +112,9 @@ static int i40evf_dev_link_update(struct rte_eth_dev *dev,
 				  __rte_unused int wait_to_complete);
 static void i40evf_dev_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *stats);
+static int i40evf_dev_xstats_get(struct rte_eth_dev *dev,
+				 struct rte_eth_xstats *xstats, unsigned n);
+static void i40evf_dev_xstats_reset(struct rte_eth_dev *dev);
 static int i40evf_vlan_filter_set(struct rte_eth_dev *dev,
 				  uint16_t vlan_id, int on);
 static void i40evf_vlan_offload_set(struct rte_eth_dev *dev, int mask);
@@ -148,6 +151,30 @@ static int i40evf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 /* Default hash key buffer for RSS */
 static uint32_t rss_key_default[I40E_VFQF_HKEY_MAX_INDEX + 1];
 
+struct rte_i40evf_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	unsigned offset;
+};
+
+static const struct rte_i40evf_xstats_name_off rte_i40evf_stats_strings[] = {
+	{"rx_bytes", offsetof(struct i40e_eth_stats, rx_bytes)},
+	{"rx_unicast_packets", offsetof(struct i40e_eth_stats, rx_unicast)},
+	{"rx_multicast_packets", offsetof(struct i40e_eth_stats, rx_multicast)},
+	{"rx_broadcast_packets", offsetof(struct i40e_eth_stats, rx_broadcast)},
+	{"rx_dropped_packets", offsetof(struct i40e_eth_stats, rx_discards)},
+	{"rx_unknown_protocol_packets", offsetof(struct i40e_eth_stats,
+		rx_unknown_protocol)},
+	{"tx_bytes", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_unicast_packets", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_multicast_packets", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_broadcast_packets", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_dropped_packets", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_error_packets", offsetof(struct i40e_eth_stats, tx_bytes)},
+};
+
+#define I40EVF_NB_XSTATS (sizeof(rte_i40evf_stats_strings) / \
+		sizeof(rte_i40evf_stats_strings[0]))
+
 static const struct eth_dev_ops i40evf_eth_dev_ops = {
 	.dev_configure        = i40evf_dev_configure,
 	.dev_start            = i40evf_dev_start,
@@ -158,6 +185,8 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = {
 	.allmulticast_disable = i40evf_dev_allmulticast_disable,
 	.link_update          = i40evf_dev_link_update,
 	.stats_get            = i40evf_dev_stats_get,
+	.xstats_get           = i40evf_dev_xstats_get,
+	.xstats_reset         = i40evf_dev_xstats_reset,
 	.dev_close            = i40evf_dev_close,
 	.dev_infos_get        = i40evf_dev_info_get,
 	.vlan_filter_set      = i40evf_vlan_filter_set,
@@ -888,11 +917,10 @@ i40evf_del_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 }
 
 static int
-i40evf_get_statics(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+i40evf_update_stats(struct rte_eth_dev *dev, struct i40e_eth_stats **pstats)
 {
 	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 	struct i40e_virtchnl_queue_select q_stats;
-	struct i40e_eth_stats *pstats;
 	int err;
 	struct vf_cmd_info args;
 
@@ -907,9 +935,23 @@ i40evf_get_statics(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	err = i40evf_execute_vf_cmd(dev, &args);
 	if (err) {
 		PMD_DRV_LOG(ERR, "fail to execute command OP_GET_STATS");
+		*pstats = NULL;
 		return err;
 	}
-	pstats = (struct i40e_eth_stats *)args.out_buffer;
+	*pstats = (struct i40e_eth_stats *)args.out_buffer;
+	return 0;
+}
+
+static int
+i40evf_get_statics(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+	int ret;
+	struct i40e_eth_stats *pstats = NULL;
+
+	ret = i40evf_update_stats(dev, &pstats);
+	if(ret != 0)
+		return 0;
+
 	stats->ipackets = pstats->rx_unicast + pstats->rx_multicast +
 						pstats->rx_broadcast;
 	stats->opackets = pstats->tx_broadcast + pstats->tx_multicast +
@@ -922,6 +964,47 @@ i40evf_get_statics(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	return 0;
 }
 
+static void
+i40evf_dev_xstats_reset(struct rte_eth_dev *dev)
+{
+	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+	struct i40e_eth_stats *pstats = NULL;
+
+	/* read stat values to clear hardware registers */
+	i40evf_update_stats(dev, &pstats);
+
+	/* set stats offset base on current values */
+	vf->vsi.eth_stats_offset = vf->vsi.eth_stats;
+}
+
+static int i40evf_dev_xstats_get(struct rte_eth_dev *dev,
+				 struct rte_eth_xstats *xstats, unsigned n)
+{
+	int ret;
+	unsigned i;
+	struct i40e_eth_stats *pstats = NULL;
+
+	if(n < I40EVF_NB_XSTATS)
+		return I40EVF_NB_XSTATS;
+
+	ret = i40evf_update_stats(dev, &pstats);
+	if(ret != 0)
+		return 0;
+
+	if(!xstats)
+		return 0;
+
+	/* loop over xstats array and values from pstats */
+	for(i = 0; i < I40EVF_NB_XSTATS; i++) {
+		snprintf(xstats[i].name, sizeof(xstats[i].name),
+			 "%s", rte_i40evf_stats_strings[i].name);
+		xstats[i].value = *(uint64_t *)(((char *)pstats) +
+			rte_i40evf_stats_strings[i].offset);
+	}
+
+	return I40EVF_NB_XSTATS;
+}
+
 static int
 i40evf_add_vlan(struct rte_eth_dev *dev, uint16_t vlanid)
 {
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v4 10/10] fm10k: add xstats() implementation
  2015-10-30 11:36       ` [dpdk-dev] [PATCH v4 00/10] Port XStats Harry van Haaren
                           ` (8 preceding siblings ...)
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 09/10] i40evf: " Harry van Haaren
@ 2015-10-30 11:36         ` Harry van Haaren
  2015-10-30 13:21         ` [dpdk-dev] [PATCH v4 00/10] Port XStats Tahhan, Maryam
  2015-11-02  8:04         ` Thomas Monjalon
  11 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-10-30 11:36 UTC (permalink / raw)
  To: dev

Add xstats() functions and statistic strings.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/fm10k/fm10k_ethdev.c | 87 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 87 insertions(+)

diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index b104fc2..533b25e 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -68,6 +68,46 @@ fm10k_MACVLAN_remove_all(struct rte_eth_dev *dev);
 static void fm10k_tx_queue_release(void *queue);
 static void fm10k_rx_queue_release(void *queue);
 
+struct fm10k_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	unsigned offset;
+};
+
+struct fm10k_xstats_name_off fm10k_hw_stats_strings[] = {
+	{"completion_timeout_count", offsetof(struct fm10k_hw_stats, timeout)},
+	{"unsupported_requests_count", offsetof(struct fm10k_hw_stats, ur)},
+	{"completer_abort_count", offsetof(struct fm10k_hw_stats, ca)},
+	{"unsupported_message_count", offsetof(struct fm10k_hw_stats, um)},
+	{"checksum_error_count", offsetof(struct fm10k_hw_stats, xec)},
+	{"vlan_dropped", offsetof(struct fm10k_hw_stats, vlan_drop)},
+	{"loopback_dropped", offsetof(struct fm10k_hw_stats, loopback_drop)},
+	{"rx_mbuf_allocation_errors", offsetof(struct fm10k_hw_stats,
+		nodesc_drop)},
+};
+
+#define FM10K_NB_HW_XSTATS (sizeof(fm10k_hw_stats_strings) / \
+		sizeof(fm10k_hw_stats_strings[0]))
+
+struct fm10k_xstats_name_off fm10k_hw_stats_rx_q_strings[] = {
+	{"packets", offsetof(struct fm10k_hw_stats_q, rx_packets)},
+	{"bytes", offsetof(struct fm10k_hw_stats_q, rx_bytes)},
+	{"dropped", offsetof(struct fm10k_hw_stats_q, rx_drops)},
+};
+
+#define FM10K_NB_RX_Q_XSTATS (sizeof(fm10k_hw_stats_rx_q_strings) / \
+		sizeof(fm10k_hw_stats_rx_q_strings[0]))
+
+struct fm10k_xstats_name_off fm10k_hw_stats_tx_q_strings[] = {
+	{"packets", offsetof(struct fm10k_hw_stats_q, tx_packets)},
+	{"bytes", offsetof(struct fm10k_hw_stats_q, tx_bytes)},
+};
+
+#define FM10K_NB_TX_Q_XSTATS (sizeof(fm10k_hw_stats_tx_q_strings) / \
+		sizeof(fm10k_hw_stats_tx_q_strings[0]))
+
+#define FM10K_NB_XSTATS (FM10K_NB_HW_XSTATS + FM10K_MAX_QUEUES_PF * \
+		(FM10K_NB_RX_Q_XSTATS + FM10K_NB_TX_Q_XSTATS))
+
 static void
 fm10k_mbx_initlock(struct fm10k_hw *hw)
 {
@@ -867,6 +907,51 @@ fm10k_link_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static int
+fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		 unsigned n)
+{
+	struct fm10k_hw_stats *hw_stats =
+		FM10K_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+	unsigned i, q, count = 0;
+
+	if(n < FM10K_NB_XSTATS)
+		return FM10K_NB_XSTATS;
+
+	/* Global stats */
+	for(i = 0; i < FM10K_NB_HW_XSTATS; i++) {
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "%s", fm10k_hw_stats_strings[count].name);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+			fm10k_hw_stats_strings[count].offset);
+		count++;
+	}
+
+	/* PF queue stats */
+	for(q = 0; q < FM10K_MAX_QUEUES_PF; q++) {
+		for(i = 0; i < FM10K_NB_RX_Q_XSTATS; i++) {
+			snprintf(xstats[count].name, sizeof(xstats[count].name),
+				 "rx_q%u_%s", q,
+				 fm10k_hw_stats_rx_q_strings[i].name);
+			xstats[count].value =
+				*(uint64_t *)(((char *)&hw_stats->q[q]) +
+				fm10k_hw_stats_rx_q_strings[i].offset);
+			count++;
+		}
+		for(i = 0; i < FM10K_NB_TX_Q_XSTATS; i++) {
+			snprintf(xstats[count].name, sizeof(xstats[count].name),
+				 "tx_q%u_%s", q,
+				 fm10k_hw_stats_tx_q_strings[i].name);
+			xstats[count].value =
+				*(uint64_t *)(((char *)&hw_stats->q[q]) +
+				fm10k_hw_stats_tx_q_strings[i].offset);
+			count++;
+		}
+	}
+
+	return FM10K_NB_XSTATS;
+}
+
 static void
 fm10k_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 {
@@ -2035,7 +2120,9 @@ static const struct eth_dev_ops fm10k_eth_dev_ops = {
 	.allmulticast_enable    = fm10k_dev_allmulticast_enable,
 	.allmulticast_disable   = fm10k_dev_allmulticast_disable,
 	.stats_get		= fm10k_stats_get,
+	.xstats_get		= fm10k_xstats_get,
 	.stats_reset		= fm10k_stats_reset,
+	.xstats_reset		= fm10k_stats_reset,
 	.link_update		= fm10k_link_update,
 	.dev_infos_get		= fm10k_dev_infos_get,
 	.vlan_filter_set	= fm10k_vlan_filter_set,
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v4 00/10] Port XStats
  2015-10-30 11:36       ` [dpdk-dev] [PATCH v4 00/10] Port XStats Harry van Haaren
                           ` (9 preceding siblings ...)
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 10/10] fm10k: " Harry van Haaren
@ 2015-10-30 13:21         ` Tahhan, Maryam
  2015-11-02  8:04         ` Thomas Monjalon
  11 siblings, 0 replies; 77+ messages in thread
From: Tahhan, Maryam @ 2015-10-30 13:21 UTC (permalink / raw)
  To: Van Haaren, Harry, dev

> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Harry van Haaren
> Sent: Friday, October 30, 2015 11:36 AM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v4 00/10] Port XStats
> 
> This patchset adds an implementation of the xstats_get() and xstats_reset()
> API to the following PMDs: virtio, igb, igbvf, ixgbe, ixgbevf, i40e, i40evf and
> fm10k.
> 
> The xstats API allows DPDK apps to gain access to extended statistics from
> each port on a NIC. These statistics are structured as per a scheme detailed in
> the patch for the doc/prog_guide.
> 
> v4: Consistency of names, refactored Q stat code
> v3: Added more stats to PMDs
> v2: Send correct patchset
> 
> Harry van Haaren (10):
>   doc: add extended statistics to prog_guide
>   ethdev: update xstats_get() strings and Q handling
>   virtio: add xstats() implementation
>   igb: add xstats() implementation
>   igbvf: add xstats() implementation
>   ixgbe: add extended statistic strings
>   ixgbevf: add xstats() implementation
>   i40e: add xstats() implementation
>   i40evf: add xstats() implementation
>   fm10k: add xstats() implementation
> 
>  doc/guides/prog_guide/poll_mode_drv.rst |  51 ++++++-
>  doc/guides/rel_notes/release_2_2.rst    |  14 ++
>  drivers/net/e1000/igb_ethdev.c          | 193 ++++++++++++++++++++++--
>  drivers/net/fm10k/fm10k_ethdev.c        |  87 +++++++++++
>  drivers/net/i40e/i40e_ethdev.c          | 217
> ++++++++++++++++++++++++++-
>  drivers/net/i40e/i40e_ethdev_vf.c       |  89 ++++++++++-
>  drivers/net/ixgbe/ixgbe_ethdev.c        | 254
> +++++++++++++++++++++++++++-----
>  drivers/net/virtio/virtio_ethdev.c      |  98 +++++++++++-
>  drivers/net/virtio/virtio_rxtx.c        |  32 ++++
>  drivers/net/virtio/virtqueue.h          |   4 +
>  lib/librte_ether/rte_ethdev.c           |  38 +++--
>  11 files changed, 1006 insertions(+), 71 deletions(-)
> 
> --
> 1.9.1

Series-acked-by: Maryam Tahhan <maryam.tahhan@intel.com>

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v4 02/10] ethdev: update xstats_get() strings and Q handling
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 02/10] ethdev: update xstats_get() strings and Q handling Harry van Haaren
@ 2015-11-02  7:59           ` Thomas Monjalon
  2015-11-02 10:17             ` Van Haaren, Harry
  0 siblings, 1 reply; 77+ messages in thread
From: Thomas Monjalon @ 2015-11-02  7:59 UTC (permalink / raw)
  To: Harry van Haaren; +Cc: dev

2015-10-30 11:36, Harry van Haaren:
> +       /* if xstats_get() is implemented by the PMD, the Q stats are done */
> +       if (dev->dev_ops->xstats_get != NULL)
> +               return count + xcount;
> +
>         /* per-rxq stats */
>         for (q = 0; q < dev->data->nb_rx_queues; q++) {
>                 for (i = 0; i < RTE_NB_RXQ_STATS; i++) {

Please could you explain why the generic per-queue stats are not used when
xstats is implemented in the driver?

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v4 00/10] Port XStats
  2015-10-30 11:36       ` [dpdk-dev] [PATCH v4 00/10] Port XStats Harry van Haaren
                           ` (10 preceding siblings ...)
  2015-10-30 13:21         ` [dpdk-dev] [PATCH v4 00/10] Port XStats Tahhan, Maryam
@ 2015-11-02  8:04         ` Thomas Monjalon
  11 siblings, 0 replies; 77+ messages in thread
From: Thomas Monjalon @ 2015-11-02  8:04 UTC (permalink / raw)
  To: Harry van Haaren; +Cc: dev

Harry,
Checkpatch is not happy because you missed the space after the keywords
"if" and "for".

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v4 02/10] ethdev: update xstats_get() strings and Q handling
  2015-11-02  7:59           ` Thomas Monjalon
@ 2015-11-02 10:17             ` Van Haaren, Harry
  2015-11-02 16:23               ` Thomas Monjalon
  0 siblings, 1 reply; 77+ messages in thread
From: Van Haaren, Harry @ 2015-11-02 10:17 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

Hi,

> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Monday, November 2, 2015 7:59 AM
> > +       /* if xstats_get() is implemented by the PMD, the Q stats are done */
> > +       if (dev->dev_ops->xstats_get != NULL)
> > +               return count + xcount;
> > +
> >         /* per-rxq stats */
> >         for (q = 0; q < dev->data->nb_rx_queues; q++) {
> >                 for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
> 
> Please could you explain why the generic per-queue stats are not used when
> xstats is implemented in the driver?

Each PMD exposes its own queue stats so it has the flexibility of presenting them exactly has the hardware counts, in a human-readable order.

If the generic xstats were used, testpmd> xstats output would split a single queue's xstats to two places in the list. As stats are used during debugging, readability and clarity of the stats is vital in my opinion.

-Harry

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v5 00/10] Port XStats
  2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 01/10] doc: add extended statistics to prog_guide Harry van Haaren
@ 2015-11-02 10:18           ` Harry van Haaren
  2015-11-02 10:18             ` [dpdk-dev] [PATCH v5 01/10] doc: add extended statistics to prog_guide Harry van Haaren
                               ` (10 more replies)
  0 siblings, 11 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-11-02 10:18 UTC (permalink / raw)
  To: dev

This patchset adds an implementation of the xstats_get() and xstats_reset() API
to the following PMDs: virtio, igb, igbvf, ixgbe, ixgbevf, i40e, i40evf and
fm10k.

The xstats API allows DPDK apps to gain access to extended statistics from each
port on a NIC. These statistics are structured as per a scheme detailed in the
patch for the doc/prog_guide.

v5: Fix Checkpatch inconsistencies
v4: Consistency of names, refactored Q stat code
v3: Added more stats to PMDs
v2: Send correct patchset

Harry van Haaren (10):
  doc: add extended statistics to prog_guide
  ethdev: update xstats_get() strings and Q handling
  virtio: add xstats() implementation
  igb: add xstats() implementation
  igbvf: add xstats() implementation
  ixgbe: add extended statistic strings
  ixgbevf: add xstats() implementation
  i40e: add xstats() implementation
  i40evf: add xstats() implementation
  fm10k: add xstats() implementation

 doc/guides/prog_guide/poll_mode_drv.rst |  51 ++++++-
 doc/guides/rel_notes/release_2_2.rst    |  14 ++
 drivers/net/e1000/igb_ethdev.c          | 193 ++++++++++++++++++++++--
 drivers/net/fm10k/fm10k_ethdev.c        |  87 +++++++++++
 drivers/net/i40e/i40e_ethdev.c          | 215 ++++++++++++++++++++++++++-
 drivers/net/i40e/i40e_ethdev_vf.c       |  89 ++++++++++-
 drivers/net/ixgbe/ixgbe_ethdev.c        | 252 ++++++++++++++++++++++++++++----
 drivers/net/virtio/virtio_ethdev.c      |  98 ++++++++++++-
 drivers/net/virtio/virtio_rxtx.c        |  32 ++++
 drivers/net/virtio/virtqueue.h          |   4 +
 lib/librte_ether/rte_ethdev.c           |  38 +++--
 11 files changed, 1004 insertions(+), 69 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v5 01/10] doc: add extended statistics to prog_guide
  2015-11-02 10:18           ` [dpdk-dev] [PATCH v5 00/10] Port XStats Harry van Haaren
@ 2015-11-02 10:18             ` Harry van Haaren
  2015-11-02 10:18             ` [dpdk-dev] [PATCH v5 02/10] ethdev: update xstats_get() strings and Q handling Harry van Haaren
                               ` (9 subsequent siblings)
  10 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-11-02 10:18 UTC (permalink / raw)
  To: dev

Add extended statistic section to the programmers
guide, poll mode driver section. This section describes
how the strings stats are formatted, and how the client
code can use this to gather information about the stat.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 doc/guides/prog_guide/poll_mode_drv.rst | 51 ++++++++++++++++++++++++++++++++-
 doc/guides/rel_notes/release_2_2.rst    | 14 +++++++++
 2 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/doc/guides/prog_guide/poll_mode_drv.rst b/doc/guides/prog_guide/poll_mode_drv.rst
index 8780ba3..44cc9ce 100644
--- a/doc/guides/prog_guide/poll_mode_drv.rst
+++ b/doc/guides/prog_guide/poll_mode_drv.rst
@@ -1,5 +1,5 @@
 ..  BSD LICENSE
-    Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+    Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
     All rights reserved.
 
     Redistribution and use in source and binary forms, with or without
@@ -294,3 +294,52 @@ Ethernet Device API
 ~~~~~~~~~~~~~~~~~~~
 
 The Ethernet device API exported by the Ethernet PMDs is described in the *DPDK API Reference*.
+
+Extended Statistics API
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The extended statistics API allows each individual PMD to expose a unique set
+of statistics. The client of the API provides an array of
+``struct rte_eth_xstats`` type. Each ``struct rte_eth_xstats`` contains a
+string and value pair. The amount of xstats exposed, and position of the
+statistic in the array must remain constant during runtime.
+
+A naming scheme exists for the strings exposed to clients of the API. This is
+to allow scraping of the API for statistics of interest. The naming scheme uses
+strings split by a single underscore ``_``. The scheme is as follows:
+
+* direction
+* detail 1
+* detail 2
+* detail n
+* unit
+
+Examples of common statistics xstats strings, formatted to comply to the scheme
+proposed above:
+
+* ``rx_bytes``
+* ``rx_crc_errors``
+* ``tx_multicast_packets``
+
+The scheme, although quite simple, allows flexibility in presenting and reading
+information from the statistic strings. The following example illustrates the
+naming scheme:``rx_packets``. In this example, the string is split into two
+components. The first component ``rx`` indicates that the statistic is
+associated with the receive side of the NIC.  The second component ``packets``
+indicates that the unit of measure is packets.
+
+A more complicated example: ``tx_size_128_to_255_packets``. In this example,
+``tx`` indicates transmission, ``size``  is the first detail, ``128`` etc are
+more details, and ``packets`` indicates that this is a packet counter.
+
+Some additions in the metadata scheme are as follows:
+
+* If the first part does not match ``rx`` or ``tx``, the statistic does not
+  have an affinity with either recieve of transmit.
+
+* If the first letter of the second part is ``q`` and this ``q`` is followed
+  by a number, this statistic is part of a specific queue.
+
+An example where queue numbers are used is as follows: ``tx_q7_bytes`` which
+indicates this statistic applies to queue number 7, and represents the number
+of transmitted bytes on that queue.
diff --git a/doc/guides/rel_notes/release_2_2.rst b/doc/guides/rel_notes/release_2_2.rst
index 89e4d58..8e29ec3 100644
--- a/doc/guides/rel_notes/release_2_2.rst
+++ b/doc/guides/rel_notes/release_2_2.rst
@@ -31,6 +31,20 @@ New Features
 
 * **Added vhost-user multiple queue support.**
 
+* **Extended Statistics**
+
+  Define extended statistics naming scheme to store metadata in the name
+  string name of each statistic, refer to the Extended Statistics section
+  of the programmers guide. Implemented the extended stats API for these
+  PMDs:
+
+  * igb
+  * igbvf
+  * i40e
+  * i40evf
+  * fm10k
+  * virtio
+
 Resolved Issues
 ---------------
 
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v5 02/10] ethdev: update xstats_get() strings and Q handling
  2015-11-02 10:18           ` [dpdk-dev] [PATCH v5 00/10] Port XStats Harry van Haaren
  2015-11-02 10:18             ` [dpdk-dev] [PATCH v5 01/10] doc: add extended statistics to prog_guide Harry van Haaren
@ 2015-11-02 10:18             ` Harry van Haaren
  2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 03/10] virtio: add xstats() implementation Harry van Haaren
                               ` (8 subsequent siblings)
  10 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-11-02 10:18 UTC (permalink / raw)
  To: dev

Update the strings used for presenting stats to adhere
to the scheme previously presented. Updated xstats_get()
function to handle Q information only if xstats() is not
implemented in the PMD, providing the PMD with the needed
flexibility to expose its extended Q stats.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 lib/librte_ether/rte_ethdev.c | 38 +++++++++++++++++++++++---------------
 1 file changed, 23 insertions(+), 15 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index f593f6e..07f0c26 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -137,27 +137,30 @@ struct rte_eth_xstats_name_off {
 };
 
 static const struct rte_eth_xstats_name_off rte_stats_strings[] = {
-	{"rx_packets", offsetof(struct rte_eth_stats, ipackets)},
-	{"tx_packets", offsetof(struct rte_eth_stats, opackets)},
-	{"rx_bytes", offsetof(struct rte_eth_stats, ibytes)},
-	{"tx_bytes", offsetof(struct rte_eth_stats, obytes)},
-	{"tx_errors", offsetof(struct rte_eth_stats, oerrors)},
+	{"rx_good_packets", offsetof(struct rte_eth_stats, ipackets)},
+	{"tx_good_packets", offsetof(struct rte_eth_stats, opackets)},
+	{"rx_good_bytes", offsetof(struct rte_eth_stats, ibytes)},
+	{"tx_good_bytes", offsetof(struct rte_eth_stats, obytes)},
 	{"rx_errors", offsetof(struct rte_eth_stats, ierrors)},
-	{"alloc_rx_buff_failed", offsetof(struct rte_eth_stats, rx_nombuf)},
+	{"tx_errors", offsetof(struct rte_eth_stats, oerrors)},
+	{"rx_mbuf_allocation_errors", offsetof(struct rte_eth_stats,
+		rx_nombuf)},
 };
+
 #define RTE_NB_STATS (sizeof(rte_stats_strings) / sizeof(rte_stats_strings[0]))
 
 static const struct rte_eth_xstats_name_off rte_rxq_stats_strings[] = {
-	{"rx_packets", offsetof(struct rte_eth_stats, q_ipackets)},
-	{"rx_bytes", offsetof(struct rte_eth_stats, q_ibytes)},
+	{"packets", offsetof(struct rte_eth_stats, q_ipackets)},
+	{"bytes", offsetof(struct rte_eth_stats, q_ibytes)},
+	{"errors", offsetof(struct rte_eth_stats, q_errors)},
 };
+
 #define RTE_NB_RXQ_STATS (sizeof(rte_rxq_stats_strings) /	\
 		sizeof(rte_rxq_stats_strings[0]))
 
 static const struct rte_eth_xstats_name_off rte_txq_stats_strings[] = {
-	{"tx_packets", offsetof(struct rte_eth_stats, q_opackets)},
-	{"tx_bytes", offsetof(struct rte_eth_stats, q_obytes)},
-	{"tx_errors", offsetof(struct rte_eth_stats, q_errors)},
+	{"packets", offsetof(struct rte_eth_stats, q_opackets)},
+	{"bytes", offsetof(struct rte_eth_stats, q_obytes)},
 };
 #define RTE_NB_TXQ_STATS (sizeof(rte_txq_stats_strings) /	\
 		sizeof(rte_txq_stats_strings[0]))
@@ -1666,8 +1669,6 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 
 	/* Return generic statistics */
 	count = RTE_NB_STATS;
-	count += dev->data->nb_rx_queues * RTE_NB_RXQ_STATS;
-	count += dev->data->nb_tx_queues * RTE_NB_TXQ_STATS;
 
 	/* implemented by the driver */
 	if (dev->dev_ops->xstats_get != NULL) {
@@ -1679,6 +1680,9 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 
 		if (xcount < 0)
 			return xcount;
+	} else {
+		count += dev->data->nb_rx_queues * RTE_NB_RXQ_STATS;
+		count += dev->data->nb_tx_queues * RTE_NB_TXQ_STATS;
 	}
 
 	if (n < count + xcount)
@@ -1698,6 +1702,10 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 		xstats[count++].value = val;
 	}
 
+	/* if xstats_get() is implemented by the PMD, the Q stats are done */
+	if (dev->dev_ops->xstats_get != NULL)
+		return count + xcount;
+
 	/* per-rxq stats */
 	for (q = 0; q < dev->data->nb_rx_queues; q++) {
 		for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
@@ -1706,7 +1714,7 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 					q * sizeof(uint64_t));
 			val = *stats_ptr;
 			snprintf(xstats[count].name, sizeof(xstats[count].name),
-				"rx_queue_%u_%s", q,
+				"rx_q%u_%s", q,
 				rte_rxq_stats_strings[i].name);
 			xstats[count++].value = val;
 		}
@@ -1720,7 +1728,7 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats,
 					q * sizeof(uint64_t));
 			val = *stats_ptr;
 			snprintf(xstats[count].name, sizeof(xstats[count].name),
-				"tx_queue_%u_%s", q,
+				"tx_q%u_%s", q,
 				rte_txq_stats_strings[i].name);
 			xstats[count++].value = val;
 		}
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v5 03/10] virtio: add xstats() implementation
  2015-11-02 10:18           ` [dpdk-dev] [PATCH v5 00/10] Port XStats Harry van Haaren
  2015-11-02 10:18             ` [dpdk-dev] [PATCH v5 01/10] doc: add extended statistics to prog_guide Harry van Haaren
  2015-11-02 10:18             ` [dpdk-dev] [PATCH v5 02/10] ethdev: update xstats_get() strings and Q handling Harry van Haaren
@ 2015-11-02 10:19             ` Harry van Haaren
  2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 04/10] igb: " Harry van Haaren
                               ` (7 subsequent siblings)
  10 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-11-02 10:19 UTC (permalink / raw)
  To: dev

Add xstats() functions and statistic strings to virtio PMD.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/virtio/virtio_ethdev.c | 98 +++++++++++++++++++++++++++++++++++++-
 drivers/net/virtio/virtio_rxtx.c   | 32 +++++++++++++
 drivers/net/virtio/virtqueue.h     |  4 ++
 3 files changed, 132 insertions(+), 2 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 12fcc23..fe5afb9 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -80,7 +80,10 @@ static int virtio_dev_link_update(struct rte_eth_dev *dev,
 static void virtio_set_hwaddr(struct virtio_hw *hw);
 static void virtio_get_hwaddr(struct virtio_hw *hw);
 
-static void virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats);
+static void virtio_dev_stats_get(struct rte_eth_dev *dev,
+				 struct rte_eth_stats *stats);
+static int virtio_dev_xstats_get(struct rte_eth_dev *dev,
+				 struct rte_eth_xstats *xstats, unsigned n);
 static void virtio_dev_stats_reset(struct rte_eth_dev *dev);
 static void virtio_dev_free_mbufs(struct rte_eth_dev *dev);
 static int virtio_vlan_filter_set(struct rte_eth_dev *dev,
@@ -109,6 +112,31 @@ static const struct rte_pci_id pci_id_virtio_map[] = {
 { .vendor_id = 0, /* sentinel */ },
 };
 
+struct rte_virtio_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	unsigned offset;
+};
+
+/* [rt]x_qX_ is prepended to the name string here */
+static const struct rte_virtio_xstats_name_off rte_virtio_q_stat_strings[] = {
+	{"good_packets",           offsetof(struct virtqueue, packets)},
+	{"good_bytes",             offsetof(struct virtqueue, bytes)},
+	{"errors",                 offsetof(struct virtqueue, errors)},
+	{"multicast_packets",      offsetof(struct virtqueue, multicast)},
+	{"broadcast_packets",      offsetof(struct virtqueue, broadcast)},
+	{"undersize_packets",      offsetof(struct virtqueue, size_bins[0])},
+	{"size_64_packets",        offsetof(struct virtqueue, size_bins[1])},
+	{"size_65_127_packets",    offsetof(struct virtqueue, size_bins[2])},
+	{"size_128_255_packets",   offsetof(struct virtqueue, size_bins[3])},
+	{"size_256_511_packets",   offsetof(struct virtqueue, size_bins[4])},
+	{"size_512_1023_packets",  offsetof(struct virtqueue, size_bins[5])},
+	{"size_1024_1517_packets", offsetof(struct virtqueue, size_bins[6])},
+	{"size_1518_max_packets",  offsetof(struct virtqueue, size_bins[7])},
+};
+
+#define VIRTIO_NB_Q_XSTATS (sizeof(rte_virtio_q_stat_strings) / \
+			    sizeof(rte_virtio_q_stat_strings[0]))
+
 static int
 virtio_send_command(struct virtqueue *vq, struct virtio_pmd_ctrl *ctrl,
 		int *dlen, int pkt_num)
@@ -568,7 +596,9 @@ static const struct eth_dev_ops virtio_eth_dev_ops = {
 
 	.dev_infos_get           = virtio_dev_info_get,
 	.stats_get               = virtio_dev_stats_get,
+	.xstats_get              = virtio_dev_xstats_get,
 	.stats_reset             = virtio_dev_stats_reset,
+	.xstats_reset            = virtio_dev_stats_reset,
 	.link_update             = virtio_dev_link_update,
 	.rx_queue_setup          = virtio_dev_rx_queue_setup,
 	.rx_queue_release        = virtio_dev_rx_queue_release,
@@ -623,7 +653,7 @@ virtio_dev_atomic_write_link_status(struct rte_eth_dev *dev,
 }
 
 static void
-virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+virtio_update_stats(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 {
 	unsigned i;
 
@@ -660,6 +690,64 @@ virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed;
 }
 
+static int
+virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		      unsigned n)
+{
+	unsigned i;
+	unsigned count = 0;
+
+	unsigned nstats = dev->data->nb_tx_queues * VIRTIO_NB_Q_XSTATS +
+		dev->data->nb_rx_queues * VIRTIO_NB_Q_XSTATS;
+
+	if (n < nstats)
+		return nstats;
+
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		struct virtqueue *rxvq = dev->data->rx_queues[i];
+
+		if (rxvq == NULL)
+			continue;
+
+		unsigned t;
+
+		for (t = 0; t < VIRTIO_NB_Q_XSTATS; t++) {
+			snprintf(xstats[count].name, sizeof(xstats[count].name),
+				 "rx_q%u_%s", i,
+				 rte_virtio_q_stat_strings[t].name);
+			xstats[count].value = *(uint64_t *)(((char *)rxvq) +
+				rte_virtio_q_stat_strings[t].offset);
+			count++;
+		}
+	}
+
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
+		struct virtqueue *txvq = dev->data->tx_queues[i];
+
+		if (txvq == NULL)
+			continue;
+
+		unsigned t;
+
+		for (t = 0; t < VIRTIO_NB_Q_XSTATS; t++) {
+			snprintf(xstats[count].name, sizeof(xstats[count].name),
+				 "tx_q%u_%s", i,
+				 rte_virtio_q_stat_strings[t].name);
+			xstats[count].value = *(uint64_t *)(((char *)txvq) +
+				rte_virtio_q_stat_strings[t].offset);
+			count++;
+		}
+	}
+
+	return count;
+}
+
+static void
+virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+	virtio_update_stats(dev, stats);
+}
+
 static void
 virtio_dev_stats_reset(struct rte_eth_dev *dev)
 {
@@ -673,6 +761,9 @@ virtio_dev_stats_reset(struct rte_eth_dev *dev)
 		txvq->packets = 0;
 		txvq->bytes = 0;
 		txvq->errors = 0;
+		txvq->multicast = 0;
+		txvq->broadcast = 0;
+		memset(txvq->size_bins, 0, sizeof(txvq->size_bins[0]) * 8);
 	}
 
 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
@@ -683,6 +774,9 @@ virtio_dev_stats_reset(struct rte_eth_dev *dev)
 		rxvq->packets = 0;
 		rxvq->bytes = 0;
 		rxvq->errors = 0;
+		rxvq->multicast = 0;
+		rxvq->broadcast = 0;
+		memset(rxvq->size_bins, 0, sizeof(rxvq->size_bins[0]) * 8);
 	}
 
 	dev->data->rx_mbuf_alloc_failed = 0;
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index d35c5f9..7590485 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -482,6 +482,34 @@ virtio_discard_rxbuf(struct virtqueue *vq, struct rte_mbuf *m)
 	}
 }
 
+static void
+virtio_update_packet_stats(struct virtqueue *vq, struct rte_mbuf *mbuf)
+{
+	uint32_t s = mbuf->pkt_len;
+	struct ether_addr *ea;
+
+	if (s == 64) {
+		vq->size_bins[1]++;
+	} else if (s > 64 && s < 1024) {
+		uint32_t bin;
+
+		/* count zeros, and offset into correct bin */
+		bin = (sizeof(s) * 8) - __builtin_clz(s) - 5;
+		vq->size_bins[bin]++;
+	} else {
+		if (s < 64)
+			vq->size_bins[0]++;
+		else if (s < 1519)
+			vq->size_bins[6]++;
+		else if (s >= 1519)
+			vq->size_bins[7]++;
+	}
+
+	ea = rte_pktmbuf_mtod(mbuf, struct ether_addr *);
+	vq->multicast += is_multicast_ether_addr(ea);
+	vq->broadcast += is_broadcast_ether_addr(ea);
+}
+
 #define VIRTIO_MBUF_BURST_SZ 64
 #define DESC_PER_CACHELINE (RTE_CACHE_LINE_SIZE / sizeof(struct vring_desc))
 uint16_t
@@ -543,7 +571,9 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 		VIRTIO_DUMP_PACKET(rxm, rxm->data_len);
 
 		rx_pkts[nb_rx++] = rxm;
+
 		rxvq->bytes += rx_pkts[nb_rx - 1]->pkt_len;
+		virtio_update_packet_stats(rxvq, rxm);
 	}
 
 	rxvq->packets += nb_rx;
@@ -706,6 +736,7 @@ virtio_recv_mergeable_pkts(void *rx_queue,
 			rx_pkts[nb_rx]->data_len);
 
 		rxvq->bytes += rx_pkts[nb_rx]->pkt_len;
+		virtio_update_packet_stats(rxvq, rx_pkts[nb_rx]);
 		nb_rx++;
 	}
 
@@ -806,6 +837,7 @@ virtio_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 			}
 			nb_tx++;
 			txvq->bytes += txm->pkt_len;
+			virtio_update_packet_stats(txvq, txm);
 		} else {
 			PMD_TX_LOG(ERR, "No free tx descriptors to transmit");
 			break;
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 7789411..9032e6d 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -194,6 +194,10 @@ struct virtqueue {
 	uint64_t	packets;
 	uint64_t	bytes;
 	uint64_t	errors;
+	uint64_t	multicast;
+	uint64_t	broadcast;
+	/* Size bins in array as RFC 2819, undersized [0], 64 [1], etc */
+	uint64_t	size_bins[8];
 
 	struct vq_desc_extra {
 		void              *cookie;
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v5 04/10] igb: add xstats() implementation
  2015-11-02 10:18           ` [dpdk-dev] [PATCH v5 00/10] Port XStats Harry van Haaren
                               ` (2 preceding siblings ...)
  2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 03/10] virtio: add xstats() implementation Harry van Haaren
@ 2015-11-02 10:19             ` Harry van Haaren
  2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 05/10] igbvf: " Harry van Haaren
                               ` (6 subsequent siblings)
  10 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-11-02 10:19 UTC (permalink / raw)
  To: dev

Add xstats_get() and xstats_reset() functions to igb
driver, and the neccessary strings to expose these
NIC statistics.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/e1000/igb_ethdev.c | 135 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 130 insertions(+), 5 deletions(-)

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 3ab082e..a5461e5 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -96,7 +96,10 @@ static int  eth_igb_link_update(struct rte_eth_dev *dev,
 				int wait_to_complete);
 static void eth_igb_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *rte_stats);
+static int eth_igb_xstats_get(struct rte_eth_dev *dev,
+			      struct rte_eth_xstats *xstats, unsigned n);
 static void eth_igb_stats_reset(struct rte_eth_dev *dev);
+static void eth_igb_xstats_reset(struct rte_eth_dev *dev);
 static void eth_igb_infos_get(struct rte_eth_dev *dev,
 			      struct rte_eth_dev_info *dev_info);
 static void eth_igbvf_infos_get(struct rte_eth_dev *dev,
@@ -291,7 +294,9 @@ static const struct eth_dev_ops eth_igb_ops = {
 	.allmulticast_disable = eth_igb_allmulticast_disable,
 	.link_update          = eth_igb_link_update,
 	.stats_get            = eth_igb_stats_get,
+	.xstats_get           = eth_igb_xstats_get,
 	.stats_reset          = eth_igb_stats_reset,
+	.xstats_reset         = eth_igb_xstats_reset,
 	.dev_infos_get        = eth_igb_infos_get,
 	.mtu_set              = eth_igb_mtu_set,
 	.vlan_filter_set      = eth_igb_vlan_filter_set,
@@ -353,6 +358,76 @@ static const struct eth_dev_ops igbvf_eth_dev_ops = {
 	.get_reg              = igbvf_get_regs,
 };
 
+/* store statistics names and its offset in stats structure */
+struct rte_igb_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	unsigned offset;
+};
+
+static const struct rte_igb_xstats_name_off rte_igb_stats_strings[] = {
+	{"rx_crc_errors", offsetof(struct e1000_hw_stats, crcerrs)},
+	{"rx_align_errors", offsetof(struct e1000_hw_stats, algnerrc)},
+	{"rx_symbol_errors", offsetof(struct e1000_hw_stats, symerrs)},
+	{"rx_missed_packets", offsetof(struct e1000_hw_stats, mpc)},
+	{"tx_single_collision_packets", offsetof(struct e1000_hw_stats, scc)},
+	{"tx_multiple_collision_packets", offsetof(struct e1000_hw_stats, mcc)},
+	{"tx_excessive_collision_packets", offsetof(struct e1000_hw_stats,
+		ecol)},
+	{"tx_late_collisions", offsetof(struct e1000_hw_stats, latecol)},
+	{"tx_total_collisions", offsetof(struct e1000_hw_stats, colc)},
+	{"tx_deferred_packets", offsetof(struct e1000_hw_stats, dc)},
+	{"tx_no_carrier_sense_packets", offsetof(struct e1000_hw_stats, tncrs)},
+	{"rx_carrier_ext_errors", offsetof(struct e1000_hw_stats, cexterr)},
+	{"rx_length_errors", offsetof(struct e1000_hw_stats, rlec)},
+	{"rx_xon_packets", offsetof(struct e1000_hw_stats, xonrxc)},
+	{"tx_xon_packets", offsetof(struct e1000_hw_stats, xontxc)},
+	{"rx_xoff_packets", offsetof(struct e1000_hw_stats, xoffrxc)},
+	{"tx_xoff_packets", offsetof(struct e1000_hw_stats, xofftxc)},
+	{"rx_flow_control_unsupported_packets", offsetof(struct e1000_hw_stats,
+		fcruc)},
+	{"rx_size_64_packets", offsetof(struct e1000_hw_stats, prc64)},
+	{"rx_size_65_to_127_packets", offsetof(struct e1000_hw_stats, prc127)},
+	{"rx_size_128_to_255_packets", offsetof(struct e1000_hw_stats, prc255)},
+	{"rx_size_256_to_511_packets", offsetof(struct e1000_hw_stats, prc511)},
+	{"rx_size_512_to_1023_packets", offsetof(struct e1000_hw_stats,
+		prc1023)},
+	{"rx_size_1024_to_max_packets", offsetof(struct e1000_hw_stats,
+		prc1522)},
+	{"rx_broadcast_packets", offsetof(struct e1000_hw_stats, bprc)},
+	{"rx_multicast_packets", offsetof(struct e1000_hw_stats, mprc)},
+	{"rx_undersize_errors", offsetof(struct e1000_hw_stats, ruc)},
+	{"rx_fragment_errors", offsetof(struct e1000_hw_stats, rfc)},
+	{"rx_oversize_errors", offsetof(struct e1000_hw_stats, roc)},
+	{"rx_jabber_errors", offsetof(struct e1000_hw_stats, rjc)},
+	{"rx_management_packets", offsetof(struct e1000_hw_stats, mgprc)},
+	{"rx_management_dropped", offsetof(struct e1000_hw_stats, mgpdc)},
+	{"tx_management_packets", offsetof(struct e1000_hw_stats, mgptc)},
+	{"rx_total_packets", offsetof(struct e1000_hw_stats, tpr)},
+	{"tx_total_packets", offsetof(struct e1000_hw_stats, tpt)},
+	{"rx_total_bytes", offsetof(struct e1000_hw_stats, tor)},
+	{"tx_total_bytes", offsetof(struct e1000_hw_stats, tot)},
+	{"tx_size_64_packets", offsetof(struct e1000_hw_stats, ptc64)},
+	{"tx_size_65_to_127_packets", offsetof(struct e1000_hw_stats, ptc127)},
+	{"tx_size_128_to_255_packets", offsetof(struct e1000_hw_stats, ptc255)},
+	{"tx_size_256_to_511_packets", offsetof(struct e1000_hw_stats, ptc511)},
+	{"tx_size_512_to_1023_packets", offsetof(struct e1000_hw_stats,
+		ptc1023)},
+	{"tx_size_1023_to_max_packets", offsetof(struct e1000_hw_stats,
+		ptc1522)},
+	{"tx_multicast_packets", offsetof(struct e1000_hw_stats, mptc)},
+	{"tx_broadcast_packets", offsetof(struct e1000_hw_stats, bptc)},
+	{"tx_tso_packets", offsetof(struct e1000_hw_stats, tsctc)},
+	{"tx_tso_errors", offsetof(struct e1000_hw_stats, tsctfc)},
+	{"rx_sent_to_host_packets", offsetof(struct e1000_hw_stats, rpthc)},
+	{"tx_sent_by_host_packets", offsetof(struct e1000_hw_stats, hgptc)},
+	{"rx_code_violation_packets", offsetof(struct e1000_hw_stats, scvpc)},
+
+	{"interrupt_assert_count", offsetof(struct e1000_hw_stats, iac)},
+};
+
+#define IGB_NB_XSTATS (sizeof(rte_igb_stats_strings) / \
+		sizeof(rte_igb_stats_strings[0]))
+
 /**
  * Atomically reads the link status information from global
  * structure rte_eth_dev.
@@ -1256,11 +1331,8 @@ igb_hardware_init(struct e1000_hw *hw)
 
 /* This function is based on igb_update_stats_counters() in igb/if_igb.c */
 static void
-eth_igb_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
+igb_read_stats_registers(struct e1000_hw *hw, struct e1000_hw_stats *stats)
 {
-	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	struct e1000_hw_stats *stats =
-			E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
 	int pause_frames;
 
 	if(hw->phy.media_type == e1000_media_type_copper ||
@@ -1366,6 +1438,16 @@ eth_igb_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
 	stats->cexterr += E1000_READ_REG(hw, E1000_CEXTERR);
 	stats->tsctc += E1000_READ_REG(hw, E1000_TSCTC);
 	stats->tsctfc += E1000_READ_REG(hw, E1000_TSCTFC);
+}
+
+static void
+eth_igb_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_hw_stats *stats =
+			E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+
+	igb_read_stats_registers(hw, stats);
 
 	if (rte_stats == NULL)
 		return;
@@ -1408,6 +1490,50 @@ eth_igb_stats_reset(struct rte_eth_dev *dev)
 }
 
 static void
+eth_igb_xstats_reset(struct rte_eth_dev *dev)
+{
+	struct e1000_hw_stats *stats =
+			E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+
+	/* HW registers are cleared on read */
+	eth_igb_xstats_get(dev, NULL, IGB_NB_XSTATS);
+
+	/* Reset software totals */
+	memset(stats, 0, sizeof(*stats));
+}
+
+static int
+eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		   unsigned n)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_hw_stats *hw_stats =
+			E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+	unsigned i;
+
+	if (n < IGB_NB_XSTATS)
+		return IGB_NB_XSTATS;
+
+	igb_read_stats_registers(hw, hw_stats);
+
+	/* If this is a reset xstats is NULL, and we have cleared the
+	 * registers by reading them.
+	 */
+	if (!xstats)
+		return 0;
+
+	/* Extended stats */
+	for (i = 0; i < IGB_NB_XSTATS; i++) {
+		snprintf(xstats[i].name, sizeof(xstats[i].name),
+			 "%s", rte_igb_stats_strings[i].name);
+		xstats[i].value = *(uint64_t *)(((char *)hw_stats) +
+			rte_igb_stats_strings[i].offset);
+	}
+
+	return IGB_NB_XSTATS;
+}
+
+static void
 eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
@@ -1462,7 +1588,6 @@ eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
 	rte_stats->ilbbytes = hw_stats->gorlbc;
 	rte_stats->olbpackets = hw_stats->gptlbc;
 	rte_stats->olbbytes = hw_stats->gotlbc;
-
 }
 
 static void
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v5 05/10] igbvf: add xstats() implementation
  2015-11-02 10:18           ` [dpdk-dev] [PATCH v5 00/10] Port XStats Harry van Haaren
                               ` (3 preceding siblings ...)
  2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 04/10] igb: " Harry van Haaren
@ 2015-11-02 10:19             ` Harry van Haaren
  2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 06/10] ixgbe: add extended statistic strings Harry van Haaren
                               ` (5 subsequent siblings)
  10 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-11-02 10:19 UTC (permalink / raw)
  To: dev

Add xstats functionality to igbvf PMD, adding
necessary statistic strings.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/e1000/igb_ethdev.c | 62 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 55 insertions(+), 7 deletions(-)

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index a5461e5..e57d436 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -152,7 +152,10 @@ static int igbvf_dev_start(struct rte_eth_dev *dev);
 static void igbvf_dev_stop(struct rte_eth_dev *dev);
 static void igbvf_dev_close(struct rte_eth_dev *dev);
 static int eth_igbvf_link_update(struct e1000_hw *hw);
-static void eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats);
+static void eth_igbvf_stats_get(struct rte_eth_dev *dev,
+				struct rte_eth_stats *rte_stats);
+static int eth_igbvf_xstats_get(struct rte_eth_dev *dev,
+				struct rte_eth_xstats *xstats, unsigned n);
 static void eth_igbvf_stats_reset(struct rte_eth_dev *dev);
 static int igbvf_vlan_filter_set(struct rte_eth_dev *dev,
 		uint16_t vlan_id, int on);
@@ -345,7 +348,9 @@ static const struct eth_dev_ops igbvf_eth_dev_ops = {
 	.dev_close            = igbvf_dev_close,
 	.link_update          = eth_igb_link_update,
 	.stats_get            = eth_igbvf_stats_get,
+	.xstats_get           = eth_igbvf_xstats_get,
 	.stats_reset          = eth_igbvf_stats_reset,
+	.xstats_reset         = eth_igbvf_stats_reset,
 	.vlan_filter_set      = igbvf_vlan_filter_set,
 	.dev_infos_get        = eth_igbvf_infos_get,
 	.rx_queue_setup       = eth_igb_rx_queue_setup,
@@ -428,6 +433,17 @@ static const struct rte_igb_xstats_name_off rte_igb_stats_strings[] = {
 #define IGB_NB_XSTATS (sizeof(rte_igb_stats_strings) / \
 		sizeof(rte_igb_stats_strings[0]))
 
+static const struct rte_igb_xstats_name_off rte_igbvf_stats_strings[] = {
+	{"rx_multicast_packets", offsetof(struct e1000_vf_stats, mprc)},
+	{"rx_good_loopback_packets", offsetof(struct e1000_vf_stats, gprlbc)},
+	{"tx_good_loopback_packets", offsetof(struct e1000_vf_stats, gptlbc)},
+	{"rx_good_loopback_bytes", offsetof(struct e1000_vf_stats, gorlbc)},
+	{"tx_good_loopback_bytes", offsetof(struct e1000_vf_stats, gotlbc)},
+};
+
+#define IGBVF_NB_XSTATS (sizeof(rte_igbvf_stats_strings) / \
+		sizeof(rte_igbvf_stats_strings[0]))
+
 /**
  * Atomically reads the link status information from global
  * structure rte_eth_dev.
@@ -1534,12 +1550,8 @@ eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
 }
 
 static void
-eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
+igbvf_read_stats_registers(struct e1000_hw *hw, struct e1000_vf_stats *hw_stats)
 {
-	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	struct e1000_vf_stats *hw_stats = (struct e1000_vf_stats*)
-			  E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
-
 	/* Good Rx packets, include VF loopback */
 	UPDATE_VF_STAT(E1000_VFGPRC,
 	    hw_stats->last_gprc, hw_stats->gprc);
@@ -1575,6 +1587,43 @@ eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
 	/* Good Tx loopback octets */
 	UPDATE_VF_STAT(E1000_VFGOTLBC,
 	    hw_stats->last_gotlbc, hw_stats->gotlbc);
+}
+
+static int
+eth_igbvf_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		     unsigned n)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_vf_stats *hw_stats = (struct e1000_vf_stats *)
+			E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+	unsigned i;
+
+	if (n < IGBVF_NB_XSTATS)
+		return IGBVF_NB_XSTATS;
+
+	igbvf_read_stats_registers(hw, hw_stats);
+
+	if (!xstats)
+		return 0;
+
+	for (i = 0; i < IGBVF_NB_XSTATS; i++) {
+		snprintf(xstats[i].name, sizeof(xstats[i].name), "%s",
+			 rte_igbvf_stats_strings[i].name);
+		xstats[i].value = *(uint64_t *)(((char *)hw_stats) +
+			rte_igbvf_stats_strings[i].offset);
+	}
+
+	return IGBVF_NB_XSTATS;
+}
+
+static void
+eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_vf_stats *hw_stats = (struct e1000_vf_stats *)
+			  E1000_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+
+	igbvf_read_stats_registers(hw, hw_stats);
 
 	if (rte_stats == NULL)
 		return;
@@ -1602,7 +1651,6 @@ eth_igbvf_stats_reset(struct rte_eth_dev *dev)
 	/* reset HW current stats*/
 	memset(&hw_stats->gprc, 0, sizeof(*hw_stats) -
 	       offsetof(struct e1000_vf_stats, gprc));
-
 }
 
 static void
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v5 06/10] ixgbe: add extended statistic strings
  2015-11-02 10:18           ` [dpdk-dev] [PATCH v5 00/10] Port XStats Harry van Haaren
                               ` (4 preceding siblings ...)
  2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 05/10] igbvf: " Harry van Haaren
@ 2015-11-02 10:19             ` Harry van Haaren
  2015-11-02 22:31               ` Thomas Monjalon
  2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 07/10] ixgbevf: add xstats() implementation Harry van Haaren
                               ` (4 subsequent siblings)
  10 siblings, 1 reply; 77+ messages in thread
From: Harry van Haaren @ 2015-11-02 10:19 UTC (permalink / raw)
  To: dev

Added and updated statistic strings as used by xstats_get(),
exposed extended queue statistics.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 203 +++++++++++++++++++++++++++++++++------
 1 file changed, 172 insertions(+), 31 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 4373661..c657955 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -510,33 +510,95 @@ struct rte_ixgbe_xstats_name_off {
 };
 
 static const struct rte_ixgbe_xstats_name_off rte_ixgbe_stats_strings[] = {
-	{"rx_illegal_byte_err", offsetof(struct ixgbe_hw_stats, errbc)},
-	{"rx_len_err", offsetof(struct ixgbe_hw_stats, rlec)},
-	{"rx_undersize_count", offsetof(struct ixgbe_hw_stats, ruc)},
-	{"rx_oversize_count", offsetof(struct ixgbe_hw_stats, roc)},
-	{"rx_fragment_count", offsetof(struct ixgbe_hw_stats, rfc)},
-	{"rx_jabber_count", offsetof(struct ixgbe_hw_stats, rjc)},
-	{"l3_l4_xsum_error", offsetof(struct ixgbe_hw_stats, xec)},
-	{"mac_local_fault", offsetof(struct ixgbe_hw_stats, mlfc)},
-	{"mac_remote_fault", offsetof(struct ixgbe_hw_stats, mrfc)},
-	{"mac_short_pkt_discard", offsetof(struct ixgbe_hw_stats, mspdc)},
-	{"fccrc_error", offsetof(struct ixgbe_hw_stats, fccrc)},
-	{"fcoe_drop", offsetof(struct ixgbe_hw_stats, fcoerpdc)},
-	{"fc_last_error", offsetof(struct ixgbe_hw_stats, fclast)},
-	{"rx_broadcast_packets", offsetof(struct ixgbe_hw_stats, bprc)},
-	{"rx_phy_multicast_packets", offsetof(struct ixgbe_hw_stats, mprc)},
-	{"mgmt_pkts_dropped", offsetof(struct ixgbe_hw_stats, mngpdc)},
 	{"rx_crc_errors", offsetof(struct ixgbe_hw_stats, crcerrs)},
-	{"fdir_match", offsetof(struct ixgbe_hw_stats, fdirmatch)},
-	{"fdir_miss", offsetof(struct ixgbe_hw_stats, fdirmiss)},
-	{"tx_flow_control_xon", offsetof(struct ixgbe_hw_stats, lxontxc)},
-	{"rx_flow_control_xon", offsetof(struct ixgbe_hw_stats, lxonrxc)},
-	{"tx_flow_control_xoff", offsetof(struct ixgbe_hw_stats, lxofftxc)},
-	{"rx_flow_control_xoff", offsetof(struct ixgbe_hw_stats, lxoffrxc)},
+	{"rx_illegal_byte_errors", offsetof(struct ixgbe_hw_stats, illerrc)},
+	{"rx_error_bytes", offsetof(struct ixgbe_hw_stats, errbc)},
+	{"mac_local_errors", offsetof(struct ixgbe_hw_stats, mlfc)},
+	{"mac_remote_errors", offsetof(struct ixgbe_hw_stats, mrfc)},
+	{"rx_length_errors", offsetof(struct ixgbe_hw_stats, rlec)},
+	{"tx_xon_packets", offsetof(struct ixgbe_hw_stats, lxontxc)},
+	{"rx_xon_packets", offsetof(struct ixgbe_hw_stats, lxonrxc)},
+	{"tx_xoff_packets", offsetof(struct ixgbe_hw_stats, lxofftxc)},
+	{"rx_xoff_packets", offsetof(struct ixgbe_hw_stats, lxoffrxc)},
+	{"rx_size_64_packets", offsetof(struct ixgbe_hw_stats, prc64)},
+	{"rx_size_65_to_127_packets", offsetof(struct ixgbe_hw_stats, prc127)},
+	{"rx_size_128_to_255_packets", offsetof(struct ixgbe_hw_stats, prc255)},
+	{"rx_size_256_to_511_packets", offsetof(struct ixgbe_hw_stats, prc511)},
+	{"rx_size_512_to_1023_packets", offsetof(struct ixgbe_hw_stats,
+		prc1023)},
+	{"rx_size_1024_to_max_packets", offsetof(struct ixgbe_hw_stats,
+		prc1522)},
+	{"rx_broadcast_packets", offsetof(struct ixgbe_hw_stats, bprc)},
+	{"rx_multicast_packets", offsetof(struct ixgbe_hw_stats, mprc)},
+	{"rx_fragment_errors", offsetof(struct ixgbe_hw_stats, rfc)},
+	{"rx_undersize_errors", offsetof(struct ixgbe_hw_stats, ruc)},
+	{"rx_oversize_errors", offsetof(struct ixgbe_hw_stats, roc)},
+	{"rx_jabber_errors", offsetof(struct ixgbe_hw_stats, rjc)},
+	{"rx_managment_packets", offsetof(struct ixgbe_hw_stats, mngprc)},
+	{"rx_managment_dropped", offsetof(struct ixgbe_hw_stats, mngpdc)},
+	{"tx_managment_packets", offsetof(struct ixgbe_hw_stats, mngptc)},
+	{"rx_total_packets", offsetof(struct ixgbe_hw_stats, tpr)},
+	{"rx_total_bytes", offsetof(struct ixgbe_hw_stats, tor)},
+	{"tx_total_packets", offsetof(struct ixgbe_hw_stats, tpt)},
+	{"tx_size_64_packets", offsetof(struct ixgbe_hw_stats, ptc64)},
+	{"tx_size_65_to_127_packets", offsetof(struct ixgbe_hw_stats, ptc127)},
+	{"tx_size_128_to_255_packets", offsetof(struct ixgbe_hw_stats, ptc255)},
+	{"tx_size_256_to_511_packets", offsetof(struct ixgbe_hw_stats, ptc511)},
+	{"tx_size_512_to_1023_packets", offsetof(struct ixgbe_hw_stats,
+		ptc1023)},
+	{"tx_size_1024_to_max_packets", offsetof(struct ixgbe_hw_stats,
+		ptc1522)},
+	{"tx_multicast_packets", offsetof(struct ixgbe_hw_stats, mptc)},
+	{"tx_broadcast_packets", offsetof(struct ixgbe_hw_stats, bptc)},
+	{"rx_mac_short_packet_dropped", offsetof(struct ixgbe_hw_stats, mspdc)},
+	{"rx_l3_l4_xsum_error", offsetof(struct ixgbe_hw_stats, xec)},
+
+	{"flow_director_added_filters", offsetof(struct ixgbe_hw_stats,
+		fdirustat_add)},
+	{"flow_director_removed_filters", offsetof(struct ixgbe_hw_stats,
+		fdirustat_remove)},
+	{"flow_director_filter_add_errors", offsetof(struct ixgbe_hw_stats,
+		fdirfstat_fadd)},
+	{"flow_director_filter_remove_errors", offsetof(struct ixgbe_hw_stats,
+		fdirfstat_fremove)},
+	{"flow_director_matched_filters", offsetof(struct ixgbe_hw_stats,
+		fdirmatch)},
+	{"flow_director_missed_filters", offsetof(struct ixgbe_hw_stats,
+		fdirmiss)},
+
+	{"rx_fcoe_crc_errors", offsetof(struct ixgbe_hw_stats, fccrc)},
+	{"rx_fcoe_dropped", offsetof(struct ixgbe_hw_stats, fcoerpdc)},
+	{"rx_fcoe_mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats,
+		fclast)},
+	{"rx_fcoe_packets", offsetof(struct ixgbe_hw_stats, fcoeprc)},
+	{"tx_fcoe_packets", offsetof(struct ixgbe_hw_stats, fcoeptc)},
+	{"rx_fcoe_bytes", offsetof(struct ixgbe_hw_stats, fcoedwrc)},
+	{"tx_fcoe_bytes", offsetof(struct ixgbe_hw_stats, fcoedwtc)},
+	{"rx_fcoe_no_direct_data_placement", offsetof(struct ixgbe_hw_stats,
+		fcoe_noddp)},
+	{"rx_fcoe_no_direct_data_placement_ext_buff",
+		offsetof(struct ixgbe_hw_stats, fcoe_noddp_ext_buff)},
+
+	{"tx_flow_control_xon_packets", offsetof(struct ixgbe_hw_stats,
+		lxontxc)},
+	{"rx_flow_control_xon_packets", offsetof(struct ixgbe_hw_stats,
+		lxonrxc)},
+	{"tx_flow_control_xoff_packets", offsetof(struct ixgbe_hw_stats,
+		lxofftxc)},
+	{"rx_flow_control_xoff_packets", offsetof(struct ixgbe_hw_stats,
+		lxoffrxc)},
+	{"rx_total_missed_packets", offsetof(struct ixgbe_hw_stats, mpctotal)},
 };
 
-#define IXGBE_NB_XSTATS (sizeof(rte_ixgbe_stats_strings) /	\
-		sizeof(rte_ixgbe_stats_strings[0]))
+#define IXGBE_NB_HW_STATS (sizeof(rte_ixgbe_stats_strings) / \
+			   sizeof(rte_ixgbe_stats_strings[0]))
+
+/* Per-queue statistics */
+#define IXBGE_NB_8_PER_Q_STATS (8 * 7)
+#define IXBGE_NB_16_PER_Q_STATS (16 * 5)
+#define IXGBE_NB_Q_STATS (IXBGE_NB_8_PER_Q_STATS + IXBGE_NB_16_PER_Q_STATS)
+
+#define IXGBE_NB_XSTATS (IXGBE_NB_HW_STATS + IXGBE_NB_Q_STATS)
 
 /**
  * Atomically reads the link status information from global
@@ -2257,7 +2319,7 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
 	total_qprdc = 0;
 
 	ixgbe_read_stats_registers(hw, hw_stats, &total_missed_rx, &total_qbrc,
-							   &total_qprc, &total_qprdc);
+				   &total_qprc, &total_qprdc);
 
 	/* If this is a reset xstats is NULL, and we have cleared the
 	 * registers by reading them.
@@ -2265,12 +2327,91 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
 	if (!xstats)
 		return 0;
 
-	/* Extended stats */
-	for (i = 0; i < IXGBE_NB_XSTATS; i++) {
-		snprintf(xstats[i].name, sizeof(xstats[i].name),
-				"%s", rte_ixgbe_stats_strings[i].name);
-		xstats[i].value = *(uint64_t *)(((char *)hw_stats) +
-							rte_ixgbe_stats_strings[i].offset);
+	/* Extended stats from ixgbe_hw_stats */
+	count = 0;
+	for (i = 0; i < IXGBE_NB_HW_STATS; i++) {
+		snprintf(xstats[count].name, sizeof(xstats[count].name), "%s",
+			 rte_ixgbe_stats_strings[i].name);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				rte_ixgbe_stats_strings[i].offset);
+		count++;
+	}
+
+	/* Per-Q stats, with 8 queues available */
+	for (i = 0; i < 8; i++) {
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "rx_q%u_mbuf_allocation_errors", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, rnbc[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "rx_q%u_missed_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, mpc[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "rx_q%u_xon_priority_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, pxonrxc[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "tx_q%u_xon_priority_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, pxontxc[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "rx_q%u_xoff_priority_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, pxoffrxc[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "tx_q%u_xoff_priority_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, pxofftxc[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "xx_q%u_xon_to_xoff_priority_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, pxon2offc[i]));
+		count++;
+	}
+
+	for (i = 0; i < 16; i++) {
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "rx_q%u_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, qprc[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "rx_q%u_bytes", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, qbrc[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "tx_q%u_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, qptc[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "tx_q%u_bytes", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, qbtc[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "rx_q%u_dropped", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct ixgbe_hw_stats, qprdc[i]));
+		count++;
 	}
 
 	return count;
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v5 07/10] ixgbevf: add xstats() implementation
  2015-11-02 10:18           ` [dpdk-dev] [PATCH v5 00/10] Port XStats Harry van Haaren
                               ` (5 preceding siblings ...)
  2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 06/10] ixgbe: add extended statistic strings Harry van Haaren
@ 2015-11-02 10:19             ` Harry van Haaren
  2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 08/10] i40e: " Harry van Haaren
                               ` (3 subsequent siblings)
  10 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-11-02 10:19 UTC (permalink / raw)
  To: dev

Add xstats() functions and stat strings as necessary to ixgbevf PMD.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 49 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index c657955..0a6288a 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -149,6 +149,8 @@ static void ixgbe_dev_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *stats);
 static int ixgbe_dev_xstats_get(struct rte_eth_dev *dev,
 				struct rte_eth_xstats *xstats, unsigned n);
+static int ixgbevf_dev_xstats_get(struct rte_eth_dev *dev,
+				  struct rte_eth_xstats *xstats, unsigned n);
 static void ixgbe_dev_stats_reset(struct rte_eth_dev *dev);
 static void ixgbe_dev_xstats_reset(struct rte_eth_dev *dev);
 static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
@@ -477,7 +479,9 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
 	.dev_stop             = ixgbevf_dev_stop,
 	.link_update          = ixgbe_dev_link_update,
 	.stats_get            = ixgbevf_dev_stats_get,
+	.xstats_get           = ixgbevf_dev_xstats_get,
 	.stats_reset          = ixgbevf_dev_stats_reset,
+	.xstats_reset         = ixgbevf_dev_stats_reset,
 	.dev_close            = ixgbevf_dev_close,
 	.dev_infos_get        = ixgbevf_dev_info_get,
 	.mtu_set              = ixgbevf_dev_set_mtu,
@@ -600,6 +604,13 @@ static const struct rte_ixgbe_xstats_name_off rte_ixgbe_stats_strings[] = {
 
 #define IXGBE_NB_XSTATS (IXGBE_NB_HW_STATS + IXGBE_NB_Q_STATS)
 
+static const struct rte_ixgbe_xstats_name_off rte_ixgbevf_stats_strings[] = {
+	{"rx_multicast_packets", offsetof(struct ixgbevf_hw_stats, vfmprc)},
+};
+
+#define IXGBEVF_NB_XSTATS (sizeof(rte_ixgbevf_stats_strings) /	\
+		sizeof(rte_ixgbevf_stats_strings[0]))
+
 /**
  * Atomically reads the link status information from global
  * structure rte_eth_dev.
@@ -2431,7 +2442,7 @@ ixgbe_dev_xstats_reset(struct rte_eth_dev *dev)
 }
 
 static void
-ixgbevf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+ixgbevf_update_stats(struct rte_eth_dev *dev)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct ixgbevf_hw_stats *hw_stats = (struct ixgbevf_hw_stats*)
@@ -2456,6 +2467,42 @@ ixgbevf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	/* Rx Multicst Packet */
 	UPDATE_VF_STAT(IXGBE_VFMPRC,
 	    hw_stats->last_vfmprc, hw_stats->vfmprc);
+}
+
+static int
+ixgbevf_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		       unsigned n)
+{
+	struct ixgbevf_hw_stats *hw_stats = (struct ixgbevf_hw_stats *)
+			IXGBE_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+	unsigned i;
+
+	if (n < IXGBEVF_NB_XSTATS)
+		return IXGBEVF_NB_XSTATS;
+
+	ixgbevf_update_stats(dev);
+
+	if (!xstats)
+		return 0;
+
+	/* Extended stats */
+	for (i = 0; i < IXGBEVF_NB_XSTATS; i++) {
+		snprintf(xstats[i].name, sizeof(xstats[i].name),
+			 "%s", rte_ixgbevf_stats_strings[i].name);
+		xstats[i].value = *(uint64_t *)(((char *)hw_stats) +
+			rte_ixgbevf_stats_strings[i].offset);
+	}
+
+	return IXGBEVF_NB_XSTATS;
+}
+
+static void
+ixgbevf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+	struct ixgbevf_hw_stats *hw_stats = (struct ixgbevf_hw_stats *)
+			  IXGBE_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+
+	ixgbevf_update_stats(dev);
 
 	if (stats == NULL)
 		return;
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v5 08/10] i40e: add xstats() implementation
  2015-11-02 10:18           ` [dpdk-dev] [PATCH v5 00/10] Port XStats Harry van Haaren
                               ` (6 preceding siblings ...)
  2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 07/10] ixgbevf: add xstats() implementation Harry van Haaren
@ 2015-11-02 10:19             ` Harry van Haaren
  2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 09/10] i40evf: " Harry van Haaren
                               ` (2 subsequent siblings)
  10 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-11-02 10:19 UTC (permalink / raw)
  To: dev

Add xstats functions to i40e PMD, allowing extended statistics
to be retrieved from the NIC and exposed to the DPDK.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 215 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 209 insertions(+), 6 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 2dd9fdc..089d414 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -127,7 +127,10 @@ static int i40e_dev_set_link_up(struct rte_eth_dev *dev);
 static int i40e_dev_set_link_down(struct rte_eth_dev *dev);
 static void i40e_dev_stats_get(struct rte_eth_dev *dev,
 			       struct rte_eth_stats *stats);
+static int i40e_dev_xstats_get(struct rte_eth_dev *dev,
+			       struct rte_eth_xstats *xstats, unsigned n);
 static void i40e_dev_stats_reset(struct rte_eth_dev *dev);
+static void i40e_dev_xstats_reset(struct rte_eth_dev *dev);
 static int i40e_dev_queue_stats_mapping_set(struct rte_eth_dev *dev,
 					    uint16_t queue_id,
 					    uint8_t stat_idx,
@@ -232,6 +235,8 @@ static int i40e_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
 					   uint32_t flags);
 static int i40e_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
 					   struct timespec *timestamp);
+static void i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw);
+
 
 static const struct rte_pci_id pci_id_i40e_map[] = {
 #define RTE_PCI_DEV_ID_DECL_I40E(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
@@ -252,7 +257,9 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
 	.dev_set_link_down            = i40e_dev_set_link_down,
 	.link_update                  = i40e_dev_link_update,
 	.stats_get                    = i40e_dev_stats_get,
+	.xstats_get                   = i40e_dev_xstats_get,
 	.stats_reset                  = i40e_dev_stats_reset,
+	.xstats_reset                 = i40e_dev_xstats_reset,
 	.queue_stats_mapping_set      = i40e_dev_queue_stats_mapping_set,
 	.dev_infos_get                = i40e_dev_info_get,
 	.vlan_filter_set              = i40e_vlan_filter_set,
@@ -291,6 +298,101 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
 	.timesync_read_tx_timestamp   = i40e_timesync_read_tx_timestamp,
 };
 
+/* store statistics names and its offset in stats structure */
+struct rte_i40e_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	unsigned offset;
+};
+
+static const struct rte_i40e_xstats_name_off rte_i40e_stats_strings[] = {
+	{"rx_unicast_packets", offsetof(struct i40e_eth_stats, rx_unicast)},
+	{"rx_multicast_packets", offsetof(struct i40e_eth_stats, rx_multicast)},
+	{"rx_broadcast_packets", offsetof(struct i40e_eth_stats, rx_broadcast)},
+	{"rx_dropped", offsetof(struct i40e_eth_stats, rx_discards)},
+	{"rx_unknown_protocol_packets", offsetof(struct i40e_eth_stats,
+		rx_unknown_protocol)},
+	{"tx_unicast_packets", offsetof(struct i40e_eth_stats, tx_unicast)},
+	{"tx_multicast_packets", offsetof(struct i40e_eth_stats, tx_multicast)},
+	{"tx_broadcast_packets", offsetof(struct i40e_eth_stats, tx_broadcast)},
+	{"tx_dropped", offsetof(struct i40e_eth_stats, tx_discards)},
+};
+
+static const struct rte_i40e_xstats_name_off rte_i40e_hw_port_strings[] = {
+	{"tx_link_down_dropped", offsetof(struct i40e_hw_port_stats,
+		tx_dropped_link_down)},
+	{"rx_crc_errors", offsetof(struct i40e_hw_port_stats, crc_errors)},
+	{"rx_illegal_byte_errors", offsetof(struct i40e_hw_port_stats,
+		illegal_bytes)},
+	{"rx_error_bytes", offsetof(struct i40e_hw_port_stats, error_bytes)},
+	{"mac_local_errors", offsetof(struct i40e_hw_port_stats,
+		mac_local_faults)},
+	{"mac_remote_errors", offsetof(struct i40e_hw_port_stats,
+		mac_remote_faults)},
+	{"rx_length_errors", offsetof(struct i40e_hw_port_stats,
+		rx_length_errors)},
+	{"tx_xon_packets", offsetof(struct i40e_hw_port_stats, link_xon_tx)},
+	{"rx_xon_packets", offsetof(struct i40e_hw_port_stats, link_xon_rx)},
+	{"tx_xoff_packets", offsetof(struct i40e_hw_port_stats, link_xoff_tx)},
+	{"rx_xoff_packets", offsetof(struct i40e_hw_port_stats, link_xoff_rx)},
+	{"rx_size_64_packets", offsetof(struct i40e_hw_port_stats, rx_size_64)},
+	{"rx_size_65_to_127_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_127)},
+	{"rx_size_128_to_255_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_255)},
+	{"rx_size_256_to_511_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_511)},
+	{"rx_size_512_to_1023_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_1023)},
+	{"rx_size_1024_to_1522_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_1522)},
+	{"rx_size_1523_to_max_packets", offsetof(struct i40e_hw_port_stats,
+		rx_size_big)},
+	{"rx_undersized_errors", offsetof(struct i40e_hw_port_stats,
+		rx_undersize)},
+	{"rx_oversize_errors", offsetof(struct i40e_hw_port_stats,
+		rx_oversize)},
+	{"rx_mac_short_dropped", offsetof(struct i40e_hw_port_stats,
+		mac_short_packet_dropped)},
+	{"rx_fragmented_errors", offsetof(struct i40e_hw_port_stats,
+		rx_fragments)},
+	{"rx_jabber_errors", offsetof(struct i40e_hw_port_stats, rx_jabber)},
+	{"tx_size_64_packets", offsetof(struct i40e_hw_port_stats, tx_size_64)},
+	{"tx_size_65_to_127_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_127)},
+	{"tx_size_128_to_255_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_255)},
+	{"tx_size_256_to_511_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_511)},
+	{"tx_size_512_to_1023_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_1023)},
+	{"tx_size_1024_to_1522_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_1522)},
+	{"tx_size_1523_to_max_packets", offsetof(struct i40e_hw_port_stats,
+		tx_size_big)},
+	{"rx_flow_director_atr_match_packets",
+		offsetof(struct i40e_hw_port_stats, fd_atr_match)},
+	{"rx_flow_director_sb_match_packets",
+		offsetof(struct i40e_hw_port_stats, fd_sb_match)},
+	{"tx_low_power_idle_status", offsetof(struct i40e_hw_port_stats,
+		tx_lpi_status)},
+	{"rx_low_power_idle_status", offsetof(struct i40e_hw_port_stats,
+		rx_lpi_status)},
+	{"tx_low_power_idle_count", offsetof(struct i40e_hw_port_stats,
+		tx_lpi_count)},
+	{"rx_low_power_idle_count", offsetof(struct i40e_hw_port_stats,
+		rx_lpi_count)},
+};
+
+/* Q Stats: 5 stats are exposed for each queue, implemented in xstats_get() */
+#define I40E_NB_HW_PORT_Q_STATS (8 * 5)
+
+#define I40E_NB_ETH_XSTATS (sizeof(rte_i40e_stats_strings) / \
+		sizeof(rte_i40e_stats_strings[0]))
+#define I40E_NB_HW_PORT_XSTATS (sizeof(rte_i40e_hw_port_strings) / \
+		sizeof(rte_i40e_hw_port_strings[0]))
+#define I40E_NB_XSTATS (I40E_NB_ETH_XSTATS + I40E_NB_HW_PORT_XSTATS + \
+		I40E_NB_HW_PORT_Q_STATS)
+
 static struct eth_driver rte_i40e_pmd = {
 	.pci_drv = {
 		.name = "rte_i40e_pmd",
@@ -1322,16 +1424,12 @@ i40e_update_vsi_stats(struct i40e_vsi *vsi)
 		    vsi->vsi_id);
 }
 
-/* Get all statistics of a port */
 static void
-i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw)
 {
-	uint32_t i;
-	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
-	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	unsigned int i;
 	struct i40e_hw_port_stats *ns = &pf->stats; /* new stats */
 	struct i40e_hw_port_stats *os = &pf->stats_offset; /* old stats */
-
 	/* Get statistics of struct i40e_eth_stats */
 	i40e_stat_update_48(hw, I40E_GLPRT_GORCH(hw->port),
 			    I40E_GLPRT_GORCL(hw->port),
@@ -1510,6 +1608,19 @@ i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 
 	if (pf->main_vsi)
 		i40e_update_vsi_stats(pf->main_vsi);
+}
+
+/* Get all statistics of a port */
+static void
+i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct i40e_hw_port_stats *ns = &pf->stats; /* new stats */
+	unsigned i;
+
+	/* call read registers - updates values, now write them to struct */
+	i40e_read_stats_registers(pf, hw);
 
 	stats->ipackets = ns->eth.rx_unicast + ns->eth.rx_multicast +
 						ns->eth.rx_broadcast;
@@ -1599,6 +1710,98 @@ i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	PMD_DRV_LOG(DEBUG, "***************** PF stats end ********************");
 }
 
+static void
+i40e_dev_xstats_reset(struct rte_eth_dev *dev)
+{
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct i40e_hw_port_stats *hw_stats = &pf->stats;
+
+	/* The hw registers are cleared on read */
+	pf->offset_loaded = false;
+	i40e_read_stats_registers(pf, hw);
+
+	/* reset software counters */
+	memset(hw_stats, 0, sizeof(*hw_stats));
+}
+
+static int
+i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		    unsigned n)
+{
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	unsigned i, count = 0;
+	struct i40e_hw_port_stats *hw_stats = &pf->stats;
+
+	if (n < I40E_NB_XSTATS)
+		return I40E_NB_XSTATS;
+
+	i40e_read_stats_registers(pf, hw);
+
+	/* Reset */
+	if (xstats == NULL)
+		return 0;
+
+	/* Get stats from i40e_eth_stats struct */
+	for (i = 0; i < I40E_NB_ETH_XSTATS; i++) {
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "%s", rte_i40e_stats_strings[i].name);
+		xstats[count].value = *(uint64_t *)(((char *)&hw_stats->eth) +
+			rte_i40e_stats_strings[i].offset);
+		count++;
+	}
+
+	/* Get individiual stats from i40e_hw_port struct */
+	for (i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) {
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "%s", rte_i40e_hw_port_strings[i].name);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				rte_i40e_hw_port_strings[i].offset);
+		count++;
+	}
+
+	/* Get per-queue stats from i40e_hw_port struct */
+	for (i = 0; i < 8; i++) {
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "rx_q%u_xon_priority_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct i40e_hw_port_stats,
+					 priority_xon_rx[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "rx_q%u_xoff_priority_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct i40e_hw_port_stats,
+					 priority_xoff_rx[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "tx_q%u_xon_priority_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct i40e_hw_port_stats,
+					 priority_xon_tx[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "tx_q%u_xoff_priority_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct i40e_hw_port_stats,
+					 priority_xoff_tx[i]));
+		count++;
+
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "xx_q%u_xon_to_xoff_priority_packets", i);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+				offsetof(struct i40e_hw_port_stats,
+					 priority_xon_2_xoff[i]));
+		count++;
+	}
+
+	return I40E_NB_XSTATS;
+}
+
 /* Reset the statistics */
 static void
 i40e_dev_stats_reset(struct rte_eth_dev *dev)
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v5 09/10] i40evf: add xstats() implementation
  2015-11-02 10:18           ` [dpdk-dev] [PATCH v5 00/10] Port XStats Harry van Haaren
                               ` (7 preceding siblings ...)
  2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 08/10] i40e: " Harry van Haaren
@ 2015-11-02 10:19             ` Harry van Haaren
  2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 10/10] fm10k: " Harry van Haaren
  2015-11-02 10:24             ` [dpdk-dev] [PATCH v5 00/10] Port XStats Van Haaren, Harry
  10 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-11-02 10:19 UTC (permalink / raw)
  To: dev

Add implementation of xstats() functions in i40evf PMD.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/i40e/i40e_ethdev_vf.c | 89 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 86 insertions(+), 3 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index b694400..24153fb 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -112,6 +112,9 @@ static int i40evf_dev_link_update(struct rte_eth_dev *dev,
 				  __rte_unused int wait_to_complete);
 static void i40evf_dev_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *stats);
+static int i40evf_dev_xstats_get(struct rte_eth_dev *dev,
+				 struct rte_eth_xstats *xstats, unsigned n);
+static void i40evf_dev_xstats_reset(struct rte_eth_dev *dev);
 static int i40evf_vlan_filter_set(struct rte_eth_dev *dev,
 				  uint16_t vlan_id, int on);
 static void i40evf_vlan_offload_set(struct rte_eth_dev *dev, int mask);
@@ -148,6 +151,30 @@ static int i40evf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 /* Default hash key buffer for RSS */
 static uint32_t rss_key_default[I40E_VFQF_HKEY_MAX_INDEX + 1];
 
+struct rte_i40evf_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	unsigned offset;
+};
+
+static const struct rte_i40evf_xstats_name_off rte_i40evf_stats_strings[] = {
+	{"rx_bytes", offsetof(struct i40e_eth_stats, rx_bytes)},
+	{"rx_unicast_packets", offsetof(struct i40e_eth_stats, rx_unicast)},
+	{"rx_multicast_packets", offsetof(struct i40e_eth_stats, rx_multicast)},
+	{"rx_broadcast_packets", offsetof(struct i40e_eth_stats, rx_broadcast)},
+	{"rx_dropped_packets", offsetof(struct i40e_eth_stats, rx_discards)},
+	{"rx_unknown_protocol_packets", offsetof(struct i40e_eth_stats,
+		rx_unknown_protocol)},
+	{"tx_bytes", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_unicast_packets", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_multicast_packets", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_broadcast_packets", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_dropped_packets", offsetof(struct i40e_eth_stats, tx_bytes)},
+	{"tx_error_packets", offsetof(struct i40e_eth_stats, tx_bytes)},
+};
+
+#define I40EVF_NB_XSTATS (sizeof(rte_i40evf_stats_strings) / \
+		sizeof(rte_i40evf_stats_strings[0]))
+
 static const struct eth_dev_ops i40evf_eth_dev_ops = {
 	.dev_configure        = i40evf_dev_configure,
 	.dev_start            = i40evf_dev_start,
@@ -158,6 +185,8 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = {
 	.allmulticast_disable = i40evf_dev_allmulticast_disable,
 	.link_update          = i40evf_dev_link_update,
 	.stats_get            = i40evf_dev_stats_get,
+	.xstats_get           = i40evf_dev_xstats_get,
+	.xstats_reset         = i40evf_dev_xstats_reset,
 	.dev_close            = i40evf_dev_close,
 	.dev_infos_get        = i40evf_dev_info_get,
 	.vlan_filter_set      = i40evf_vlan_filter_set,
@@ -888,11 +917,10 @@ i40evf_del_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr)
 }
 
 static int
-i40evf_get_statics(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+i40evf_update_stats(struct rte_eth_dev *dev, struct i40e_eth_stats **pstats)
 {
 	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 	struct i40e_virtchnl_queue_select q_stats;
-	struct i40e_eth_stats *pstats;
 	int err;
 	struct vf_cmd_info args;
 
@@ -907,9 +935,23 @@ i40evf_get_statics(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	err = i40evf_execute_vf_cmd(dev, &args);
 	if (err) {
 		PMD_DRV_LOG(ERR, "fail to execute command OP_GET_STATS");
+		*pstats = NULL;
 		return err;
 	}
-	pstats = (struct i40e_eth_stats *)args.out_buffer;
+	*pstats = (struct i40e_eth_stats *)args.out_buffer;
+	return 0;
+}
+
+static int
+i40evf_get_statics(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+	int ret;
+	struct i40e_eth_stats *pstats = NULL;
+
+	ret = i40evf_update_stats(dev, &pstats);
+	if (ret != 0)
+		return 0;
+
 	stats->ipackets = pstats->rx_unicast + pstats->rx_multicast +
 						pstats->rx_broadcast;
 	stats->opackets = pstats->tx_broadcast + pstats->tx_multicast +
@@ -922,6 +964,47 @@ i40evf_get_statics(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 	return 0;
 }
 
+static void
+i40evf_dev_xstats_reset(struct rte_eth_dev *dev)
+{
+	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+	struct i40e_eth_stats *pstats = NULL;
+
+	/* read stat values to clear hardware registers */
+	i40evf_update_stats(dev, &pstats);
+
+	/* set stats offset base on current values */
+	vf->vsi.eth_stats_offset = vf->vsi.eth_stats;
+}
+
+static int i40evf_dev_xstats_get(struct rte_eth_dev *dev,
+				 struct rte_eth_xstats *xstats, unsigned n)
+{
+	int ret;
+	unsigned i;
+	struct i40e_eth_stats *pstats = NULL;
+
+	if (n < I40EVF_NB_XSTATS)
+		return I40EVF_NB_XSTATS;
+
+	ret = i40evf_update_stats(dev, &pstats);
+	if (ret != 0)
+		return 0;
+
+	if (!xstats)
+		return 0;
+
+	/* loop over xstats array and values from pstats */
+	for (i = 0; i < I40EVF_NB_XSTATS; i++) {
+		snprintf(xstats[i].name, sizeof(xstats[i].name),
+			 "%s", rte_i40evf_stats_strings[i].name);
+		xstats[i].value = *(uint64_t *)(((char *)pstats) +
+			rte_i40evf_stats_strings[i].offset);
+	}
+
+	return I40EVF_NB_XSTATS;
+}
+
 static int
 i40evf_add_vlan(struct rte_eth_dev *dev, uint16_t vlanid)
 {
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* [dpdk-dev] [PATCH v5 10/10] fm10k: add xstats() implementation
  2015-11-02 10:18           ` [dpdk-dev] [PATCH v5 00/10] Port XStats Harry van Haaren
                               ` (8 preceding siblings ...)
  2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 09/10] i40evf: " Harry van Haaren
@ 2015-11-02 10:19             ` Harry van Haaren
  2015-11-02 10:24             ` [dpdk-dev] [PATCH v5 00/10] Port XStats Van Haaren, Harry
  10 siblings, 0 replies; 77+ messages in thread
From: Harry van Haaren @ 2015-11-02 10:19 UTC (permalink / raw)
  To: dev

Add xstats() functions and statistic strings.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
---
 drivers/net/fm10k/fm10k_ethdev.c | 87 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 87 insertions(+)

diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index b104fc2..13ca098 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -68,6 +68,46 @@ fm10k_MACVLAN_remove_all(struct rte_eth_dev *dev);
 static void fm10k_tx_queue_release(void *queue);
 static void fm10k_rx_queue_release(void *queue);
 
+struct fm10k_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	unsigned offset;
+};
+
+struct fm10k_xstats_name_off fm10k_hw_stats_strings[] = {
+	{"completion_timeout_count", offsetof(struct fm10k_hw_stats, timeout)},
+	{"unsupported_requests_count", offsetof(struct fm10k_hw_stats, ur)},
+	{"completer_abort_count", offsetof(struct fm10k_hw_stats, ca)},
+	{"unsupported_message_count", offsetof(struct fm10k_hw_stats, um)},
+	{"checksum_error_count", offsetof(struct fm10k_hw_stats, xec)},
+	{"vlan_dropped", offsetof(struct fm10k_hw_stats, vlan_drop)},
+	{"loopback_dropped", offsetof(struct fm10k_hw_stats, loopback_drop)},
+	{"rx_mbuf_allocation_errors", offsetof(struct fm10k_hw_stats,
+		nodesc_drop)},
+};
+
+#define FM10K_NB_HW_XSTATS (sizeof(fm10k_hw_stats_strings) / \
+		sizeof(fm10k_hw_stats_strings[0]))
+
+struct fm10k_xstats_name_off fm10k_hw_stats_rx_q_strings[] = {
+	{"packets", offsetof(struct fm10k_hw_stats_q, rx_packets)},
+	{"bytes", offsetof(struct fm10k_hw_stats_q, rx_bytes)},
+	{"dropped", offsetof(struct fm10k_hw_stats_q, rx_drops)},
+};
+
+#define FM10K_NB_RX_Q_XSTATS (sizeof(fm10k_hw_stats_rx_q_strings) / \
+		sizeof(fm10k_hw_stats_rx_q_strings[0]))
+
+struct fm10k_xstats_name_off fm10k_hw_stats_tx_q_strings[] = {
+	{"packets", offsetof(struct fm10k_hw_stats_q, tx_packets)},
+	{"bytes", offsetof(struct fm10k_hw_stats_q, tx_bytes)},
+};
+
+#define FM10K_NB_TX_Q_XSTATS (sizeof(fm10k_hw_stats_tx_q_strings) / \
+		sizeof(fm10k_hw_stats_tx_q_strings[0]))
+
+#define FM10K_NB_XSTATS (FM10K_NB_HW_XSTATS + FM10K_MAX_QUEUES_PF * \
+		(FM10K_NB_RX_Q_XSTATS + FM10K_NB_TX_Q_XSTATS))
+
 static void
 fm10k_mbx_initlock(struct fm10k_hw *hw)
 {
@@ -867,6 +907,51 @@ fm10k_link_update(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static int
+fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats,
+		 unsigned n)
+{
+	struct fm10k_hw_stats *hw_stats =
+		FM10K_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+	unsigned i, q, count = 0;
+
+	if (n < FM10K_NB_XSTATS)
+		return FM10K_NB_XSTATS;
+
+	/* Global stats */
+	for (i = 0; i < FM10K_NB_HW_XSTATS; i++) {
+		snprintf(xstats[count].name, sizeof(xstats[count].name),
+			 "%s", fm10k_hw_stats_strings[count].name);
+		xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+			fm10k_hw_stats_strings[count].offset);
+		count++;
+	}
+
+	/* PF queue stats */
+	for (q = 0; q < FM10K_MAX_QUEUES_PF; q++) {
+		for (i = 0; i < FM10K_NB_RX_Q_XSTATS; i++) {
+			snprintf(xstats[count].name, sizeof(xstats[count].name),
+				 "rx_q%u_%s", q,
+				 fm10k_hw_stats_rx_q_strings[i].name);
+			xstats[count].value =
+				*(uint64_t *)(((char *)&hw_stats->q[q]) +
+				fm10k_hw_stats_rx_q_strings[i].offset);
+			count++;
+		}
+		for (i = 0; i < FM10K_NB_TX_Q_XSTATS; i++) {
+			snprintf(xstats[count].name, sizeof(xstats[count].name),
+				 "tx_q%u_%s", q,
+				 fm10k_hw_stats_tx_q_strings[i].name);
+			xstats[count].value =
+				*(uint64_t *)(((char *)&hw_stats->q[q]) +
+				fm10k_hw_stats_tx_q_strings[i].offset);
+			count++;
+		}
+	}
+
+	return FM10K_NB_XSTATS;
+}
+
 static void
 fm10k_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 {
@@ -2035,7 +2120,9 @@ static const struct eth_dev_ops fm10k_eth_dev_ops = {
 	.allmulticast_enable    = fm10k_dev_allmulticast_enable,
 	.allmulticast_disable   = fm10k_dev_allmulticast_disable,
 	.stats_get		= fm10k_stats_get,
+	.xstats_get		= fm10k_xstats_get,
 	.stats_reset		= fm10k_stats_reset,
+	.xstats_reset		= fm10k_stats_reset,
 	.link_update		= fm10k_link_update,
 	.dev_infos_get		= fm10k_dev_infos_get,
 	.vlan_filter_set	= fm10k_vlan_filter_set,
-- 
1.9.1

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v5 00/10] Port XStats
  2015-11-02 10:18           ` [dpdk-dev] [PATCH v5 00/10] Port XStats Harry van Haaren
                               ` (9 preceding siblings ...)
  2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 10/10] fm10k: " Harry van Haaren
@ 2015-11-02 10:24             ` Van Haaren, Harry
  2015-11-02 23:23               ` Thomas Monjalon
  10 siblings, 1 reply; 77+ messages in thread
From: Van Haaren, Harry @ 2015-11-02 10:24 UTC (permalink / raw)
  To: dev

> Subject: [PATCH v5 00/10] Port XStats

Series-acked-by: Maryam Tahhan <maryam.tahhan@intel.com>

Same code as previous v4, same Ack. Will include in commit message in future.
-Harry

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v4 02/10] ethdev: update xstats_get() strings and Q handling
  2015-11-02 10:17             ` Van Haaren, Harry
@ 2015-11-02 16:23               ` Thomas Monjalon
  0 siblings, 0 replies; 77+ messages in thread
From: Thomas Monjalon @ 2015-11-02 16:23 UTC (permalink / raw)
  To: Van Haaren, Harry; +Cc: dev

2015-11-02 10:17, Van Haaren, Harry:
> > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > Sent: Monday, November 2, 2015 7:59 AM
> > > +       /* if xstats_get() is implemented by the PMD, the Q stats are done */
> > > +       if (dev->dev_ops->xstats_get != NULL)
> > > +               return count + xcount;
> > > +
> > >         /* per-rxq stats */
> > >         for (q = 0; q < dev->data->nb_rx_queues; q++) {
> > >                 for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
> > 
> > Please could you explain why the generic per-queue stats are not used when
> > xstats is implemented in the driver?
> 
> Each PMD exposes its own queue stats so it has the flexibility of presenting them exactly has the hardware counts, in a human-readable order.
> 
> If the generic xstats were used, testpmd> xstats output would split a single queue's xstats to two places in the list. As stats are used during debugging, readability and clarity of the stats is vital in my opinion.

Output control is the role of testpmd, not the driver.
I think you can reorder the stats in testpmd given that you have defined
a clear scheme naming (thanks).

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v5 06/10] ixgbe: add extended statistic strings
  2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 06/10] ixgbe: add extended statistic strings Harry van Haaren
@ 2015-11-02 22:31               ` Thomas Monjalon
  0 siblings, 0 replies; 77+ messages in thread
From: Thomas Monjalon @ 2015-11-02 22:31 UTC (permalink / raw)
  To: Harry van Haaren; +Cc: dev

2015-11-02 10:19, Harry van Haaren:
> +       {"rx_managment_packets", offsetof(struct ixgbe_hw_stats, mngprc)},
> +       {"rx_managment_dropped", offsetof(struct ixgbe_hw_stats, mngpdc)},
> +       {"tx_managment_packets", offsetof(struct ixgbe_hw_stats, mngptc)},

Looks to be a typo. Management?

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: [dpdk-dev] [PATCH v5 00/10] Port XStats
  2015-11-02 10:24             ` [dpdk-dev] [PATCH v5 00/10] Port XStats Van Haaren, Harry
@ 2015-11-02 23:23               ` Thomas Monjalon
  0 siblings, 0 replies; 77+ messages in thread
From: Thomas Monjalon @ 2015-11-02 23:23 UTC (permalink / raw)
  To: Van Haaren, Harry; +Cc: dev

2015-11-02 10:24, Van Haaren, Harry:
> > Subject: [PATCH v5 00/10] Port XStats
> 
> Series-acked-by: Maryam Tahhan <maryam.tahhan@intel.com>

Applied with some typo fixes, thanks

I'm still not sure about the queue stats handling but it can be fixed
later if more people disagree with your choice.

^ permalink raw reply	[flat|nested] 77+ messages in thread

end of thread, other threads:[~2015-11-02 23:24 UTC | newest]

Thread overview: 77+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-30  9:40 [dpdk-dev] [PATCH v2 00/11] Port XStats Harry van Haaren
2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 01/11] doc: add extended statistics notes Harry van Haaren
2015-10-22 15:48   ` [dpdk-dev] [PATCH v3 00/11] Port XStats Harry van Haaren
2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 01/11] doc: add extended statistics notes Harry van Haaren
2015-10-30 11:36       ` [dpdk-dev] [PATCH v4 00/10] Port XStats Harry van Haaren
2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 01/10] doc: add extended statistics to prog_guide Harry van Haaren
2015-11-02 10:18           ` [dpdk-dev] [PATCH v5 00/10] Port XStats Harry van Haaren
2015-11-02 10:18             ` [dpdk-dev] [PATCH v5 01/10] doc: add extended statistics to prog_guide Harry van Haaren
2015-11-02 10:18             ` [dpdk-dev] [PATCH v5 02/10] ethdev: update xstats_get() strings and Q handling Harry van Haaren
2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 03/10] virtio: add xstats() implementation Harry van Haaren
2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 04/10] igb: " Harry van Haaren
2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 05/10] igbvf: " Harry van Haaren
2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 06/10] ixgbe: add extended statistic strings Harry van Haaren
2015-11-02 22:31               ` Thomas Monjalon
2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 07/10] ixgbevf: add xstats() implementation Harry van Haaren
2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 08/10] i40e: " Harry van Haaren
2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 09/10] i40evf: " Harry van Haaren
2015-11-02 10:19             ` [dpdk-dev] [PATCH v5 10/10] fm10k: " Harry van Haaren
2015-11-02 10:24             ` [dpdk-dev] [PATCH v5 00/10] Port XStats Van Haaren, Harry
2015-11-02 23:23               ` Thomas Monjalon
2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 02/10] ethdev: update xstats_get() strings and Q handling Harry van Haaren
2015-11-02  7:59           ` Thomas Monjalon
2015-11-02 10:17             ` Van Haaren, Harry
2015-11-02 16:23               ` Thomas Monjalon
2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 03/10] virtio: add xstats() implementation Harry van Haaren
2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 04/10] igb: " Harry van Haaren
2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 05/10] igbvf: " Harry van Haaren
2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 06/10] ixgbe: add extended statistic strings Harry van Haaren
2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 07/10] ixgbevf: add xstats() implementation Harry van Haaren
2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 08/10] i40e: " Harry van Haaren
2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 09/10] i40evf: " Harry van Haaren
2015-10-30 11:36         ` [dpdk-dev] [PATCH v4 10/10] fm10k: " Harry van Haaren
2015-10-30 13:21         ` [dpdk-dev] [PATCH v4 00/10] Port XStats Tahhan, Maryam
2015-11-02  8:04         ` Thomas Monjalon
2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 02/11] doc: add extended statistics to prog_guide Harry van Haaren
2015-10-23 14:29       ` Tahhan, Maryam
2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 03/11] ethdev: update xstats_get() strings and Q handling Harry van Haaren
2015-10-23 14:35       ` Tahhan, Maryam
2015-10-23 15:28         ` Tahhan, Maryam
2015-10-23 15:28       ` Tahhan, Maryam
2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 04/11] virtio: add xstats() implementation Harry van Haaren
2015-10-29 16:19       ` Tahhan, Maryam
2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 05/11] igb: " Harry van Haaren
2015-10-23 14:56       ` Tahhan, Maryam
2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 06/11] igbvf: " Harry van Haaren
2015-10-28 12:17       ` Tahhan, Maryam
2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 07/11] ixgbe: update statistic strings to scheme Harry van Haaren
2015-10-23 14:41       ` Tahhan, Maryam
2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 08/11] ixgbevf: add xstats() functions to VF Harry van Haaren
2015-10-28 12:16       ` Tahhan, Maryam
2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 09/11] i40e: add xstats() implementation Harry van Haaren
2015-10-23 15:11       ` Tahhan, Maryam
2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 10/11] i40evf: " Harry van Haaren
2015-10-28 12:15       ` Tahhan, Maryam
2015-10-22 15:48     ` [dpdk-dev] [PATCH v3 11/11] fm10k: " Harry van Haaren
2015-10-29 16:41       ` Tahhan, Maryam
2015-10-28 17:35     ` [dpdk-dev] [PATCH v3 00/11] Port XStats Tom Crugnale
2015-10-28 21:32       ` Stephen Hemminger
2015-10-29  0:55         ` Tom Crugnale
2015-10-29 12:55           ` Kyle Larose
2015-10-29 13:10             ` Thomas Monjalon
2015-10-29 13:57               ` Kyle Larose
2015-10-29 14:01                 ` Thomas Monjalon
2015-10-29 14:10                   ` Kyle Larose
2015-10-29 13:17             ` Van Haaren, Harry
2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 02/11] doc: add extended statistics to prog_guide Harry van Haaren
2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 03/11] ethdev: update xstats_get() strings and Q handling Harry van Haaren
2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 04/11] virtio: add xstats() implementation Harry van Haaren
2015-09-30 17:44   ` Stephen Hemminger
2015-10-01  8:00     ` Van Haaren, Harry
2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 05/11] igb: " Harry van Haaren
2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 06/11] igbvf: " Harry van Haaren
2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 07/11] ixgbe: update statistic strings to scheme Harry van Haaren
2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 08/11] ixgbevf: add xstats() functions to VF Harry van Haaren
2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 09/11] i40e: add xstats() implementation Harry van Haaren
2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 10/11] i40evf: " Harry van Haaren
2015-09-30  9:40 ` [dpdk-dev] [PATCH v2 11/11] fm10k: " Harry van Haaren

DPDK patches and discussions

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://inbox.dpdk.org/dev/0 dev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 dev dev/ https://inbox.dpdk.org/dev \
		dev@dpdk.org
	public-inbox-index dev

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.dpdk.org/inbox.dpdk.dev


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git