* [dpdk-dev] [PATCH 1/4] ethdev: add retrieving xstats by group and xstats by name
2017-03-03 12:54 [dpdk-dev] [PATCH 0/4] extend API to retriving xstats by group and xstats by name Kuba Kozak
@ 2017-03-03 12:54 ` Kuba Kozak
2017-03-06 10:17 ` Thomas Monjalon
2017-03-03 12:54 ` [dpdk-dev] [PATCH 2/4] net/e1000: add grouping of xstats for e1000 driver Kuba Kozak
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: Kuba Kozak @ 2017-03-03 12:54 UTC (permalink / raw)
To: dev; +Cc: Jacek Piasecki, Kuba Kozak
From: Jacek Piasecki <jacekx.piasecki@intel.com>
This patch extends library for retriving xstats by specified groups and
single xstat by given name.
Signed-off-by: Jacek Piasecki <jacekx.piasecki@intel.com>
Signed-off-by: Kuba Kozak <kubax.kozak@intel.com>
---
lib/librte_ether/rte_ethdev.c | 310 ++++++++++++++++++++++++++++++++++++++++--
lib/librte_ether/rte_ethdev.h | 105 +++++++++++++-
2 files changed, 401 insertions(+), 14 deletions(-)
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index eb0a94a..aad8913 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -87,33 +87,37 @@
struct rte_eth_xstats_name_off {
char name[RTE_ETH_XSTATS_NAME_SIZE];
unsigned offset;
+ uint64_t group_mask;
};
static const struct rte_eth_xstats_name_off rte_stats_strings[] = {
- {"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)},
- {"tx_errors", offsetof(struct rte_eth_stats, oerrors)},
+ {"rx_good_packets", offsetof(struct rte_eth_stats, ipackets), RX_GROUP},
+ {"tx_good_packets", offsetof(struct rte_eth_stats, opackets), TX_GROUP},
+ {"rx_good_bytes", offsetof(struct rte_eth_stats, ibytes), RX_GROUP},
+ {"tx_good_bytes", offsetof(struct rte_eth_stats, obytes), TX_GROUP},
+ {"rx_errors", offsetof(struct rte_eth_stats, ierrors),
+ RX_GROUP | ERR_GROUP},
+ {"tx_errors", offsetof(struct rte_eth_stats, oerrors),
+ TX_GROUP | ERR_GROUP},
{"rx_mbuf_allocation_errors", offsetof(struct rte_eth_stats,
- rx_nombuf)},
+ rx_nombuf), RX_GROUP | ERR_GROUP},
};
#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[] = {
- {"packets", offsetof(struct rte_eth_stats, q_ipackets)},
- {"bytes", offsetof(struct rte_eth_stats, q_ibytes)},
- {"errors", offsetof(struct rte_eth_stats, q_errors)},
+ {"packets", offsetof(struct rte_eth_stats, q_ipackets), RXQ_GROUP},
+ {"bytes", offsetof(struct rte_eth_stats, q_ibytes), RXQ_GROUP},
+ {"errors", offsetof(struct rte_eth_stats, q_errors),
+ RXQ_GROUP | ERR_GROUP},
};
#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[] = {
- {"packets", offsetof(struct rte_eth_stats, q_opackets)},
- {"bytes", offsetof(struct rte_eth_stats, q_obytes)},
+ {"packets", offsetof(struct rte_eth_stats, q_opackets), TXQ_GROUP},
+ {"bytes", offsetof(struct rte_eth_stats, q_obytes), TXQ_GROUP},
};
#define RTE_NB_TXQ_STATS (sizeof(rte_txq_stats_strings) / \
sizeof(rte_txq_stats_strings[0]))
@@ -1448,6 +1452,110 @@ struct rte_eth_dev *
return count;
}
+static int
+get_xstats_count_by_group(uint8_t port_id, uint64_t group_mask)
+{
+ struct rte_eth_dev *dev;
+ int count = 0;
+ int dcount = 0;
+ unsigned int i;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
+ dev = &rte_eth_devices[port_id];
+ if (dev->dev_ops->xstats_get_names_by_group != NULL) {
+ dcount = (*dev->dev_ops->xstats_get_names_by_group)
+ (dev, NULL, 0, group_mask);
+ if (dcount < 0)
+ return dcount;
+ }
+
+
+
+
+ for (i = 0; i < RTE_NB_STATS; i++) {
+ if (rte_stats_strings[i].group_mask & group_mask)
+ count++;
+ }
+ for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
+ if (rte_rxq_stats_strings[i].group_mask & group_mask)
+ count += RTE_MIN(dev->data->nb_rx_queues,
+ RTE_ETHDEV_QUEUE_STAT_CNTRS);
+ }
+ for (i = 0; i < RTE_NB_TXQ_STATS; i++) {
+ if (rte_txq_stats_strings[i].group_mask & group_mask)
+ count += RTE_MIN(dev->data->nb_tx_queues,
+ RTE_ETHDEV_QUEUE_STAT_CNTRS);
+ }
+ return count+dcount;
+}
+
+int
+rte_eth_xstats_get_by_name(uint8_t port_id, struct rte_eth_xstat *xstat,
+ const char *name)
+{
+ struct rte_eth_xstat *xstats;
+ int cnt_xstats, idx_xstat;
+ struct rte_eth_xstat_name *xstats_names;
+
+
+
+ /* Get count */
+ cnt_xstats = rte_eth_xstats_get_names(port_id, NULL, 0);
+ if (cnt_xstats < 0) {
+ printf("Error: Cannot get count of xstats\n");
+ return -1;
+ }
+
+ /* Get id-name lookup table */
+ xstats_names = malloc(sizeof(struct rte_eth_xstat_name) * cnt_xstats);
+ if (xstats_names == NULL) {
+ printf("Cannot allocate memory for xstats lookup\n");
+ return -1;
+ }
+ if (cnt_xstats != rte_eth_xstats_get_names(
+ port_id, xstats_names, cnt_xstats)) {
+ printf("Error: Cannot get xstats lookup\n");
+ free(xstats_names);
+ return -1;
+ }
+
+ /* Get stats themselves */
+ xstats = malloc(sizeof(struct rte_eth_xstat) * cnt_xstats);
+ if (xstats == NULL) {
+ printf("Cannot allocate memory for xstats\n");
+ free(xstats_names);
+ return -1;
+ }
+
+ if (cnt_xstats != rte_eth_xstats_get(port_id, xstats, cnt_xstats)) {
+ printf("Error: Unable to get xstats\n");
+ free(xstats_names);
+ free(xstats);
+ return -1;
+ }
+
+ if (!xstat) {
+ printf("Error: xstat pointer is NULL\n");
+ free(xstats_names);
+ free(xstats);
+ return -1;
+ }
+
+ /* Display xstats */
+ for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++) {
+ if (!strcmp(xstats_names[idx_xstat].name, name)) {
+
+ xstat->id = xstats[idx_xstat].id;
+ xstat->value = xstats[idx_xstat].value;
+ return 0;
+ };
+ }
+
+ free(xstats_names);
+ free(xstats);
+ return -1;
+}
+
int
rte_eth_xstats_get_names(uint8_t port_id,
struct rte_eth_xstat_name *xstats_names,
@@ -1513,6 +1621,83 @@ struct rte_eth_dev *
return cnt_used_entries;
}
+int
+rte_eth_xstats_get_names_by_group(uint8_t port_id,
+ struct rte_eth_xstat_name *xstats_names,
+ unsigned int size, __rte_unused uint64_t group_mask)
+{
+ struct rte_eth_dev *dev;
+ int cnt_used_entries;
+ int cnt_expected_entries;
+ int cnt_driver_entries;
+ uint32_t idx, id_queue;
+ uint16_t num_q;
+
+ cnt_expected_entries = get_xstats_count_by_group(port_id, group_mask);
+ if (xstats_names == NULL || cnt_expected_entries < 0 ||
+ (int)size < cnt_expected_entries)
+ return cnt_expected_entries;
+
+ /* port_id checked in get_xstats_count() */
+ dev = &rte_eth_devices[port_id];
+ cnt_used_entries = 0;
+
+ for (idx = 0; idx < RTE_NB_STATS; idx++) {
+ if (rte_stats_strings[idx].group_mask & group_mask) {
+ snprintf(xstats_names[cnt_used_entries].name,
+ sizeof(xstats_names[0].name),
+ "%s", rte_stats_strings[idx].name);
+ cnt_used_entries++;
+ }
+ }
+ num_q = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
+ for (id_queue = 0; id_queue < num_q; id_queue++) {
+ for (idx = 0; idx < RTE_NB_RXQ_STATS; idx++) {
+ if (rte_rxq_stats_strings[idx].group_mask &
+ group_mask) {
+ snprintf(xstats_names[cnt_used_entries].name,
+ sizeof(xstats_names[0].name),
+ "rx_q%u%s",
+ id_queue,
+ rte_rxq_stats_strings[idx].name);
+ cnt_used_entries++;
+ }
+ }
+ }
+ num_q = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
+ for (id_queue = 0; id_queue < num_q; id_queue++) {
+ for (idx = 0; idx < RTE_NB_TXQ_STATS; idx++) {
+ if (rte_txq_stats_strings[idx].group_mask &
+ group_mask) {
+ snprintf(xstats_names[cnt_used_entries].name,
+ sizeof(xstats_names[0].name),
+ "tx_q%u%s",
+ id_queue,
+ rte_txq_stats_strings[idx].name);
+ cnt_used_entries++;
+ }
+
+ }
+ }
+
+ if (dev->dev_ops->xstats_get_names != NULL) {
+ /* If there are any driver-specific xstats, append them
+ * to end of list.
+ */
+ cnt_driver_entries =
+ (*dev->dev_ops->xstats_get_names_by_group)(
+ dev,
+ xstats_names + cnt_used_entries,
+ size - cnt_used_entries,
+ group_mask);
+ if (cnt_driver_entries < 0)
+ return cnt_driver_entries;
+ cnt_used_entries += cnt_driver_entries;
+ }
+
+ return cnt_used_entries;
+}
+
/* retrieve ethdev extended statistics */
int
rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstat *xstats,
@@ -1595,6 +1780,104 @@ struct rte_eth_dev *
return count + xcount;
}
+/* retrieve ethdev extended statistics */
+int
+rte_eth_xstats_get_by_group(uint8_t port_id, struct rte_eth_xstat *xstats,
+ unsigned int n, uint64_t group_mask)
+{
+ struct rte_eth_stats eth_stats;
+ struct rte_eth_dev *dev;
+ unsigned int count = 0, i, q;
+ signed int xcount = 0;
+ uint64_t val, *stats_ptr;
+ uint16_t nb_rxqs, nb_txqs;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
+
+ dev = &rte_eth_devices[port_id];
+
+ nb_rxqs = RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
+ nb_txqs = RTE_MIN(dev->data->nb_tx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS);
+
+ for (i = 0; i < RTE_NB_STATS; i++) {
+ if (rte_stats_strings[i].group_mask & group_mask)
+ count++;
+ }
+ for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
+ if (rte_rxq_stats_strings[i].group_mask & group_mask)
+ count += nb_rxqs;
+ }
+ for (i = 0; i < RTE_NB_TXQ_STATS; i++) {
+ if (rte_txq_stats_strings[i].group_mask & group_mask)
+ count += nb_txqs;
+ }
+
+ /* implemented by the driver */
+ if (dev->dev_ops->xstats_get_by_group != NULL) {
+ /* Retrieve the xstats from the driver at the end of the
+ * xstats struct.
+ */
+ xcount = (*dev->dev_ops->xstats_get_by_group)(dev,
+ xstats ? xstats + count : NULL,
+ (n > count) ? n - count : 0,
+ group_mask);
+
+ if (xcount < 0)
+ return xcount;
+ }
+
+ if (n < count + xcount || xstats == NULL)
+ return count + xcount;
+
+ /* now fill the xstats structure */
+ count = 0;
+ rte_eth_stats_get(port_id, ð_stats);
+
+ /* global stats */
+ for (i = 0; i < RTE_NB_STATS; i++) {
+ if (rte_stats_strings[i].group_mask & group_mask) {
+ stats_ptr = RTE_PTR_ADD(ð_stats,
+ rte_stats_strings[i].offset);
+ val = *stats_ptr;
+ xstats[count++].value = val;
+ }
+ }
+
+ /* per-rxq stats */
+ for (q = 0; q < nb_rxqs; q++) {
+ for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
+ if (rte_rxq_stats_strings[i].group_mask & group_mask) {
+ stats_ptr = RTE_PTR_ADD(ð_stats,
+ rte_rxq_stats_strings[i].offset
+ + q * sizeof(uint64_t));
+ val = *stats_ptr;
+ xstats[count++].value = val;
+ }
+ }
+ }
+
+ /* per-txq stats */
+ for (q = 0; q < nb_txqs; q++) {
+ for (i = 0; i < RTE_NB_TXQ_STATS; i++) {
+ if (rte_txq_stats_strings[i].group_mask & group_mask) {
+ stats_ptr = RTE_PTR_ADD(ð_stats,
+ rte_txq_stats_strings[i].offset
+ + q * sizeof(uint64_t));
+ val = *stats_ptr;
+ xstats[count++].value = val;
+ }
+ }
+ }
+
+ for (i = 0; i < count; i++)
+ xstats[i].id = i;
+ /* add an offset to driver-specific stats */
+ for ( ; i < count + xcount; i++)
+ xstats[i].id += count;
+
+ return count + xcount;
+}
+
/* reset ethdev extended statistics */
void
rte_eth_xstats_reset(uint8_t port_id)
@@ -1624,7 +1907,8 @@ struct rte_eth_dev *
dev = &rte_eth_devices[port_id];
- RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_stats_mapping_set, -ENOTSUP);
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_stats_mapping_set,
+ -ENOTSUP);
return (*dev->dev_ops->queue_stats_mapping_set)
(dev, queue_id, stat_idx, is_rx);
}
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index c17bbda..6c063aa 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -990,6 +990,17 @@ struct rte_eth_xstat_name {
#define ETH_MAX_VMDQ_POOL 64
/**
+ * Xstats groups by bit no. in 'group_mask'
+ */
+#define TX_GROUP 0x0001
+#define RX_GROUP 0x0002
+#define ERR_GROUP 0x0004
+#define TXQ_GROUP 0x0008
+#define RXQ_GROUP 0x0010
+#define VF_GROUP 0x0020
+#define MAC_GROUP 0x0040
+
+/**
* A structure used to get the information of queue and
* TC mapping on both TX and RX paths.
*/
@@ -1118,6 +1129,10 @@ typedef int (*eth_xstats_get_t)(struct rte_eth_dev *dev,
struct rte_eth_xstat *stats, unsigned n);
/**< @internal Get extended stats of an Ethernet device. */
+typedef int (*eth_xstats_get_by_group_t)(struct rte_eth_dev *dev,
+ struct rte_eth_xstat *stats, unsigned int n, uint64_t group_mask);
+/**< @internal Get extended stats of an Ethernet device. */
+
typedef void (*eth_xstats_reset_t)(struct rte_eth_dev *dev);
/**< @internal Reset extended stats of an Ethernet device. */
@@ -1125,6 +1140,17 @@ typedef int (*eth_xstats_get_names_t)(struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names, unsigned size);
/**< @internal Get names of extended stats of an Ethernet device. */
+typedef int (*eth_xstats_get_names_by_group_t)(struct rte_eth_dev *dev,
+ struct rte_eth_xstat_name *xstats_names,
+ unsigned int size, uint64_t group_mask);
+/**< @internal Get names of extended stats of an Ethernet device. */
+
+typedef int (*eth_xstats_get_by_name_t)(struct rte_eth_dev *dev,
+ struct rte_eth_xstat_name *xstats_names,
+ struct rte_eth_xstat *xstat,
+ const char *name);
+/**< @internal Get xstat specified by name of an Ethernet device. */
+
typedef int (*eth_queue_stats_mapping_set_t)(struct rte_eth_dev *dev,
uint16_t queue_id,
uint8_t stat_idx,
@@ -1456,8 +1482,13 @@ struct eth_dev_ops {
eth_stats_get_t stats_get; /**< Get generic device statistics. */
eth_stats_reset_t stats_reset; /**< Reset generic device statistics. */
eth_xstats_get_t xstats_get; /**< Get extended device statistics. */
+ eth_xstats_get_by_group_t xstats_get_by_group;
+ /**< Get extended device statistics. */
eth_xstats_reset_t xstats_reset; /**< Reset extended device statistics. */
- eth_xstats_get_names_t xstats_get_names;
+ eth_xstats_get_names_t xstats_get_names;
+ eth_xstats_get_names_by_group_t xstats_get_names_by_group;
+ eth_xstats_get_by_name_t xstats_get_by_name;
+
/**< Get names of extended statistics. */
eth_queue_stats_mapping_set_t queue_stats_mapping_set;
/**< Configure per queue stat counter mapping. */
@@ -2307,6 +2338,51 @@ int rte_eth_xstats_get_names(uint8_t port_id,
unsigned size);
/**
+ * Get extended statistics of an Ethernet device matching specified name.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param name
+ * Phrase used to search extended statistics
+ * @param name *xstat
+ * Pointer to allocated memory for rte_eth_xstat structure
+ * @return
+ * - 0 when xstat was successfully found and value and id were returned
+ * using pointer to rte_eth_xstat,
+ * - A negative value when xstat wasn't found.
+ */
+int
+rte_eth_xstats_get_by_name(uint8_t port_id, struct rte_eth_xstat *xstat,
+ const char *name);
+
+
+/**
+ * Retrieve names of extended grouped statistics of an Ethernet device.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param xstats_names
+ * An rte_eth_xstat_name array of at least *size* elements to
+ * be filled. If set to NULL, the function returns the required number
+ * of elements.
+ * @param size
+ * The size of the xstats_names array (number of elements).
+ * @param group_id
+ * Group identificator
+ * @return
+ * - A positive value lower or equal to size: success. The return value
+ * is the number of entries filled in the stats table.
+ * - A positive value higher than size: error, the given statistics table
+ * is too small. The return value corresponds to the size that should
+ * be given to succeed. The entries in the table are not valid and
+ * shall not be used by the caller.
+ */
+int
+rte_eth_xstats_get_names_by_group(uint8_t port_id,
+ struct rte_eth_xstat_name *xstats_names,
+ unsigned int size, uint64_t group_mask);
+
+/**
* Retrieve extended statistics of an Ethernet device.
*
* @param port_id
@@ -2332,6 +2408,33 @@ int rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstat *xstats,
unsigned n);
/**
+ * Retrieve extended grouped statistics of an Ethernet device.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param xstats
+ * A pointer to a table of structure of type *rte_eth_xstat*
+ * to be filled with device statistics ids and values: id is the
+ * index of the name string in xstats_names (see rte_eth_xstats_get_names()),
+ * and value is the statistic counter.
+ * This parameter can be set to NULL if n is 0.
+ * @param n
+ * The size of the xstats array (number of elements).
+ * @param group_id
+ * Group identificator
+ * @return
+ * - A positive value lower or equal to n: success. The return value
+ * is the number of entries filled in the stats table.
+ * - A positive value higher than n: error, the given statistics table
+ * is too small. The return value corresponds to the size that should
+ * be given to succeed. The entries in the table are not valid and
+ * shall not be used by the caller.
+ * - A negative value on error (invalid port id).
+ */
+int rte_eth_xstats_get_by_group(uint8_t port_id, struct rte_eth_xstat *xstats,
+ unsigned int n, uint64_t group_mask);
+
+/**
* Reset extended statistics of an Ethernet device.
*
* @param port_id
--
1.9.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [dpdk-dev] [PATCH 1/4] ethdev: add retrieving xstats by group and xstats by name
2017-03-03 12:54 ` [dpdk-dev] [PATCH 1/4] ethdev: add retrieving " Kuba Kozak
@ 2017-03-06 10:17 ` Thomas Monjalon
0 siblings, 0 replies; 8+ messages in thread
From: Thomas Monjalon @ 2017-03-06 10:17 UTC (permalink / raw)
To: Kuba Kozak, Jacek Piasecki; +Cc: dev
Hi,
2017-03-03 13:54, Kuba Kozak:
> From: Jacek Piasecki <jacekx.piasecki@intel.com>
>
> This patch extends library for retriving xstats by specified groups and
> single xstat by given name.
>
> Signed-off-by: Jacek Piasecki <jacekx.piasecki@intel.com>
> Signed-off-by: Kuba Kozak <kubax.kozak@intel.com>
As you probably know, it is difficult to have a good review
(or a simple review at all).
The most difficult part in such a change is not writing the code,
it is explaining your idea and getting people to agree.
Please show you have thought about the API, seen an issue or a lack,
and propose an idea with a clear target.
In short, we are missing a "why" and "how".
You must also explain what is a group, better than a list of #define.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [dpdk-dev] [PATCH 2/4] net/e1000: add grouping of xstats for e1000 driver
2017-03-03 12:54 [dpdk-dev] [PATCH 0/4] extend API to retriving xstats by group and xstats by name Kuba Kozak
2017-03-03 12:54 ` [dpdk-dev] [PATCH 1/4] ethdev: add retrieving " Kuba Kozak
@ 2017-03-03 12:54 ` Kuba Kozak
2017-03-06 2:05 ` Lu, Wenzhuo
2017-03-03 12:54 ` [dpdk-dev] [PATCH 3/4] net/ixgbe: add grouping of xstats for ixgbe driver Kuba Kozak
2017-03-03 12:54 ` [dpdk-dev] [PATCH 4/4] app/proc_info: add support for xstats-name and xstats-group Kuba Kozak
3 siblings, 1 reply; 8+ messages in thread
From: Kuba Kozak @ 2017-03-03 12:54 UTC (permalink / raw)
To: dev; +Cc: Jacek Piasecki, Kuba Kozak
From: Jacek Piasecki <jacekx.piasecki@intel.com>
This patch extends the 'rte_igb_xstats_name_off' structure
with additional field 'group_mask'. For each xstats there is now
specified group (e.g. TX_GROUP), one xstatistic can be in several groups.
To implement new functionality of retriving xstats by group
on driver level, there are two functions added:
eth_igb_xstats_get_by_group() and eth_igb_xstats_get_names_by_group()
Signed-off-by: Jacek Piasecki <jacekx.piasecki@intel.com>
Signed-off-by: Kuba Kozak <kubax.kozak@intel.com>
---
drivers/net/e1000/igb_ethdev.c | 261 +++++++++++++++++++++++++++++++----------
1 file changed, 199 insertions(+), 62 deletions(-)
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index a112b38..28eced6 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -115,9 +115,18 @@ 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_xstat *xstats, unsigned n);
+static
+int eth_igb_xstats_get_by_group(struct rte_eth_dev *dev,
+ struct rte_eth_xstat *xstats,
+ unsigned int n, uint64_t group_mask);
static int eth_igb_xstats_get_names(struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names,
unsigned limit);
+static int
+eth_igb_xstats_get_names_by_group(__rte_unused struct rte_eth_dev *dev,
+ struct rte_eth_xstat_name *xstats_names,
+ __rte_unused unsigned int limit,
+ uint64_t group_mask);
static void eth_igb_stats_reset(struct rte_eth_dev *dev);
static void eth_igb_xstats_reset(struct rte_eth_dev *dev);
static int eth_igb_fw_version_get(struct rte_eth_dev *dev,
@@ -390,7 +399,9 @@ static void eth_igbvf_interrupt_handler(struct rte_intr_handle *handle,
.link_update = eth_igb_link_update,
.stats_get = eth_igb_stats_get,
.xstats_get = eth_igb_xstats_get,
+ .xstats_get_by_group = eth_igb_xstats_get_by_group,
.xstats_get_names = eth_igb_xstats_get_names,
+ .xstats_get_names_by_group = eth_igb_xstats_get_names_by_group,
.stats_reset = eth_igb_stats_reset,
.xstats_reset = eth_igb_xstats_reset,
.fw_version_get = eth_igb_fw_version_get,
@@ -473,78 +484,128 @@ static void eth_igbvf_interrupt_handler(struct rte_intr_handle *handle,
struct rte_igb_xstats_name_off {
char name[RTE_ETH_XSTATS_NAME_SIZE];
unsigned offset;
+ uint64_t group_mask;
};
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)},
+ {"rx_crc_errors", offsetof(struct e1000_hw_stats, crcerrs),
+ RX_GROUP | ERR_GROUP},
+ {"rx_align_errors", offsetof(struct e1000_hw_stats, algnerrc),
+ RX_GROUP | ERR_GROUP},
+ {"rx_symbol_errors", offsetof(struct e1000_hw_stats, symerrs),
+ RX_GROUP | ERR_GROUP},
+ {"rx_missed_packets", offsetof(struct e1000_hw_stats, mpc),
+ RX_GROUP},
+ {"tx_single_collision_packets", offsetof(struct e1000_hw_stats, scc),
+ TX_GROUP},
+ {"tx_multiple_collision_packets", offsetof(struct e1000_hw_stats, mcc),
+ TX_GROUP},
{"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)},
+ ecol), TX_GROUP},
+ {"tx_late_collisions", offsetof(struct e1000_hw_stats, latecol),
+ TX_GROUP},
+ {"tx_total_collisions", offsetof(struct e1000_hw_stats, colc),
+ TX_GROUP},
+ {"tx_deferred_packets", offsetof(struct e1000_hw_stats, dc),
+ TX_GROUP},
+ {"tx_no_carrier_sense_packets", offsetof(struct e1000_hw_stats, tncrs),
+ TX_GROUP},
+ {"rx_carrier_ext_errors", offsetof(struct e1000_hw_stats, cexterr),
+ RX_GROUP | ERR_GROUP},
+ {"rx_length_errors", offsetof(struct e1000_hw_stats, rlec),
+ RX_GROUP | ERR_GROUP},
+ {"rx_xon_packets", offsetof(struct e1000_hw_stats, xonrxc),
+ RX_GROUP},
+ {"tx_xon_packets", offsetof(struct e1000_hw_stats, xontxc),
+ TX_GROUP},
+ {"rx_xoff_packets", offsetof(struct e1000_hw_stats, xoffrxc),
+ RX_GROUP},
+ {"tx_xoff_packets", offsetof(struct e1000_hw_stats, xofftxc),
+ TX_GROUP},
{"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)},
+ fcruc), RX_GROUP},
+ {"rx_size_64_packets", offsetof(struct e1000_hw_stats, prc64),
+ RX_GROUP},
+ {"rx_size_65_to_127_packets", offsetof(struct e1000_hw_stats, prc127),
+ RX_GROUP},
+ {"rx_size_128_to_255_packets", offsetof(struct e1000_hw_stats, prc255),
+ RX_GROUP},
+ {"rx_size_256_to_511_packets", offsetof(struct e1000_hw_stats, prc511),
+ RX_GROUP},
{"rx_size_512_to_1023_packets", offsetof(struct e1000_hw_stats,
- prc1023)},
+ prc1023), RX_GROUP},
{"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)},
+ prc1522), RX_GROUP},
+ {"rx_broadcast_packets", offsetof(struct e1000_hw_stats, bprc),
+ RX_GROUP},
+ {"rx_multicast_packets", offsetof(struct e1000_hw_stats, mprc),
+ RX_GROUP},
+ {"rx_undersize_errors", offsetof(struct e1000_hw_stats, ruc),
+ RX_GROUP | ERR_GROUP},
+ {"rx_fragment_errors", offsetof(struct e1000_hw_stats, rfc),
+ RX_GROUP | ERR_GROUP},
+ {"rx_oversize_errors", offsetof(struct e1000_hw_stats, roc),
+ RX_GROUP | ERR_GROUP},
+ {"rx_jabber_errors", offsetof(struct e1000_hw_stats, rjc),
+ RX_GROUP | ERR_GROUP},
+ {"rx_management_packets", offsetof(struct e1000_hw_stats, mgprc),
+ RX_GROUP},
+ {"rx_management_dropped", offsetof(struct e1000_hw_stats, mgpdc),
+ RX_GROUP},
+ {"tx_management_packets", offsetof(struct e1000_hw_stats, mgptc),
+ TX_GROUP},
+ {"rx_total_packets", offsetof(struct e1000_hw_stats, tpr),
+ RX_GROUP},
+ {"tx_total_packets", offsetof(struct e1000_hw_stats, tpt),
+ TX_GROUP},
+ {"rx_total_bytes", offsetof(struct e1000_hw_stats, tor),
+ RX_GROUP},
+ {"tx_total_bytes", offsetof(struct e1000_hw_stats, tot),
+ TX_GROUP},
+ {"tx_size_64_packets", offsetof(struct e1000_hw_stats, ptc64),
+ TX_GROUP},
+ {"tx_size_65_to_127_packets", offsetof(struct e1000_hw_stats, ptc127),
+ TX_GROUP},
+ {"tx_size_128_to_255_packets", offsetof(struct e1000_hw_stats, ptc255),
+ TX_GROUP},
+ {"tx_size_256_to_511_packets", offsetof(struct e1000_hw_stats, ptc511),
+ TX_GROUP},
{"tx_size_512_to_1023_packets", offsetof(struct e1000_hw_stats,
- ptc1023)},
+ ptc1023), TX_GROUP},
{"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)},
+ ptc1522), TX_GROUP},
+ {"tx_multicast_packets", offsetof(struct e1000_hw_stats, mptc),
+ TX_GROUP},
+ {"tx_broadcast_packets", offsetof(struct e1000_hw_stats, bptc),
+ TX_GROUP},
+ {"tx_tso_packets", offsetof(struct e1000_hw_stats, tsctc),
+ TX_GROUP},
+ {"tx_tso_errors", offsetof(struct e1000_hw_stats, tsctfc),
+ TX_GROUP | ERR_GROUP},
+ {"rx_sent_to_host_packets", offsetof(struct e1000_hw_stats, rpthc),
+ RX_GROUP},
+ {"tx_sent_by_host_packets", offsetof(struct e1000_hw_stats, hgptc),
+ TX_GROUP},
+ {"rx_code_violation_packets", offsetof(struct e1000_hw_stats, scvpc),
+ TX_GROUP},
+ {"interrupt_assert_count", offsetof(struct e1000_hw_stats, iac),
+ RX_GROUP},
};
#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)},
+ {"rx_multicast_packets", offsetof(struct e1000_vf_stats, mprc),
+ RX_GROUP | VF_GROUP},
+ {"rx_good_loopback_packets", offsetof(struct e1000_vf_stats, gprlbc),
+ RX_GROUP | VF_GROUP},
+ {"tx_good_loopback_packets", offsetof(struct e1000_vf_stats, gptlbc),
+ TX_GROUP | VF_GROUP},
+ {"rx_good_loopback_bytes", offsetof(struct e1000_vf_stats, gorlbc),
+ RX_GROUP | VF_GROUP},
+ {"tx_good_loopback_bytes", offsetof(struct e1000_vf_stats, gotlbc),
+ TX_GROUP | VF_GROUP},
};
#define IGBVF_NB_XSTATS (sizeof(rte_igbvf_stats_strings) / \
@@ -1846,10 +1907,43 @@ static int eth_igb_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
}
static int
-eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
- unsigned n)
+eth_igb_xstats_get_names_by_group(__rte_unused struct rte_eth_dev *dev,
+ struct rte_eth_xstat_name *xstats_names,
+ __rte_unused unsigned int limit,
+ uint64_t group_mask)
{
- struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ unsigned int i;
+ unsigned int count = 0;
+
+ if (xstats_names == NULL) {
+ for (i = 0; i < IGB_NB_XSTATS; i++) {
+ if (rte_igb_stats_strings[i].group_mask & group_mask)
+ count++;
+ }
+ return count;
+ }
+
+ /* Note: limit checked in rte_eth_xstats_names() */
+
+ count = 0;
+ for (i = 0; i < IGB_NB_XSTATS; i++) {
+ if (rte_igb_stats_strings[i].group_mask & group_mask) {
+ snprintf(xstats_names[count].name,
+ sizeof(xstats_names[0].name),
+ "%s", rte_igb_stats_strings[i].name);
+ count++;
+ }
+ }
+ return count;
+}
+
+static
+int eth_igb_xstats_get(struct rte_eth_dev *dev,
+ struct rte_eth_xstat *xstats,
+ unsigned int 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;
@@ -1875,8 +1969,50 @@ static int eth_igb_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
return IGB_NB_XSTATS;
}
+static
+int eth_igb_xstats_get_by_group(struct rte_eth_dev *dev,
+ struct rte_eth_xstat *xstats,
+ unsigned int n, uint64_t group_mask)
+{
+ 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 int i;
+ unsigned int count = 0;
+
+
+ for (i = 0; i < IGB_NB_XSTATS; i++) {
+ if (rte_igb_stats_strings[i].group_mask & group_mask)
+ count++;
+ }
+
+ if (n < IGB_NB_XSTATS)
+ return count;
+
+ 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++) {
+ if (rte_igb_stats_strings[i].group_mask & group_mask) {
+ xstats[i].id = i;
+ xstats[i].value = *(uint64_t *)(((char *)hw_stats) +
+ rte_igb_stats_strings[i].offset);
+ }
+ }
+
+ return count;
+}
+
static void
-igbvf_read_stats_registers(struct e1000_hw *hw, struct e1000_vf_stats *hw_stats)
+igbvf_read_stats_registers(struct e1000_hw *hw,
+ struct e1000_vf_stats *hw_stats)
{
/* Good Rx packets, include VF loopback */
UPDATE_VF_STAT(E1000_VFGPRC,
@@ -2314,7 +2450,8 @@ static int eth_igbvf_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
/* Let firmware know the driver has taken over */
ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
- E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
+ E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext |
+ E1000_CTRL_EXT_DRV_LOAD);
}
/*
--
1.9.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [dpdk-dev] [PATCH 2/4] net/e1000: add grouping of xstats for e1000 driver
2017-03-03 12:54 ` [dpdk-dev] [PATCH 2/4] net/e1000: add grouping of xstats for e1000 driver Kuba Kozak
@ 2017-03-06 2:05 ` Lu, Wenzhuo
0 siblings, 0 replies; 8+ messages in thread
From: Lu, Wenzhuo @ 2017-03-06 2:05 UTC (permalink / raw)
To: Kozak, KubaX, dev; +Cc: Piasecki, JacekX, Kozak, KubaX
Hi,
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Kuba Kozak
> Sent: Friday, March 3, 2017 8:55 PM
> To: dev@dpdk.org
> Cc: Piasecki, JacekX; Kozak, KubaX
> Subject: [dpdk-dev] [PATCH 2/4] net/e1000: add grouping of xstats for e1000
> driver
>
> From: Jacek Piasecki <jacekx.piasecki@intel.com>
>
> This patch extends the 'rte_igb_xstats_name_off' structure with additional field
> 'group_mask'. For each xstats there is now specified group (e.g. TX_GROUP),
> one xstatistic can be in several groups.
> To implement new functionality of retriving xstats by group on driver level, there
> are two functions added:
> eth_igb_xstats_get_by_group() and eth_igb_xstats_get_names_by_group()
>
> Signed-off-by: Jacek Piasecki <jacekx.piasecki@intel.com>
> Signed-off-by: Kuba Kozak <kubax.kozak@intel.com>
Acked-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
Just a reminder, the tittle need to add v2 when sending a new version, like ' [dpdk-dev] [v2 PATCH 2/4]'
^ permalink raw reply [flat|nested] 8+ messages in thread
* [dpdk-dev] [PATCH 3/4] net/ixgbe: add grouping of xstats for ixgbe driver
2017-03-03 12:54 [dpdk-dev] [PATCH 0/4] extend API to retriving xstats by group and xstats by name Kuba Kozak
2017-03-03 12:54 ` [dpdk-dev] [PATCH 1/4] ethdev: add retrieving " Kuba Kozak
2017-03-03 12:54 ` [dpdk-dev] [PATCH 2/4] net/e1000: add grouping of xstats for e1000 driver Kuba Kozak
@ 2017-03-03 12:54 ` Kuba Kozak
2017-03-03 12:54 ` [dpdk-dev] [PATCH 4/4] app/proc_info: add support for xstats-name and xstats-group Kuba Kozak
3 siblings, 0 replies; 8+ messages in thread
From: Kuba Kozak @ 2017-03-03 12:54 UTC (permalink / raw)
To: dev; +Cc: Jacek Piasecki, Kuba Kozak
From: Jacek Piasecki <jacekx.piasecki@intel.com>
This patch extends the 'rte_ixgbe_xstats_name_off' structure
with additional field 'group_mask'. For each xstats there is
now specified group (e.g. MAC_GROUP), one xstatistic can be in
several groups. To implement new functionality of retriving
xstats by group on driver level, there are two functions added:
ixgbe_dev_xstats_get_by_group() and ixgbe_dev_xstats_get_names_by_group()
Signed-off-by: Jacek Piasecki <jacekx.piasecki@intel.com>
Signed-off-by: Kuba Kozak <kubax.kozak@intel.com>
---
drivers/net/ixgbe/ixgbe_ethdev.c | 496 +++++++++++++++++++++++++++++++--------
1 file changed, 403 insertions(+), 93 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 7169007..69731ce 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -124,7 +124,8 @@
#define IXGBEVF_PMD_NAME "rte_ixgbevf_pmd" /* PMD name */
-#define IXGBE_QUEUE_STAT_COUNTERS (sizeof(hw_stats->qprc) / sizeof(hw_stats->qprc[0]))
+#define IXGBE_QUEUE_STAT_COUNTERS (sizeof(hw_stats->qprc) \
+ / sizeof(hw_stats->qprc[0]))
#define IXGBE_HKEY_MAX_INDEX 10
@@ -187,12 +188,25 @@ 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_xstat *xstats, unsigned n);
+static int ixgbe_dev_xstats_get_by_group(struct rte_eth_dev *dev,
+ struct rte_eth_xstat *xstats,
+ unsigned int n, uint64_t group_mask);
static int ixgbevf_dev_xstats_get(struct rte_eth_dev *dev,
struct rte_eth_xstat *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_xstats_get_by_name(struct rte_eth_dev *dev,
+ struct rte_eth_xstat_name *xstats_names,
+ struct rte_eth_xstat *xstat,
+ const char *name);
static int ixgbe_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names, __rte_unused unsigned limit);
+static
+int ixgbe_dev_xstats_get_names_by_group(__rte_unused
+ struct rte_eth_dev *dev,
+ struct rte_eth_xstat_name *xstats_names,
+ unsigned int limit,
+ uint64_t group_mask);
static int ixgbevf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names, __rte_unused unsigned limit);
static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
@@ -532,10 +546,13 @@ static int ixgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
.link_update = ixgbe_dev_link_update,
.stats_get = ixgbe_dev_stats_get,
.xstats_get = ixgbe_dev_xstats_get,
+ .xstats_get_by_name = ixgbe_xstats_get_by_name,
+ .xstats_get_by_group = ixgbe_dev_xstats_get_by_group,
.stats_reset = ixgbe_dev_stats_reset,
.xstats_reset = ixgbe_dev_xstats_reset,
.xstats_get_names = ixgbe_dev_xstats_get_names,
.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
+ .xstats_get_names_by_group = ixgbe_dev_xstats_get_names_by_group,
.fw_version_get = ixgbe_fw_version_get,
.dev_infos_get = ixgbe_dev_info_get,
.dev_supported_ptypes_get = ixgbe_dev_supported_ptypes_get,
@@ -653,87 +670,118 @@ static int ixgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
struct rte_ixgbe_xstats_name_off {
char name[RTE_ETH_XSTATS_NAME_SIZE];
unsigned offset;
+ uint64_t group_mask;
};
static const struct rte_ixgbe_xstats_name_off rte_ixgbe_stats_strings[] = {
- {"rx_crc_errors", offsetof(struct ixgbe_hw_stats, crcerrs)},
- {"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_crc_errors", offsetof(struct ixgbe_hw_stats, crcerrs),
+ RX_GROUP | ERR_GROUP},
+ {"rx_illegal_byte_errors",
+ offsetof(struct ixgbe_hw_stats, illerrc),
+ RX_GROUP | ERR_GROUP},
+ {"rx_error_bytes", offsetof(struct ixgbe_hw_stats, errbc),
+ RX_GROUP | ERR_GROUP},
+ {"mac_local_errors", offsetof(struct ixgbe_hw_stats, mlfc), ERR_GROUP},
+ {"mac_remote_errors", offsetof(struct ixgbe_hw_stats, mrfc), ERR_GROUP},
+ {"rx_length_errors", offsetof(struct ixgbe_hw_stats, rlec),
+ RX_GROUP | ERR_GROUP},
+ {"tx_xon_packets", offsetof(struct ixgbe_hw_stats, lxontxc), TX_GROUP},
+ {"rx_xon_packets", offsetof(struct ixgbe_hw_stats, lxonrxc), RX_GROUP},
+ {"tx_xoff_packets", offsetof(struct ixgbe_hw_stats, lxofftxc),
+ TX_GROUP},
+ {"rx_xoff_packets", offsetof(struct ixgbe_hw_stats, lxoffrxc),
+ RX_GROUP},
+ {"rx_size_64_packets", offsetof(struct ixgbe_hw_stats, prc64),
+ RX_GROUP},
+ {"rx_size_65_to_127_packets",
+ offsetof(struct ixgbe_hw_stats, prc127), RX_GROUP},
+ {"rx_size_128_to_255_packets",
+ offsetof(struct ixgbe_hw_stats, prc255), RX_GROUP},
+ {"rx_size_256_to_511_packets",
+ offsetof(struct ixgbe_hw_stats, prc511), RX_GROUP},
{"rx_size_512_to_1023_packets", offsetof(struct ixgbe_hw_stats,
- prc1023)},
+ prc1023), RX_GROUP},
{"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_management_packets", offsetof(struct ixgbe_hw_stats, mngprc)},
- {"rx_management_dropped", offsetof(struct ixgbe_hw_stats, mngpdc)},
- {"tx_management_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)},
+ prc1522), RX_GROUP},
+ {"rx_broadcast_packets", offsetof(struct ixgbe_hw_stats, bprc),
+ RX_GROUP},
+ {"rx_multicast_packets", offsetof(struct ixgbe_hw_stats, mprc),
+ RX_GROUP},
+ {"rx_fragment_errors", offsetof(struct ixgbe_hw_stats, rfc),
+ RX_GROUP | ERR_GROUP},
+ {"rx_undersize_errors", offsetof(struct ixgbe_hw_stats, ruc),
+ RX_GROUP | ERR_GROUP},
+ {"rx_oversize_errors", offsetof(struct ixgbe_hw_stats, roc),
+ RX_GROUP | ERR_GROUP},
+ {"rx_jabber_errors", offsetof(struct ixgbe_hw_stats, rjc),
+ RX_GROUP | ERR_GROUP},
+ {"rx_management_packets", offsetof(struct ixgbe_hw_stats, mngprc),
+ RX_GROUP},
+ {"rx_management_dropped", offsetof(struct ixgbe_hw_stats, mngpdc),
+ RX_GROUP},
+ {"tx_management_packets", offsetof(struct ixgbe_hw_stats, mngptc),
+ TX_GROUP},
+ {"rx_total_packets", offsetof(struct ixgbe_hw_stats, tpr), RX_GROUP},
+ {"rx_total_bytes", offsetof(struct ixgbe_hw_stats, tor), RX_GROUP},
+ {"tx_total_packets", offsetof(struct ixgbe_hw_stats, tpt), TX_GROUP},
+ {"tx_size_64_packets", offsetof(struct ixgbe_hw_stats, ptc64),
+ TX_GROUP},
+ {"tx_size_65_to_127_packets",
+ offsetof(struct ixgbe_hw_stats, ptc127), TX_GROUP},
+ {"tx_size_128_to_255_packets",
+ offsetof(struct ixgbe_hw_stats, ptc255), TX_GROUP},
+ {"tx_size_256_to_511_packets",
+ offsetof(struct ixgbe_hw_stats, ptc511), TX_GROUP},
+ {"tx_size_512_to_1023_packets",
+ offsetof(struct ixgbe_hw_stats,
+ ptc1023), TX_GROUP},
{"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)},
-
+ ptc1522), TX_GROUP},
+ {"tx_multicast_packets", offsetof(struct ixgbe_hw_stats, mptc),
+ TX_GROUP},
+ {"tx_broadcast_packets", offsetof(struct ixgbe_hw_stats, bptc),
+ TX_GROUP},
+ {"rx_mac_short_packet_dropped",
+ offsetof(struct ixgbe_hw_stats, mspdc), RX_GROUP},
+ {"rx_l3_l4_xsum_error", offsetof(struct ixgbe_hw_stats, xec),
+ RX_GROUP | ERR_GROUP},
{"flow_director_added_filters", offsetof(struct ixgbe_hw_stats,
- fdirustat_add)},
+ fdirustat_add), 0},
{"flow_director_removed_filters", offsetof(struct ixgbe_hw_stats,
- fdirustat_remove)},
+ fdirustat_remove), 0},
{"flow_director_filter_add_errors", offsetof(struct ixgbe_hw_stats,
- fdirfstat_fadd)},
+ fdirfstat_fadd), ERR_GROUP},
{"flow_director_filter_remove_errors", offsetof(struct ixgbe_hw_stats,
- fdirfstat_fremove)},
+ fdirfstat_fremove), ERR_GROUP},
{"flow_director_matched_filters", offsetof(struct ixgbe_hw_stats,
- fdirmatch)},
+ fdirmatch), 0},
{"flow_director_missed_filters", offsetof(struct ixgbe_hw_stats,
- fdirmiss)},
+ fdirmiss), 0},
- {"rx_fcoe_crc_errors", offsetof(struct ixgbe_hw_stats, fccrc)},
- {"rx_fcoe_dropped", offsetof(struct ixgbe_hw_stats, fcoerpdc)},
+ {"rx_fcoe_crc_errors", offsetof(struct ixgbe_hw_stats, fccrc),
+ RX_GROUP | ERR_GROUP},
+ {"rx_fcoe_dropped", offsetof(struct ixgbe_hw_stats, fcoerpdc),
+ RX_GROUP},
{"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)},
+ fclast), RX_GROUP | ERR_GROUP},
+ {"rx_fcoe_packets", offsetof(struct ixgbe_hw_stats, fcoeprc), RX_GROUP},
+ {"tx_fcoe_packets", offsetof(struct ixgbe_hw_stats, fcoeptc), TX_GROUP},
+ {"rx_fcoe_bytes", offsetof(struct ixgbe_hw_stats, fcoedwrc), RX_GROUP},
+ {"tx_fcoe_bytes", offsetof(struct ixgbe_hw_stats, fcoedwtc), TX_GROUP},
{"rx_fcoe_no_direct_data_placement", offsetof(struct ixgbe_hw_stats,
- fcoe_noddp)},
+ fcoe_noddp), RX_GROUP},
{"rx_fcoe_no_direct_data_placement_ext_buff",
- offsetof(struct ixgbe_hw_stats, fcoe_noddp_ext_buff)},
-
+ offsetof(struct ixgbe_hw_stats, fcoe_noddp_ext_buff), RX_GROUP},
{"tx_flow_control_xon_packets", offsetof(struct ixgbe_hw_stats,
- lxontxc)},
+ lxontxc), TX_GROUP},
{"rx_flow_control_xon_packets", offsetof(struct ixgbe_hw_stats,
- lxonrxc)},
+ lxonrxc), RX_GROUP},
{"tx_flow_control_xoff_packets", offsetof(struct ixgbe_hw_stats,
- lxofftxc)},
+ lxofftxc), TX_GROUP},
{"rx_flow_control_xoff_packets", offsetof(struct ixgbe_hw_stats,
- lxoffrxc)},
- {"rx_total_missed_packets", offsetof(struct ixgbe_hw_stats, mpctotal)},
+ lxoffrxc), RX_GROUP},
+ {"rx_total_missed_packets",
+ offsetof(struct ixgbe_hw_stats, mpctotal), RX_GROUP},
};
#define IXGBE_NB_HW_STATS (sizeof(rte_ixgbe_stats_strings) / \
@@ -742,43 +790,43 @@ struct rte_ixgbe_xstats_name_off {
/* MACsec statistics */
static const struct rte_ixgbe_xstats_name_off rte_ixgbe_macsec_strings[] = {
{"out_pkts_untagged", offsetof(struct ixgbe_macsec_stats,
- out_pkts_untagged)},
+ out_pkts_untagged), MAC_GROUP},
{"out_pkts_encrypted", offsetof(struct ixgbe_macsec_stats,
- out_pkts_encrypted)},
+ out_pkts_encrypted), MAC_GROUP},
{"out_pkts_protected", offsetof(struct ixgbe_macsec_stats,
- out_pkts_protected)},
+ out_pkts_protected), MAC_GROUP},
{"out_octets_encrypted", offsetof(struct ixgbe_macsec_stats,
- out_octets_encrypted)},
+ out_octets_encrypted), MAC_GROUP},
{"out_octets_protected", offsetof(struct ixgbe_macsec_stats,
- out_octets_protected)},
+ out_octets_protected), MAC_GROUP},
{"in_pkts_untagged", offsetof(struct ixgbe_macsec_stats,
- in_pkts_untagged)},
+ in_pkts_untagged), MAC_GROUP},
{"in_pkts_badtag", offsetof(struct ixgbe_macsec_stats,
- in_pkts_badtag)},
+ in_pkts_badtag), MAC_GROUP},
{"in_pkts_nosci", offsetof(struct ixgbe_macsec_stats,
- in_pkts_nosci)},
+ in_pkts_nosci), MAC_GROUP},
{"in_pkts_unknownsci", offsetof(struct ixgbe_macsec_stats,
- in_pkts_unknownsci)},
+ in_pkts_unknownsci), MAC_GROUP},
{"in_octets_decrypted", offsetof(struct ixgbe_macsec_stats,
- in_octets_decrypted)},
+ in_octets_decrypted), MAC_GROUP},
{"in_octets_validated", offsetof(struct ixgbe_macsec_stats,
- in_octets_validated)},
+ in_octets_validated), MAC_GROUP},
{"in_pkts_unchecked", offsetof(struct ixgbe_macsec_stats,
- in_pkts_unchecked)},
+ in_pkts_unchecked), MAC_GROUP},
{"in_pkts_delayed", offsetof(struct ixgbe_macsec_stats,
- in_pkts_delayed)},
+ in_pkts_delayed), MAC_GROUP},
{"in_pkts_late", offsetof(struct ixgbe_macsec_stats,
- in_pkts_late)},
+ in_pkts_late), MAC_GROUP},
{"in_pkts_ok", offsetof(struct ixgbe_macsec_stats,
- in_pkts_ok)},
+ in_pkts_ok), MAC_GROUP},
{"in_pkts_invalid", offsetof(struct ixgbe_macsec_stats,
- in_pkts_invalid)},
+ in_pkts_invalid), MAC_GROUP},
{"in_pkts_notvalid", offsetof(struct ixgbe_macsec_stats,
- in_pkts_notvalid)},
+ in_pkts_notvalid), MAC_GROUP},
{"in_pkts_unusedsa", offsetof(struct ixgbe_macsec_stats,
- in_pkts_unusedsa)},
+ in_pkts_unusedsa), MAC_GROUP},
{"in_pkts_notusingsa", offsetof(struct ixgbe_macsec_stats,
- in_pkts_notusingsa)},
+ in_pkts_notusingsa), MAC_GROUP},
};
#define IXGBE_NB_MACSEC_STATS (sizeof(rte_ixgbe_macsec_strings) / \
@@ -786,10 +834,11 @@ struct rte_ixgbe_xstats_name_off {
/* Per-queue statistics */
static const struct rte_ixgbe_xstats_name_off rte_ixgbe_rxq_strings[] = {
- {"mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats, rnbc)},
- {"dropped", offsetof(struct ixgbe_hw_stats, mpc)},
- {"xon_packets", offsetof(struct ixgbe_hw_stats, pxonrxc)},
- {"xoff_packets", offsetof(struct ixgbe_hw_stats, pxoffrxc)},
+ {"mbuf_allocation_errors", offsetof(struct ixgbe_hw_stats, rnbc),
+ ERR_GROUP | RXQ_GROUP},
+ {"dropped", offsetof(struct ixgbe_hw_stats, mpc), RXQ_GROUP},
+ {"xon_packets", offsetof(struct ixgbe_hw_stats, pxonrxc), RXQ_GROUP},
+ {"xoff_packets", offsetof(struct ixgbe_hw_stats, pxoffrxc), RXQ_GROUP},
};
#define IXGBE_NB_RXQ_PRIO_STATS (sizeof(rte_ixgbe_rxq_strings) / \
@@ -797,10 +846,10 @@ struct rte_ixgbe_xstats_name_off {
#define IXGBE_NB_RXQ_PRIO_VALUES 8
static const struct rte_ixgbe_xstats_name_off rte_ixgbe_txq_strings[] = {
- {"xon_packets", offsetof(struct ixgbe_hw_stats, pxontxc)},
- {"xoff_packets", offsetof(struct ixgbe_hw_stats, pxofftxc)},
+ {"xon_packets", offsetof(struct ixgbe_hw_stats, pxontxc), TXQ_GROUP},
+ {"xoff_packets", offsetof(struct ixgbe_hw_stats, pxofftxc), TXQ_GROUP},
{"xon_to_xoff_packets", offsetof(struct ixgbe_hw_stats,
- pxon2offc)},
+ pxon2offc), TXQ_GROUP},
};
#define IXGBE_NB_TXQ_PRIO_STATS (sizeof(rte_ixgbe_txq_strings) / \
@@ -808,7 +857,8 @@ struct rte_ixgbe_xstats_name_off {
#define IXGBE_NB_TXQ_PRIO_VALUES 8
static const struct rte_ixgbe_xstats_name_off rte_ixgbevf_stats_strings[] = {
- {"rx_multicast_packets", offsetof(struct ixgbevf_hw_stats, vfmprc)},
+ {"rx_multicast_packets",
+ offsetof(struct ixgbevf_hw_stats, vfmprc), RX_GROUP},
};
#define IXGBEVF_NB_XSTATS (sizeof(rte_ixgbevf_stats_strings) / \
@@ -2414,8 +2464,9 @@ static int ixgbe_l2_tn_filter_init(struct rte_eth_dev *eth_dev)
* - fixed speed: TODO implement
*/
if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED) {
- PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; fix speed not supported",
- dev->data->port_id);
+ PMD_INIT_LOG(ERR,
+ "Invalid link_speeds for port %hhu; fix speed not supported",
+ dev->data->port_id);
return -EINVAL;
}
@@ -3038,6 +3089,104 @@ static int ixgbe_l2_tn_filter_init(struct rte_eth_dev *eth_dev)
(IXGBE_NB_TXQ_PRIO_STATS * IXGBE_NB_TXQ_PRIO_VALUES);
}
+static unsigned
+ixgbe_xstats_calc_num_by_group(uint64_t group_mask) {
+ unsigned int i;
+ unsigned int count = 0;
+
+ for (i = 0; i < IXGBE_NB_HW_STATS; i++) {
+ if (rte_ixgbe_stats_strings[i].group_mask & group_mask)
+ count++;
+ }
+ for (i = 0; i < IXGBE_NB_MACSEC_STATS; i++) {
+ if (rte_ixgbe_macsec_strings[i].group_mask & group_mask)
+ count++;
+ }
+ for (i = 0; i < IXGBE_NB_RXQ_PRIO_STATS; i++) {
+ if (rte_ixgbe_rxq_strings[i].group_mask & group_mask)
+ count += IXGBE_NB_TXQ_PRIO_VALUES;
+ }
+ for (i = 0; i < IXGBE_NB_TXQ_PRIO_STATS; i++) {
+ if (rte_ixgbe_txq_strings[i].group_mask & group_mask)
+ count += IXGBE_NB_TXQ_PRIO_VALUES;
+ }
+
+ return count;
+}
+
+static int ixgbe_xstats_get_by_name(struct rte_eth_dev *dev,
+ struct rte_eth_xstat_name *xstats_names,
+ struct rte_eth_xstat *xstat,
+ const char *name)
+{
+ struct ixgbe_hw_stats *hw_stats =
+ IXGBE_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+
+ unsigned int i;
+
+
+ const unsigned int cnt_stats = ixgbe_xstats_calc_num();
+ if (xstats_names == NULL)
+ return cnt_stats;
+
+ unsigned int current = 0;
+
+ for (i = 0; i < IXGBE_NB_HW_STATS; i++) {
+ if (!strncmp(rte_ixgbe_stats_strings[i].name, name,
+ sizeof(rte_ixgbe_stats_strings[i].name))) {
+ snprintf(xstats_names[current].name,
+ sizeof(xstats_names[current].name),
+ "%s", rte_ixgbe_stats_strings[i].name);
+ xstat[current].id = current;
+ xstat[current].value =
+ *(uint64_t *)(((char *)hw_stats) +
+ rte_ixgbe_stats_strings[i].offset);
+ break;
+ };
+ }
+ for (i = 0; i < IXGBE_NB_MACSEC_STATS; i++) {
+ if (!strncmp(rte_ixgbe_macsec_strings[i].name, name,
+ sizeof(rte_ixgbe_macsec_strings[i].name))) {
+ snprintf(xstats_names[current].name,
+ sizeof(xstats_names[current].name),
+ "%s",
+ rte_ixgbe_macsec_strings[i].name);
+ xstat[current].id = current;
+ xstat[current].value =
+ *(uint64_t *)(((char *)hw_stats) +
+ rte_ixgbe_macsec_strings[i].offset);
+ break;
+ };
+ }
+ for (i = 0; i < IXGBE_NB_RXQ_PRIO_STATS; i++) {
+ if (!strncmp(rte_ixgbe_rxq_strings[i].name, name,
+ sizeof(rte_ixgbe_rxq_strings[i].name))) {
+ snprintf(xstats_names[current].name,
+ sizeof(xstats_names[current].name),
+ "%s", rte_ixgbe_rxq_strings[i].name);
+ xstat[current].id = current;
+ xstat[current].value =
+ *(uint64_t *)(((char *)hw_stats) +
+ rte_ixgbe_rxq_strings[i].offset);
+ break;
+ };
+ }
+ for (i = 0; i < IXGBE_NB_TXQ_PRIO_STATS; i++) {
+ if (!strncmp(rte_ixgbe_txq_strings[i].name, name,
+ sizeof(rte_ixgbe_txq_strings[i].name))) {
+ snprintf(xstats_names[current].name,
+ sizeof(xstats_names[current].name),
+ "%s", rte_ixgbe_txq_strings[i].name);
+ xstat[current].id = current;
+ xstat[current].value =
+ *(uint64_t *)(((char *)hw_stats) +
+ rte_ixgbe_txq_strings[i].offset);
+ break;
+ };
+ }
+ return cnt_stats;
+}
+
static int ixgbe_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names, __rte_unused unsigned limit)
{
@@ -3094,6 +3243,77 @@ static int ixgbe_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
return cnt_stats;
}
+static
+int ixgbe_dev_xstats_get_names_by_group(__rte_unused struct rte_eth_dev *dev,
+ struct rte_eth_xstat_name *xstats_names,
+ __rte_unused unsigned int limit, uint64_t group_mask)
+{
+ const unsigned int
+ cnt_stats = ixgbe_xstats_calc_num_by_group(group_mask);
+ unsigned int stat, i, count;
+
+ if (xstats_names != NULL) {
+ count = 0;
+
+ /* Note: limit >= cnt_stats checked upstream
+ * in rte_eth_xstats_names()
+ */
+
+ /* Extended stats from ixgbe_hw_stats */
+ for (i = 0; i < IXGBE_NB_HW_STATS; i++) {
+ if (rte_ixgbe_stats_strings[i].group_mask &
+ group_mask) {
+ snprintf(xstats_names[count].name,
+ sizeof(xstats_names[count].name),
+ "%s",
+ rte_ixgbe_stats_strings[i].name);
+ count++;
+ }
+ }
+
+ /* MACsec Stats */
+ for (i = 0; i < IXGBE_NB_MACSEC_STATS; i++) {
+ if (rte_ixgbe_macsec_strings[i].group_mask &
+ group_mask){
+ snprintf(xstats_names[count].name,
+ sizeof(xstats_names[count].name),
+ "%s",
+ rte_ixgbe_macsec_strings[i].name);
+ count++;
+ }
+ }
+
+ /* RX Priority Stats */
+ for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) {
+ for (i = 0; i < IXGBE_NB_RXQ_PRIO_VALUES; i++) {
+ if (rte_ixgbe_rxq_strings[stat].group_mask &
+ group_mask) {
+ snprintf(xstats_names[count].name,
+ sizeof(xstats_names[count].name),
+ "rx_priority%u_%s", i,
+ rte_ixgbe_rxq_strings[stat].name);
+ count++;
+ }
+ }
+ }
+
+ /* TX Priority Stats */
+ for (stat = 0; stat < IXGBE_NB_TXQ_PRIO_STATS; stat++) {
+ for (i = 0; i < IXGBE_NB_TXQ_PRIO_VALUES; i++) {
+ if (rte_ixgbe_txq_strings[stat].group_mask &
+ group_mask) {
+ snprintf(xstats_names[count].name,
+ sizeof(xstats_names[count].name),
+ "tx_priority%u_%s", i,
+ rte_ixgbe_txq_strings[stat].name);
+ count++;
+ }
+ }
+ }
+ }
+ return cnt_stats;
+}
+
static int ixgbevf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
struct rte_eth_xstat_name *xstats_names, unsigned limit)
{
@@ -3184,6 +3404,94 @@ static int ixgbevf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
return count;
}
+static int
+ixgbe_dev_xstats_get_by_group(struct rte_eth_dev *dev,
+ struct rte_eth_xstat *xstats,
+ unsigned int n, uint64_t group_mask)
+{
+ struct ixgbe_hw *hw =
+ IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct ixgbe_hw_stats *hw_stats =
+ IXGBE_DEV_PRIVATE_TO_STATS(dev->data->dev_private);
+ struct ixgbe_macsec_stats *macsec_stats =
+ IXGBE_DEV_PRIVATE_TO_MACSEC_STATS(
+ dev->data->dev_private);
+ uint64_t total_missed_rx, total_qbrc, total_qprc, total_qprdc;
+ unsigned int i, stat, count = 0;
+
+ count = ixgbe_xstats_calc_num_by_group(group_mask);
+
+ if (n < count)
+ return count;
+
+ total_missed_rx = 0;
+ total_qbrc = 0;
+ total_qprc = 0;
+ total_qprdc = 0;
+
+ ixgbe_read_stats_registers(hw, hw_stats, macsec_stats, &total_missed_rx,
+ &total_qbrc, &total_qprc, &total_qprdc);
+
+ /* If this is a reset xstats is NULL, and we have cleared the
+ * registers by reading them.
+ */
+ if (!xstats)
+ return 0;
+
+ /* Extended stats from ixgbe_hw_stats */
+ count = 0;
+ for (i = 0; i < IXGBE_NB_HW_STATS; i++) {
+ if (rte_ixgbe_stats_strings[i].group_mask & group_mask) {
+ xstats[count].value = *(uint64_t *)(((char *)hw_stats) +
+ rte_ixgbe_stats_strings[i].offset);
+ xstats[count].id = count;
+ count++;
+ }
+ }
+
+ /* MACsec Stats */
+ for (i = 0; i < IXGBE_NB_MACSEC_STATS; i++) {
+ if (rte_ixgbe_macsec_strings[i].group_mask & group_mask) {
+ xstats[count].value =
+ *(uint64_t *)(((char *)macsec_stats) +
+ rte_ixgbe_macsec_strings[i].offset);
+ xstats[count].id = count;
+ count++;
+ }
+ }
+
+ /* RX Priority Stats */
+ for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) {
+ for (i = 0; i < IXGBE_NB_RXQ_PRIO_VALUES; i++) {
+ if (rte_ixgbe_rxq_strings[stat].group_mask &
+ group_mask) {
+ xstats[count].value =
+ *(uint64_t *)(((char *)hw_stats) +
+ rte_ixgbe_rxq_strings[stat].offset +
+ (sizeof(uint64_t) * i));
+ xstats[count].id = count;
+ count++;
+ }
+ }
+ }
+
+ /* TX Priority Stats */
+ for (stat = 0; stat < IXGBE_NB_TXQ_PRIO_STATS; stat++) {
+ for (i = 0; i < IXGBE_NB_TXQ_PRIO_VALUES; i++) {
+ if (rte_ixgbe_txq_strings[stat].group_mask &
+ group_mask) {
+ xstats[count].value =
+ *(uint64_t *)(((char *)hw_stats) +
+ rte_ixgbe_txq_strings[stat].offset +
+ (sizeof(uint64_t) * i));
+ xstats[count].id = count;
+ count++;
+ }
+ }
+ }
+ return count;
+}
+
static void
ixgbe_dev_xstats_reset(struct rte_eth_dev *dev)
{
@@ -4097,7 +4405,8 @@ static int ixgbevf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
/* Disable any previous flow control settings */
mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
- mflcn_reg &= ~(IXGBE_MFLCN_RPFCE_SHIFT | IXGBE_MFLCN_RFCE|IXGBE_MFLCN_RPFCE);
+ mflcn_reg &= ~(IXGBE_MFLCN_RPFCE_SHIFT |
+ IXGBE_MFLCN_RFCE | IXGBE_MFLCN_RPFCE);
fccfg_reg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
fccfg_reg &= ~(IXGBE_FCCFG_TFCE_802_3X | IXGBE_FCCFG_TFCE_PRIORITY);
@@ -4206,7 +4515,8 @@ static int ixgbevf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
}
static int
-ixgbe_priority_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf)
+ixgbe_priority_flow_ctrl_set(struct rte_eth_dev *dev,
+ struct rte_eth_pfc_conf *pfc_conf)
{
int err;
uint32_t rx_buf_size;
--
1.9.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [dpdk-dev] [PATCH 4/4] app/proc_info: add support for xstats-name and xstats-group
2017-03-03 12:54 [dpdk-dev] [PATCH 0/4] extend API to retriving xstats by group and xstats by name Kuba Kozak
` (2 preceding siblings ...)
2017-03-03 12:54 ` [dpdk-dev] [PATCH 3/4] net/ixgbe: add grouping of xstats for ixgbe driver Kuba Kozak
@ 2017-03-03 12:54 ` Kuba Kozak
3 siblings, 0 replies; 8+ messages in thread
From: Kuba Kozak @ 2017-03-03 12:54 UTC (permalink / raw)
To: dev; +Cc: Jacek Piasecki, Kuba Kozak
From: Jacek Piasecki <jacekx.piasecki@intel.com>
This patch provides support for proc_info application
to allow printing single xstat value specified by its
name and printing xstats values specified by its group name.
New proc_info arguments:
--xstats-name NAME: to display single xstat value by NAME
--xstats-group GROUPNAME: to display group of xstats by GROUPNAME
Signed-off-by: Jacek Piasecki <jacekx.piasecki@intel.com>
Signed-off-by: Kuba Kozak <kubax.kozak@intel.com>
---
app/proc_info/main.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 111 insertions(+), 1 deletion(-)
diff --git a/app/proc_info/main.c b/app/proc_info/main.c
index 2c56d10..8826090 100644
--- a/app/proc_info/main.c
+++ b/app/proc_info/main.c
@@ -74,6 +74,11 @@
static uint32_t reset_xstats;
/**< Enable memory info. */
static uint32_t mem_info;
+/**< Enable displaying xstat name. */
+static uint32_t enable_xstats_name;
+static char *xstats_name;
+/**< Enable displaying xstat group name. */
+static uint64_t enable_xstats_group;
/**< display usage */
static void
@@ -85,6 +90,8 @@
" --stats: to display port statistics, enabled by default\n"
" --xstats: to display extended port statistics, disabled by "
"default\n"
+ " --xstats-name NAME: to display single xstat value by NAME\n"
+ " --xstats-group GROUPNAME: to display group of xstats by GROUPNAME\n"
" --stats-reset: to reset port statistics\n"
" --xstats-reset: to reset port extended statistics\n",
prgname);
@@ -128,6 +135,8 @@
{"stats-reset", 0, NULL, 0},
{"xstats", 0, NULL, 0},
{"xstats-reset", 0, NULL, 0},
+ {"xstats-name", required_argument, NULL, 1},
+ {"xstats-group", required_argument, NULL, 1},
{NULL, 0, 0, 0}
};
@@ -168,7 +177,27 @@
MAX_LONG_OPT_SZ))
reset_xstats = 1;
break;
-
+ case 1:
+ /* Print xstat single value given by name*/
+ if (!strncmp(long_option[option_index].name,
+ "xstats-name",
+ MAX_LONG_OPT_SZ)) {
+ enable_xstats_name = 1;
+ xstats_name = optarg;
+ printf("name:%s:%s\n",
+ long_option[option_index].name,
+ optarg);
+ }
+ /* Print xstat group values given by group name*/
+ else if (!strncmp(long_option[option_index].name,
+ "xstats-group",
+ MAX_LONG_OPT_SZ)) {
+ enable_xstats_group = atoi(optarg);
+ printf("name:%s:%s\n",
+ long_option[option_index].name,
+ optarg);
+ }
+ break;
default:
proc_info_usage(prgname);
return -1;
@@ -241,6 +270,82 @@
}
static void
+nic_xstats_by_name_display(__rte_unused uint8_t port_id,
+ __rte_unused char *name)
+{
+ struct rte_eth_xstat xstat;
+
+ printf("###### NIC statistics for port %-2d, statistic name '%s':\n",
+ port_id, name);
+
+ if (rte_eth_xstats_get_by_name(port_id, &xstat, name) == 0)
+ printf("%s: %"PRIu64"\n", name, xstat.value);
+ else
+ printf("Statistic not found...\n");
+
+}
+
+static void
+nic_xstats_by_group_display(__rte_unused uint8_t port_id,
+ __rte_unused uint64_t group_mask)
+{
+ struct rte_eth_xstat *xstats;
+ int cnt_xstats, idx_xstat;
+ struct rte_eth_xstat_name *xstats_names;
+
+ printf("###### NIC extended statistics for port %-2d,"
+ " group %-2lu #########\n",
+ port_id, group_mask);
+
+ /* Get count */
+ cnt_xstats = rte_eth_xstats_get_names_by_group(port_id, NULL, 0,
+ group_mask);
+ if (cnt_xstats < 0) {
+ printf("Error: Cannot get count of xstats\n");
+ return;
+ }
+
+ /* Get id-name lookup table */
+ xstats_names = malloc(sizeof(struct rte_eth_xstat_name) * cnt_xstats);
+ if (xstats_names == NULL) {
+ printf("Cannot allocate memory for xstats lookup\n");
+ return;
+ }
+
+ if (cnt_xstats != rte_eth_xstats_get_names_by_group(
+ port_id, xstats_names, cnt_xstats, group_mask)) {
+ printf("Error: Cannot get xstats lookup\n");
+ free(xstats_names);
+ return;
+ }
+
+ /* Get stats themselves */
+ xstats = malloc(sizeof(struct rte_eth_xstat) * cnt_xstats);
+ if (xstats == NULL) {
+ printf("Cannot allocate memory for xstats\n");
+ free(xstats_names);
+ return;
+ }
+
+ if (cnt_xstats != rte_eth_xstats_get_by_group(port_id, xstats,
+ cnt_xstats, group_mask)) {
+ printf("Error: Unable to get xstats\n");
+ free(xstats_names);
+ free(xstats);
+ return;
+ }
+
+ /* Display xstats */
+ for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++)
+ printf("%s: %"PRIu64"\n",
+ xstats_names[idx_xstat].name,
+ xstats[idx_xstat].value);
+ free(xstats_names);
+ free(xstats);
+
+}
+
+static void
nic_xstats_display(uint8_t port_id)
{
struct rte_eth_xstat_name *xstats_names;
@@ -360,6 +465,11 @@
nic_stats_clear(i);
else if (reset_xstats)
nic_xstats_clear(i);
+ else if (enable_xstats_group)
+ nic_xstats_by_group_display(i,
+ enable_xstats_group);
+ else if (enable_xstats_name)
+ nic_xstats_by_name_display(i, xstats_name);
}
}
--
1.9.1
^ permalink raw reply [flat|nested] 8+ messages in thread