* [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats @ 2016-04-15 14:44 Remy Horton 2016-04-15 14:44 ` [dpdk-dev] [RFC PATCH v1 1/3] rte: change xstats to use integer keys Remy Horton ` (5 more replies) 0 siblings, 6 replies; 71+ messages in thread From: Remy Horton @ 2016-04-15 14:44 UTC (permalink / raw) To: dev The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This RFC patchset changes the API for xstats to use integer identifiers instead of strings and implements this new API for the ixgbe driver. Others drivers to follow. -- Since this will involve API & ABI breakage as previously advertised, there are several design assumptions that need consideration: *) id-name & id-value pairs for both lookup and query Permits out-of-order and non-contigious returning of names/ids/values, even though expected implmentations would in practice return items in sorted order by id. Is this sufficent/desirable future proofing? Idea is to allow possibility of drivers returning partial statistics. *) Bulk name-id mapping lookup only At the moment individual lookup is not supported, as this would impose extra overheads on drivers. The assumption is that any end user would fetch all this data once on startup and then cache the mappings. *) Replacement or additional API This patch replaces the current xstats API, but there is no inherant reason beyond maintainability why this funtionality could not be in addition rather than a replacement. What is consensus on this? Comments welcome. Remy Horton (3): rte: change xstats to use integer keys drivers/net/ixgbe: change xstats to use integer keys examples/ethtool: add xstats display command drivers/net/ixgbe/ixgbe_ethdev.c | 87 +++++++++++++++++++++++++++++++---- examples/ethtool/ethtool-app/ethapp.c | 57 +++++++++++++++++++++++ lib/librte_ether/rte_ethdev.c | 87 +++++++++++++++++++++++++++++++---- lib/librte_ether/rte_ethdev.h | 38 +++++++++++++++ 4 files changed, 252 insertions(+), 17 deletions(-) -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [RFC PATCH v1 1/3] rte: change xstats to use integer keys 2016-04-15 14:44 [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats Remy Horton @ 2016-04-15 14:44 ` Remy Horton 2016-04-29 13:17 ` David Harton (dharton) 2016-04-15 14:44 ` [dpdk-dev] [RFC PATCH v1 2/3] drivers/net/ixgbe: change xstats to use integers Remy Horton ` (4 subsequent siblings) 5 siblings, 1 reply; 71+ messages in thread From: Remy Horton @ 2016-04-15 14:44 UTC (permalink / raw) To: dev, Thomas Monjalon Signed-off-by: Remy Horton <remy.horton@intel.com> --- lib/librte_ether/rte_ethdev.c | 87 +++++++++++++++++++++++++++++++++++++++---- lib/librte_ether/rte_ethdev.h | 38 +++++++++++++++++++ 2 files changed, 117 insertions(+), 8 deletions(-) diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index a31018e..cdd0685 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -1507,6 +1507,82 @@ rte_eth_stats_reset(uint8_t port_id) dev->data->rx_mbuf_alloc_failed = 0; } +static int +rte_eth_xstats_count(uint8_t port_id) +{ + struct rte_eth_dev *dev; + int count; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); + dev = &rte_eth_devices[port_id]; + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_names, -ENOTSUP); + count = (*dev->dev_ops->xstats_names)(dev, NULL, 0); + if (count >= 0) { + count += RTE_NB_STATS; + count += dev->data->nb_rx_queues * RTE_NB_RXQ_STATS; + count += dev->data->nb_tx_queues * RTE_NB_TXQ_STATS; + } + return count; +} + +int +rte_eth_xstats_names(uint8_t port_id, struct rte_eth_xstats_name *ptr_names, + unsigned limit) +{ + struct rte_eth_dev *dev; + int cnt_used_entries; + int cnt_expected_entries; + uint32_t idx, id_queue; + int offset; + + cnt_expected_entries = rte_eth_xstats_count(port_id); + if (cnt_expected_entries < 0 || ptr_names == NULL) + return cnt_expected_entries; + + if ((int)limit < cnt_expected_entries) + return -ERANGE; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); + dev = &rte_eth_devices[port_id]; + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_names, -ENOTSUP); + cnt_used_entries = (*dev->dev_ops->xstats_names)( + dev, ptr_names, limit); + + if (cnt_used_entries < 0) + return cnt_used_entries; + + offset = cnt_used_entries * RTE_ETH_XSTATS_NAME_SIZE; + for (idx = 0; idx < RTE_NB_STATS; idx++) { + snprintf(ptr_names[cnt_used_entries].name, + sizeof(ptr_names[0].name), + "%s", rte_stats_strings[idx].name); + offset += RTE_ETH_XSTATS_NAME_SIZE; + cnt_used_entries++; + } + for (id_queue = 0; id_queue < dev->data->nb_rx_queues; id_queue++) { + for (idx = 0; idx < RTE_NB_RXQ_STATS; idx++) { + snprintf(ptr_names[cnt_used_entries].name, + sizeof(ptr_names[0].name), + "rx_q%u%s", + id_queue, rte_rxq_stats_strings[idx].name); + offset += RTE_ETH_XSTATS_NAME_SIZE; + cnt_used_entries++; + } + + } + for (id_queue = 0; id_queue < dev->data->nb_tx_queues; id_queue++) { + for (idx = 0; idx < RTE_NB_TXQ_STATS; idx++) { + snprintf(ptr_names[cnt_used_entries].name, + sizeof(ptr_names[0].name), + "tx_q%u%s", + id_queue, rte_txq_stats_strings[idx].name); + offset += RTE_ETH_XSTATS_NAME_SIZE; + cnt_used_entries++; + } + } + return cnt_used_entries; +} + /* retrieve ethdev extended statistics */ int rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, @@ -1551,8 +1627,7 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, stats_ptr = RTE_PTR_ADD(ð_stats, rte_stats_strings[i].offset); val = *stats_ptr; - snprintf(xstats[count].name, sizeof(xstats[count].name), - "%s", rte_stats_strings[i].name); + xstats[count].key = count + xcount; xstats[count++].value = val; } @@ -1563,9 +1638,7 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, rte_rxq_stats_strings[i].offset + q * sizeof(uint64_t)); val = *stats_ptr; - snprintf(xstats[count].name, sizeof(xstats[count].name), - "rx_q%u_%s", q, - rte_rxq_stats_strings[i].name); + xstats[count].key = count + xcount; xstats[count++].value = val; } } @@ -1577,9 +1650,7 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, rte_txq_stats_strings[i].offset + q * sizeof(uint64_t)); val = *stats_ptr; - snprintf(xstats[count].name, sizeof(xstats[count].name), - "tx_q%u_%s", q, - rte_txq_stats_strings[i].name); + xstats[count].key = count + xcount; xstats[count++].value = val; } } diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index 022733e..4b81c59 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -941,10 +941,23 @@ struct rte_eth_txq_info { * structure. */ struct rte_eth_xstats { + /* FIXME: Remove name[] once remaining drivers converted */ char name[RTE_ETH_XSTATS_NAME_SIZE]; + uint64_t key; uint64_t value; }; +/** + * A name-key lookup element for extended statistics. + * + * This structure is used to map between names and ID numbers + * for extended ethernet statistics. + */ +struct rte_eth_xstats_name { + char name[RTE_ETH_XSTATS_NAME_SIZE]; + uint64_t id; +}; + #define ETH_DCB_NUM_TCS 8 #define ETH_MAX_VMDQ_POOL 64 @@ -1080,6 +1093,10 @@ typedef int (*eth_xstats_get_t)(struct rte_eth_dev *dev, typedef void (*eth_xstats_reset_t)(struct rte_eth_dev *dev); /**< @internal Reset extended stats of an Ethernet device. */ +typedef int (*eth_xstats_names_t)(struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, unsigned limit); +/**< @internal Get names of extended stats 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, @@ -1427,6 +1444,8 @@ struct eth_dev_ops { eth_stats_reset_t stats_reset; /**< Reset generic device statistics. */ eth_xstats_get_t xstats_get; /**< Get extended device statistics. */ eth_xstats_reset_t xstats_reset; /**< Reset extended device statistics. */ + eth_xstats_names_t xstats_names; + /**< Get names of extended statistics. */ eth_queue_stats_mapping_set_t queue_stats_mapping_set; /**< Configure per queue stat counter mapping. */ eth_dev_infos_get_t dev_infos_get; /**< Get device info. */ @@ -2279,6 +2298,25 @@ int rte_eth_stats_get(uint8_t port_id, struct rte_eth_stats *stats); void rte_eth_stats_reset(uint8_t port_id); /** + * Retrieve names of extended statistics of an Ethernet device. + * + * Names within ptr_strings will be aligned to RTE_ETH_XSTATS_NAME_SIZE and + * will be listed in ascending mapping order. + * + * @param port_id + * The port identifier of the Ethernet device. + * @param ptr_names + * Block of memory to insert names into. Must be at least limit in size. + * If NULL, function returns how many statistics are available. + * @param limit + * Capacity of ptr_strings (number of names). Ignored if ptr_string is NULL. + * @return + * If successful, number of statistics; negative on error. + */ +int rte_eth_xstats_names(uint8_t port_id, struct rte_eth_xstats_name *ptr_names, + unsigned limit); + +/** * Retrieve extended statistics of an Ethernet device. * * @param port_id -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v1 1/3] rte: change xstats to use integer keys 2016-04-15 14:44 ` [dpdk-dev] [RFC PATCH v1 1/3] rte: change xstats to use integer keys Remy Horton @ 2016-04-29 13:17 ` David Harton (dharton) 0 siblings, 0 replies; 71+ messages in thread From: David Harton (dharton) @ 2016-04-29 13:17 UTC (permalink / raw) To: Remy Horton, dev, Thomas Monjalon > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Remy Horton > Sent: Friday, April 15, 2016 10:44 AM > To: dev@dpdk.org; Thomas Monjalon <thomas.monjalon@6wind.com> > Subject: [dpdk-dev] [RFC PATCH v1 1/3] rte: change xstats to use integer > keys > > Signed-off-by: Remy Horton <remy.horton@intel.com> > --- > lib/librte_ether/rte_ethdev.c | 87 > +++++++++++++++++++++++++++++++++++++++---- > lib/librte_ether/rte_ethdev.h | 38 +++++++++++++++++++ > 2 files changed, 117 insertions(+), 8 deletions(-) > > diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c > index a31018e..cdd0685 100644 > --- a/lib/librte_ether/rte_ethdev.c > +++ b/lib/librte_ether/rte_ethdev.c > @@ -1507,6 +1507,82 @@ rte_eth_stats_reset(uint8_t port_id) > dev->data->rx_mbuf_alloc_failed = 0; > } > > +static int > +rte_eth_xstats_count(uint8_t port_id) Thanks for adding this. I believe an overt API is much more clear. > +{ > + struct rte_eth_dev *dev; > + int count; > + > + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); > + dev = &rte_eth_devices[port_id]; > + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_names, -ENOTSUP); > + count = (*dev->dev_ops->xstats_names)(dev, NULL, 0); > + if (count >= 0) { > + count += RTE_NB_STATS; > + count += dev->data->nb_rx_queues * RTE_NB_RXQ_STATS; > + count += dev->data->nb_tx_queues * RTE_NB_TXQ_STATS; > + } > + return count; > +} > + > +int > +rte_eth_xstats_names(uint8_t port_id, struct rte_eth_xstats_name > *ptr_names, > + unsigned limit) > +{ > + struct rte_eth_dev *dev; > + int cnt_used_entries; > + int cnt_expected_entries; > + uint32_t idx, id_queue; > + int offset; > + > + cnt_expected_entries = rte_eth_xstats_count(port_id); > + if (cnt_expected_entries < 0 || ptr_names == NULL) > + return cnt_expected_entries; I suggest we don't provide two ways to get the number of stats and that users always call rte_eth_xstats_count(). Recommend returning -EINVAL if ptr_names is NULL. > + > + if ((int)limit < cnt_expected_entries) > + return -ERANGE; > + > + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); > + dev = &rte_eth_devices[port_id]; > + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->xstats_names, -ENOTSUP); I think this check is too restrictive. There are drivers that do not provide device specific xstats today but the xstats API will still return the per q stats. Recommend skipping the device specific steps that follow. > + cnt_used_entries = (*dev->dev_ops->xstats_names)( > + dev, ptr_names, limit); > + > + if (cnt_used_entries < 0) > + return cnt_used_entries; > + > + offset = cnt_used_entries * RTE_ETH_XSTATS_NAME_SIZE; > + for (idx = 0; idx < RTE_NB_STATS; idx++) { > + snprintf(ptr_names[cnt_used_entries].name, > + sizeof(ptr_names[0].name), > + "%s", rte_stats_strings[idx].name); > + offset += RTE_ETH_XSTATS_NAME_SIZE; > + cnt_used_entries++; > + } > + for (id_queue = 0; id_queue < dev->data->nb_rx_queues; id_queue++) { > + for (idx = 0; idx < RTE_NB_RXQ_STATS; idx++) { > + snprintf(ptr_names[cnt_used_entries].name, > + sizeof(ptr_names[0].name), > + "rx_q%u%s", > + id_queue, rte_rxq_stats_strings[idx].name); > + offset += RTE_ETH_XSTATS_NAME_SIZE; > + cnt_used_entries++; > + } > + > + } > + for (id_queue = 0; id_queue < dev->data->nb_tx_queues; id_queue++) { > + for (idx = 0; idx < RTE_NB_TXQ_STATS; idx++) { > + snprintf(ptr_names[cnt_used_entries].name, > + sizeof(ptr_names[0].name), > + "tx_q%u%s", > + id_queue, rte_txq_stats_strings[idx].name); > + offset += RTE_ETH_XSTATS_NAME_SIZE; > + cnt_used_entries++; > + } > + } > + return cnt_used_entries; > +} > + > /* retrieve ethdev extended statistics */ > int > rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, > @@ -1551,8 +1627,7 @@ rte_eth_xstats_get(uint8_t port_id, struct > rte_eth_xstats *xstats, > stats_ptr = RTE_PTR_ADD(ð_stats, > rte_stats_strings[i].offset); > val = *stats_ptr; > - snprintf(xstats[count].name, sizeof(xstats[count].name), > - "%s", rte_stats_strings[i].name); > + xstats[count].key = count + xcount; Suggest setting adding: xstats[count].name[0] = '\0' until name is removed. > xstats[count++].value = val; > } > > @@ -1563,9 +1638,7 @@ rte_eth_xstats_get(uint8_t port_id, struct > rte_eth_xstats *xstats, > rte_rxq_stats_strings[i].offset + > q * sizeof(uint64_t)); > val = *stats_ptr; > - snprintf(xstats[count].name, sizeof(xstats[count].name), > - "rx_q%u_%s", q, > - rte_rxq_stats_strings[i].name); > + xstats[count].key = count + xcount; Same name comment. > xstats[count++].value = val; > } > } > @@ -1577,9 +1650,7 @@ rte_eth_xstats_get(uint8_t port_id, struct > rte_eth_xstats *xstats, > rte_txq_stats_strings[i].offset + > q * sizeof(uint64_t)); > val = *stats_ptr; > - snprintf(xstats[count].name, sizeof(xstats[count].name), > - "tx_q%u_%s", q, > - rte_txq_stats_strings[i].name); Same name comment. > + xstats[count].key = count + xcount; > xstats[count++].value = val; > } > } > diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h > index 022733e..4b81c59 100644 > --- a/lib/librte_ether/rte_ethdev.h > +++ b/lib/librte_ether/rte_ethdev.h > @@ -941,10 +941,23 @@ struct rte_eth_txq_info { > * structure. > */ > struct rte_eth_xstats { > + /* FIXME: Remove name[] once remaining drivers converted */ > char name[RTE_ETH_XSTATS_NAME_SIZE]; > + uint64_t key; > uint64_t value; > }; > > +/** > + * A name-key lookup element for extended statistics. > + * > + * This structure is used to map between names and ID numbers > + * for extended ethernet statistics. > + */ > +struct rte_eth_xstats_name { > + char name[RTE_ETH_XSTATS_NAME_SIZE]; > + uint64_t id; Suggest naming this key as well or modifying rte_eth_xstats to use id. > +}; > + > #define ETH_DCB_NUM_TCS 8 > #define ETH_MAX_VMDQ_POOL 64 > > @@ -1080,6 +1093,10 @@ typedef int (*eth_xstats_get_t)(struct rte_eth_dev > *dev, > typedef void (*eth_xstats_reset_t)(struct rte_eth_dev *dev); > /**< @internal Reset extended stats of an Ethernet device. */ > > +typedef int (*eth_xstats_names_t)(struct rte_eth_dev *dev, > + struct rte_eth_xstats_name *ptr_names, unsigned limit); > +/**< @internal Get names of extended stats 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, > @@ -1427,6 +1444,8 @@ struct eth_dev_ops { > eth_stats_reset_t stats_reset; /**< Reset generic device > statistics. */ > eth_xstats_get_t xstats_get; /**< Get extended device > statistics. */ > eth_xstats_reset_t xstats_reset; /**< Reset extended device > statistics. */ > + eth_xstats_names_t xstats_names; > + /**< Get names of extended statistics. */ > eth_queue_stats_mapping_set_t queue_stats_mapping_set; > /**< Configure per queue stat counter mapping. */ > eth_dev_infos_get_t dev_infos_get; /**< Get device info. */ > @@ -2279,6 +2298,25 @@ int rte_eth_stats_get(uint8_t port_id, struct > rte_eth_stats *stats); > void rte_eth_stats_reset(uint8_t port_id); > > /** > + * Retrieve names of extended statistics of an Ethernet device. > + * > + * Names within ptr_strings will be aligned to RTE_ETH_XSTATS_NAME_SIZE > and > + * will be listed in ascending mapping order. > + * > + * @param port_id > + * The port identifier of the Ethernet device. > + * @param ptr_names > + * Block of memory to insert names into. Must be at least limit in size. > + * If NULL, function returns how many statistics are available. > + * @param limit > + * Capacity of ptr_strings (number of names). Ignored if ptr_string is > NULL. > + * @return > + * If successful, number of statistics; negative on error. > + */ > +int rte_eth_xstats_names(uint8_t port_id, struct rte_eth_xstats_name > *ptr_names, > + unsigned limit); > + > +/** > * Retrieve extended statistics of an Ethernet device. > * > * @param port_id > -- > 2.5.5 Nice work. Regards, Dave ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [RFC PATCH v1 2/3] drivers/net/ixgbe: change xstats to use integers 2016-04-15 14:44 [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats Remy Horton 2016-04-15 14:44 ` [dpdk-dev] [RFC PATCH v1 1/3] rte: change xstats to use integer keys Remy Horton @ 2016-04-15 14:44 ` Remy Horton 2016-04-29 13:43 ` David Harton (dharton) 2016-04-15 14:44 ` [dpdk-dev] [RFC PATCH v1 3/3] examples/ethtool: add xstats display command Remy Horton ` (3 subsequent siblings) 5 siblings, 1 reply; 71+ messages in thread From: Remy Horton @ 2016-04-15 14:44 UTC (permalink / raw) To: dev, Helin Zhang Signed-off-by: Remy Horton <remy.horton@intel.com> --- drivers/net/ixgbe/ixgbe_ethdev.c | 87 +++++++++++++++++++++++++++++++++++----- 1 file changed, 78 insertions(+), 9 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c index 3f1ebc1..4d31fe9 100644 --- a/drivers/net/ixgbe/ixgbe_ethdev.c +++ b/drivers/net/ixgbe/ixgbe_ethdev.c @@ -179,6 +179,10 @@ 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_xstats_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, __rte_unused unsigned limit); +static int ixgbevf_dev_xstats_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, __rte_unused unsigned limit); static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id, uint8_t stat_idx, @@ -466,6 +470,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = { .xstats_get = ixgbe_dev_xstats_get, .stats_reset = ixgbe_dev_stats_reset, .xstats_reset = ixgbe_dev_xstats_reset, + .xstats_names = ixgbe_dev_xstats_names, .queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set, .dev_infos_get = ixgbe_dev_info_get, .dev_supported_ptypes_get = ixgbe_dev_supported_ptypes_get, @@ -555,6 +560,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = { .xstats_get = ixgbevf_dev_xstats_get, .stats_reset = ixgbevf_dev_stats_reset, .xstats_reset = ixgbevf_dev_stats_reset, + .xstats_names = ixgbevf_dev_xstats_names, .dev_close = ixgbevf_dev_close, .allmulticast_enable = ixgbevf_dev_allmulticast_enable, .allmulticast_disable = ixgbevf_dev_allmulticast_disable, @@ -2698,6 +2704,76 @@ ixgbe_xstats_calc_num(void) { (IXGBE_NB_TXQ_PRIO_STATS * 8); } +static int ixgbe_dev_xstats_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, __rte_unused unsigned limit) +{ + const unsigned cnt_stats = ixgbe_xstats_calc_num(); + unsigned stat, i, count, offset; + + if (ptr_names != NULL) { + count = 0; + offset = 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++) { + snprintf(ptr_names[count].name, + sizeof(ptr_names[count].name), + "%s", + rte_ixgbe_stats_strings[i].name); + count++; + offset += RTE_ETH_XSTATS_NAME_SIZE; + } + + /* RX Priority Stats */ + for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) { + for (i = 0; i < 8; i++) { + snprintf(ptr_names[count].name, + sizeof(ptr_names[count].name), + "rx_priority%u_%s", i, + rte_ixgbe_rxq_strings[stat].name); + count++; + offset += RTE_ETH_XSTATS_NAME_SIZE; + } + } + + /* TX Priority Stats */ + for (stat = 0; stat < IXGBE_NB_TXQ_PRIO_STATS; stat++) { + for (i = 0; i < 8; i++) { + snprintf(ptr_names[count].name, + sizeof(ptr_names[count].name), + "tx_priority%u_%s", i, + rte_ixgbe_txq_strings[stat].name); + count++; + offset += RTE_ETH_XSTATS_NAME_SIZE; + } + } + /* FIXME: Debugging check */ + if (cnt_stats != count) + return -EIO; + } + return cnt_stats; +} + +static int ixgbevf_dev_xstats_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, __rte_unused unsigned limit) +{ + unsigned i; + + if (limit < IXGBEVF_NB_XSTATS) + return -ENOMEM; + + if (ptr_names != NULL) + for (i = 0; i < IXGBEVF_NB_XSTATS; i++) + snprintf(ptr_names[i].name, + sizeof(ptr_names[i].name), + "%s", rte_ixgbevf_stats_strings[i].name); + return IXGBEVF_NB_XSTATS; +} + static int ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned n) @@ -2731,8 +2807,6 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* 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++; @@ -2741,9 +2815,6 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* RX Priority Stats */ for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) { for (i = 0; i < 8; i++) { - snprintf(xstats[count].name, sizeof(xstats[count].name), - "rx_priority%u_%s", i, - rte_ixgbe_rxq_strings[stat].name); xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_rxq_strings[stat].offset + (sizeof(uint64_t) * i)); @@ -2754,16 +2825,14 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* TX Priority Stats */ for (stat = 0; stat < IXGBE_NB_TXQ_PRIO_STATS; stat++) { for (i = 0; i < 8; i++) { - snprintf(xstats[count].name, sizeof(xstats[count].name), - "tx_priority%u_%s", i, - rte_ixgbe_txq_strings[stat].name); xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_txq_strings[stat].offset + (sizeof(uint64_t) * i)); count++; } } - + for (i = 0; i < count; i++) + xstats[i].key = i; return count; } -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v1 2/3] drivers/net/ixgbe: change xstats to use integers 2016-04-15 14:44 ` [dpdk-dev] [RFC PATCH v1 2/3] drivers/net/ixgbe: change xstats to use integers Remy Horton @ 2016-04-29 13:43 ` David Harton (dharton) 2016-05-03 12:22 ` Remy Horton 0 siblings, 1 reply; 71+ messages in thread From: David Harton (dharton) @ 2016-04-29 13:43 UTC (permalink / raw) To: Remy Horton, dev, Helin Zhang > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Remy Horton > Sent: Friday, April 15, 2016 10:44 AM > To: dev@dpdk.org; Helin Zhang <helin.zhang@intel.com> > Subject: [dpdk-dev] [RFC PATCH v1 2/3] drivers/net/ixgbe: change xstats to > use integers > > Signed-off-by: Remy Horton <remy.horton@intel.com> > --- > drivers/net/ixgbe/ixgbe_ethdev.c | 87 > +++++++++++++++++++++++++++++++++++----- > 1 file changed, 78 insertions(+), 9 deletions(-) > > diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c > b/drivers/net/ixgbe/ixgbe_ethdev.c > index 3f1ebc1..4d31fe9 100644 > --- a/drivers/net/ixgbe/ixgbe_ethdev.c > +++ b/drivers/net/ixgbe/ixgbe_ethdev.c > @@ -179,6 +179,10 @@ 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_xstats_names(__rte_unused struct rte_eth_dev *dev, > + struct rte_eth_xstats_name *ptr_names, __rte_unused unsigned limit); > +static int ixgbevf_dev_xstats_names(__rte_unused struct rte_eth_dev *dev, > + struct rte_eth_xstats_name *ptr_names, __rte_unused unsigned limit); > static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev, > uint16_t queue_id, > uint8_t stat_idx, > @@ -466,6 +470,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = { > .xstats_get = ixgbe_dev_xstats_get, > .stats_reset = ixgbe_dev_stats_reset, > .xstats_reset = ixgbe_dev_xstats_reset, > + .xstats_names = ixgbe_dev_xstats_names, > .queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set, > .dev_infos_get = ixgbe_dev_info_get, > .dev_supported_ptypes_get = ixgbe_dev_supported_ptypes_get, > @@ -555,6 +560,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = > { > .xstats_get = ixgbevf_dev_xstats_get, > .stats_reset = ixgbevf_dev_stats_reset, > .xstats_reset = ixgbevf_dev_stats_reset, > + .xstats_names = ixgbevf_dev_xstats_names, > .dev_close = ixgbevf_dev_close, > .allmulticast_enable = ixgbevf_dev_allmulticast_enable, > .allmulticast_disable = ixgbevf_dev_allmulticast_disable, > @@ -2698,6 +2704,76 @@ ixgbe_xstats_calc_num(void) { > (IXGBE_NB_TXQ_PRIO_STATS * 8); > } > > +static int ixgbe_dev_xstats_names(__rte_unused struct rte_eth_dev *dev, > + struct rte_eth_xstats_name *ptr_names, __rte_unused unsigned limit) > +{ > + const unsigned cnt_stats = ixgbe_xstats_calc_num(); > + unsigned stat, i, count, offset; > + > + if (ptr_names != NULL) { > + count = 0; > + offset = 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++) { > + snprintf(ptr_names[count].name, > + sizeof(ptr_names[count].name), > + "%s", > + rte_ixgbe_stats_strings[i].name); > + count++; > + offset += RTE_ETH_XSTATS_NAME_SIZE; > + } > + > + /* RX Priority Stats */ > + for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) { > + for (i = 0; i < 8; i++) { 8 seems magical. Is there a constant somewhere that can be used? > + snprintf(ptr_names[count].name, > + sizeof(ptr_names[count].name), > + "rx_priority%u_%s", i, > + rte_ixgbe_rxq_strings[stat].name); > + count++; > + offset += RTE_ETH_XSTATS_NAME_SIZE; > + } > + } > + > + /* TX Priority Stats */ > + for (stat = 0; stat < IXGBE_NB_TXQ_PRIO_STATS; stat++) { > + for (i = 0; i < 8; i++) { Same magic number. > + snprintf(ptr_names[count].name, > + sizeof(ptr_names[count].name), > + "tx_priority%u_%s", i, > + rte_ixgbe_txq_strings[stat].name); > + count++; > + offset += RTE_ETH_XSTATS_NAME_SIZE; > + } > + } > + /* FIXME: Debugging check */ Just a reminder to cleanup. > + if (cnt_stats != count) > + return -EIO; > + } > + return cnt_stats; > +} > + > +static int ixgbevf_dev_xstats_names(__rte_unused struct rte_eth_dev *dev, > + struct rte_eth_xstats_name *ptr_names, __rte_unused unsigned limit) > +{ > + unsigned i; > + > + if (limit < IXGBEVF_NB_XSTATS) Think this check has to be removed since rte_eth_xstats_count() calls with limit == 0. > + return -ENOMEM; > + > + if (ptr_names != NULL) > + for (i = 0; i < IXGBEVF_NB_XSTATS; i++) > + snprintf(ptr_names[i].name, > + sizeof(ptr_names[i].name), > + "%s", rte_ixgbevf_stats_strings[i].name); > + return IXGBEVF_NB_XSTATS; > +} > + > static int > ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats > *xstats, > unsigned n) > @@ -2731,8 +2807,6 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct > rte_eth_xstats *xstats, > /* 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); Forgot to add key/id. Also, same name comment as above. > xstats[count].value = *(uint64_t *)(((char *)hw_stats) + > rte_ixgbe_stats_strings[i].offset); > count++; > @@ -2741,9 +2815,6 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct > rte_eth_xstats *xstats, > /* RX Priority Stats */ > for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) { > for (i = 0; i < 8; i++) { > - snprintf(xstats[count].name, sizeof(xstats[count].name), > - "rx_priority%u_%s", i, > - rte_ixgbe_rxq_strings[stat].name); Add key/id...terminate name. > xstats[count].value = *(uint64_t *)(((char *)hw_stats) + > rte_ixgbe_rxq_strings[stat].offset + > (sizeof(uint64_t) * i)); > @@ -2754,16 +2825,14 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, > struct rte_eth_xstats *xstats, > /* TX Priority Stats */ > for (stat = 0; stat < IXGBE_NB_TXQ_PRIO_STATS; stat++) { > for (i = 0; i < 8; i++) { > - snprintf(xstats[count].name, sizeof(xstats[count].name), > - "tx_priority%u_%s", i, > - rte_ixgbe_txq_strings[stat].name); Add key/id...terminate name. > xstats[count].value = *(uint64_t *)(((char *)hw_stats) + > rte_ixgbe_txq_strings[stat].offset + > (sizeof(uint64_t) * i)); > count++; > } > } > - > + for (i = 0; i < count; i++) > + xstats[i].key = i; Suggest doing this in the loops above to be consistent with pass-thru and likely saves some instructions. Regards, Dave > return count; > } > > -- > 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v1 2/3] drivers/net/ixgbe: change xstats to use integers 2016-04-29 13:43 ` David Harton (dharton) @ 2016-05-03 12:22 ` Remy Horton 2016-05-03 13:40 ` David Harton (dharton) 0 siblings, 1 reply; 71+ messages in thread From: Remy Horton @ 2016-05-03 12:22 UTC (permalink / raw) To: David Harton (dharton), dev, Helin Zhang On 29/04/2016 14:43, David Harton (dharton) wrote: [..] >> + /* RX Priority Stats */ >> + for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) { >> + for (i = 0; i < 8; i++) { > > 8 seems magical. Is there a constant somewhere that can be used? Not that I'm aware of. I've made it a #define as a small cleanup. >> +static int ixgbevf_dev_xstats_names(__rte_unused struct rte_eth_dev *dev, >> + struct rte_eth_xstats_name *ptr_names, __rte_unused unsigned limit) >> +{ >> + unsigned i; >> + >> + if (limit < IXGBEVF_NB_XSTATS) > > Think this check has to be removed since rte_eth_xstats_count() calls with > limit == 0. Well spotted. It should only error-out if ptr_names is non-NULL. As an aside, I am wondering whether getting stats counts should itself be a seperate driver hook. ..Remy ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v1 2/3] drivers/net/ixgbe: change xstats to use integers 2016-05-03 12:22 ` Remy Horton @ 2016-05-03 13:40 ` David Harton (dharton) 0 siblings, 0 replies; 71+ messages in thread From: David Harton (dharton) @ 2016-05-03 13:40 UTC (permalink / raw) To: Remy Horton, dev, Helin Zhang > -----Original Message----- > From: Remy Horton [mailto:remy.horton@intel.com] > Sent: Tuesday, May 03, 2016 8:23 AM > To: David Harton (dharton) <dharton@cisco.com>; dev@dpdk.org; Helin Zhang > <helin.zhang@intel.com> > Subject: Re: [dpdk-dev] [RFC PATCH v1 2/3] drivers/net/ixgbe: change > xstats to use integers > > > On 29/04/2016 14:43, David Harton (dharton) wrote: > [..] > >> + /* RX Priority Stats */ > >> + for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) { > >> + for (i = 0; i < 8; i++) { > > > > 8 seems magical. Is there a constant somewhere that can be used? > > Not that I'm aware of. I've made it a #define as a small cleanup. > > > >> +static int ixgbevf_dev_xstats_names(__rte_unused struct rte_eth_dev > *dev, > >> + struct rte_eth_xstats_name *ptr_names, __rte_unused unsigned limit) > >> +{ > >> + unsigned i; > >> + > >> + if (limit < IXGBEVF_NB_XSTATS) > > > > Think this check has to be removed since rte_eth_xstats_count() calls > > with limit == 0. > > Well spotted. It should only error-out if ptr_names is non-NULL. > > As an aside, I am wondering whether getting stats counts should itself be > a seperate driver hook. I personally think it would be cleaner. Bug, I can also see the argument of keeping the vector table smaller and would conceded to others that felt strongly about it. I do really like having a separate external API to the user. A user should explicitly ask for the count. Cheers, Dave > > > ..Remy ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [RFC PATCH v1 3/3] examples/ethtool: add xstats display command 2016-04-15 14:44 [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats Remy Horton 2016-04-15 14:44 ` [dpdk-dev] [RFC PATCH v1 1/3] rte: change xstats to use integer keys Remy Horton 2016-04-15 14:44 ` [dpdk-dev] [RFC PATCH v1 2/3] drivers/net/ixgbe: change xstats to use integers Remy Horton @ 2016-04-15 14:44 ` Remy Horton 2016-04-20 16:03 ` [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats David Harton (dharton) ` (2 subsequent siblings) 5 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-04-15 14:44 UTC (permalink / raw) To: dev Signed-off-by: Remy Horton <remy.horton@intel.com> --- examples/ethtool/ethtool-app/ethapp.c | 57 +++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/examples/ethtool/ethtool-app/ethapp.c b/examples/ethtool/ethtool-app/ethapp.c index 2ed4796..16ae4e9 100644 --- a/examples/ethtool/ethtool-app/ethapp.c +++ b/examples/ethtool/ethtool-app/ethapp.c @@ -98,6 +98,8 @@ cmdline_parse_token_string_t pcmd_rxmode_token_cmd = TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "rxmode"); cmdline_parse_token_string_t pcmd_portstats_token_cmd = TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "portstats"); +cmdline_parse_token_string_t pcmd_xstats_token_cmd = + TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "xstats"); cmdline_parse_token_num_t pcmd_int_token_port = TOKEN_NUM_INITIALIZER(struct pcmd_int_params, port, UINT16); @@ -552,6 +554,49 @@ static void pcmd_portstats_callback(__rte_unused void *ptr_params, printf("Port %i: Error fetching statistics\n", params->port); } +static void pcmd_xstats_callback(__rte_unused void *ptr_params, + __rte_unused struct cmdline *ctx, + __rte_unused void *ptr_data) +{ + struct rte_eth_xstats xstats[256]; + struct pcmd_int_params *params = ptr_params; + int cnt_xstats, idx_xstat; + struct rte_eth_xstats_name *ptr_names; + + + if (!rte_eth_dev_is_valid_port(params->port)) { + printf("Error: Invalid port number %i\n", params->port); + return; + } + + cnt_xstats = rte_eth_xstats_names(params->port, NULL, 0); + if (cnt_xstats < 0) { + printf("Port %i: %s\n", params->port, strerror(-cnt_xstats)); + return; + } + printf("Number of xstats: %i\n", cnt_xstats); + ptr_names = malloc(sizeof(struct rte_eth_xstats_name) * cnt_xstats); + if (cnt_xstats != rte_eth_xstats_names( + params->port, ptr_names, cnt_xstats)) { + printf("Error: Fetched and expected counts mismatch\n"); + return; + } + + cnt_xstats = rte_eth_xstats_get(params->port, xstats, 256); + if (cnt_xstats < 0) { + printf("Error: Unable to get xstats (%s)\n", + strerror(-cnt_xstats)); + return; + } + for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++) { + /* Assume ptr_names[x].id = x */ + printf("%s: %lu\n", ptr_names[xstats[idx_xstat].key].name, + xstats[idx_xstat].value); + } + free(ptr_names); +} + + static void pcmd_ringparam_callback(__rte_unused void *ptr_params, __rte_unused struct cmdline *ctx, void *ptr_data) @@ -790,6 +835,17 @@ cmdline_parse_inst_t pcmd_portstats = { NULL }, }; +cmdline_parse_inst_t pcmd_xstats = { + .f = pcmd_xstats_callback, + .data = NULL, + .help_str = "xstats <port_id>\n" + " Print port eth xstats", + .tokens = { + (void *)&pcmd_xstats_token_cmd, + (void *)&pcmd_int_token_port, + NULL + }, +}; cmdline_parse_inst_t pcmd_ringparam = { .f = pcmd_ringparam_callback, .data = NULL, @@ -858,6 +914,7 @@ cmdline_parse_ctx_t list_prompt_commands[] = { (cmdline_parse_inst_t *)&pcmd_stop, (cmdline_parse_inst_t *)&pcmd_validate, (cmdline_parse_inst_t *)&pcmd_vlan, + (cmdline_parse_inst_t *)&pcmd_xstats, (cmdline_parse_inst_t *)&pcmd_quit, NULL }; -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats 2016-04-15 14:44 [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats Remy Horton ` (2 preceding siblings ...) 2016-04-15 14:44 ` [dpdk-dev] [RFC PATCH v1 3/3] examples/ethtool: add xstats display command Remy Horton @ 2016-04-20 16:03 ` David Harton (dharton) 2016-04-20 16:49 ` Mcnamara, John 2016-04-28 14:56 ` Tahhan, Maryam 2016-04-29 12:52 ` David Harton (dharton) 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 " Remy Horton 5 siblings, 2 replies; 71+ messages in thread From: David Harton (dharton) @ 2016-04-20 16:03 UTC (permalink / raw) To: Remy Horton, dev > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Remy Horton > Sent: Friday, April 15, 2016 10:44 AM > To: dev@dpdk.org > Subject: [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from > xstats > > The current extended ethernet statistics fetching involve doing several > string operations, which causes performance issues if there are lots of > statistics and/or network interfaces. This RFC patchset changes the API > for xstats to use integer identifiers instead of strings and implements > this new API for the ixgbe driver. Others drivers to follow. > > -- > > Since this will involve API & ABI breakage as previously advertised, there > are several design assumptions that need consideration: > > *) id-name & id-value pairs for both lookup and query Permits out-of-order > and non-contigious returning of names/ids/values, even though expected > implmentations would in practice return items in sorted order by id. Is > this sufficent/desirable future proofing? Idea is to allow possibility of > drivers returning partial statistics. I believe forcing drivers to match to a common id-space will become burdensome. If the stats id-space isn't common then matching strings is probably just as sufficient as long as drivers don't add/remove stats ad hoc between the time the device is initialized and removed. > > *) Bulk name-id mapping lookup only > At the moment individual lookup is not supported, as this would impose > extra overheads on drivers. The assumption is that any end user would > fetch all this data once on startup and then cache the mappings. I'm not sure I see the value of looking up a single stat from a user perspective. I can see where the drivers might say that some stats are less disruptive/etc but the user doesn't have that knowledge and wouldn't know how to take advantage. Usually all stats are grabbed multiple times and the changes noted during debug sessions. > > *) Replacement or additional API > This patch replaces the current xstats API, but there is no inherant > reason beyond maintainability why this funtionality could not be in > addition rather than a replacement. What is consensus on this? I came to the conclusion that replacing the existing API isn't necessary but rather extending it so backwards compatibility could be maintained during the previous discussions on this topic. However, if we want to go forward with cleaning up in order to reduce the support drivers provide I'm all for it. I still believe the API we develop should follow an "ethtool stats like" format as suggested earlier this year: extern int rte_eth_xstats_names_get(uint8_t port_id, struct rte_eth_xstats_name *names, unsigned n); extern int rte_eth_xstats_values_get(uint8_t port_id, uint64_t *values, unsigned n); Again, these could be provided alongside the existing API or replace it. I also like the idea you provided of a separate API to obtain the xstats count rather than deriving the count by calling one of the above functions with "dummy" values. Again, I can provide the patches for the changes I've made that align with this proposed API. I just never got any feedback on it when requested previously. Regards, Dave > > Comments welcome. > > Remy Horton (3): > rte: change xstats to use integer keys > drivers/net/ixgbe: change xstats to use integer keys > examples/ethtool: add xstats display command > > drivers/net/ixgbe/ixgbe_ethdev.c | 87 > +++++++++++++++++++++++++++++++---- > examples/ethtool/ethtool-app/ethapp.c | 57 +++++++++++++++++++++++ > lib/librte_ether/rte_ethdev.c | 87 > +++++++++++++++++++++++++++++++---- > lib/librte_ether/rte_ethdev.h | 38 +++++++++++++++ > 4 files changed, 252 insertions(+), 17 deletions(-) > > -- > 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats 2016-04-20 16:03 ` [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats David Harton (dharton) @ 2016-04-20 16:49 ` Mcnamara, John 2016-04-22 15:04 ` David Harton (dharton) 2016-04-28 14:56 ` Tahhan, Maryam 1 sibling, 1 reply; 71+ messages in thread From: Mcnamara, John @ 2016-04-20 16:49 UTC (permalink / raw) To: David Harton (dharton), Horton, Remy, dev; +Cc: Van Haaren, Harry > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of David Harton > (dharton) > Sent: Wednesday, April 20, 2016 5:04 PM > To: Horton, Remy <remy.horton@intel.com>; dev@dpdk.org > Subject: Re: [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from > xstats > > > Again, I can provide the patches for the changes I've made that align with > this proposed API. I just never got any feedback on it when requested > previously. Hi David, Perhaps it would be good to submit your patches, also with an RFC tag, so we can make a comparison. Thanks, John. -- ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats 2016-04-20 16:49 ` Mcnamara, John @ 2016-04-22 15:04 ` David Harton (dharton) 0 siblings, 0 replies; 71+ messages in thread From: David Harton (dharton) @ 2016-04-22 15:04 UTC (permalink / raw) To: Mcnamara, John, Horton, Remy, dev; +Cc: Van Haaren, Harry > -----Original Message----- > From: Mcnamara, John [mailto:john.mcnamara@intel.com] > Sent: Wednesday, April 20, 2016 12:50 PM > To: David Harton (dharton) <dharton@cisco.com>; Horton, Remy > <remy.horton@intel.com>; dev@dpdk.org > Cc: Van Haaren, Harry <harry.van.haaren@intel.com> > Subject: RE: [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from > xstats > > > -----Original Message----- > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of David Harton > > (dharton) > > Sent: Wednesday, April 20, 2016 5:04 PM > > To: Horton, Remy <remy.horton@intel.com>; dev@dpdk.org > > Subject: Re: [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations > > from xstats > > > > > > Again, I can provide the patches for the changes I've made that align > > with this proposed API. I just never got any feedback on it when > > requested previously. > > Hi David, > > Perhaps it would be good to submit your patches, also with an RFC tag, so > we can make a comparison. Will do. Timing is a little bad right now due to personal commitments. Can we wait a couple weeks? Thanks, Dave > > Thanks, > > John. > -- ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats 2016-04-20 16:03 ` [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats David Harton (dharton) 2016-04-20 16:49 ` Mcnamara, John @ 2016-04-28 14:56 ` Tahhan, Maryam 2016-04-28 15:58 ` David Harton (dharton) 1 sibling, 1 reply; 71+ messages in thread From: Tahhan, Maryam @ 2016-04-28 14:56 UTC (permalink / raw) To: David Harton (dharton), Horton, Remy, dev Cc: Mcnamara, John, Van Haaren, Harry > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of David Harton > (dharton) > Sent: Wednesday, April 20, 2016 5:04 PM > To: Horton, Remy <remy.horton@intel.com>; dev@dpdk.org > Subject: Re: [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations > from xstats > > > -----Original Message----- > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Remy Horton > > Sent: Friday, April 15, 2016 10:44 AM > > To: dev@dpdk.org > > Subject: [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from > > xstats > > > > The current extended ethernet statistics fetching involve doing > > several string operations, which causes performance issues if there > > are lots of statistics and/or network interfaces. This RFC patchset > > changes the API for xstats to use integer identifiers instead of > > strings and implements this new API for the ixgbe driver. Others > drivers to follow. > > > > -- > > > > Since this will involve API & ABI breakage as previously advertised, > > there are several design assumptions that need consideration: > > > > *) id-name & id-value pairs for both lookup and query Permits > > out-of-order and non-contigious returning of names/ids/values, even > > though expected implmentations would in practice return items in > > sorted order by id. Is this sufficent/desirable future proofing? Idea > > is to allow possibility of drivers returning partial statistics. > > I believe forcing drivers to match to a common id-space will become > burdensome. If the stats id-space isn't common then matching strings is > probably just as sufficient as long as drivers don't add/remove stats ad > hoc between the time the device is initialized and removed. I'm not aware of drivers adding/removing the stats ad hoc? The idea is to have a common-id space otherwise it will be a free for all and we won't have alignment across the drivers. I don't see it being any more burdensome than having a common register naming across the board which is what is there today. The advantage being that you don't have to pull the strings every time. > > > > > *) Bulk name-id mapping lookup only > > At the moment individual lookup is not supported, as this would impose > > extra overheads on drivers. The assumption is that any end user would > > fetch all this data once on startup and then cache the mappings. > > I'm not sure I see the value of looking up a single stat from a user > perspective. I can see where the drivers might say that some stats are > less disruptive/etc but the user doesn't have that knowledge and > wouldn't know how to take advantage. Usually all stats are grabbed > multiple times and the changes noted during debug sessions. > I believe Remy's change doesn't suggest/support individual lookup. It is just a statement that we don't want to burden drivers with individual stats lookups. > > > > *) Replacement or additional API > > This patch replaces the current xstats API, but there is no inherant > > reason beyond maintainability why this funtionality could not be in > > addition rather than a replacement. What is consensus on this? > > I came to the conclusion that replacing the existing API isn't necessary > but rather extending it so backwards compatibility could be maintained > during the previous discussions on this topic. However, if we want to go > forward with cleaning up in order to reduce the support drivers provide > I'm all for it. > > I still believe the API we develop should follow an "ethtool stats like" > format as suggested earlier this year: > > extern int rte_eth_xstats_names_get(uint8_t port_id, > struct rte_eth_xstats_name *names, unsigned n); extern int > rte_eth_xstats_values_get(uint8_t port_id, > uint64_t *values, unsigned n); > > Again, these could be provided alongside the existing API or replace it. I'm struggling a bit here. This is really what Remy has posted http://dpdk.org/dev/patchwork/patch/12094/ or am I missing something obvious? > > I also like the idea you provided of a separate API to obtain the xstats > count rather than deriving the count by calling one of the above > functions with "dummy" values. +1 > > Again, I can provide the patches for the changes I've made that align > with this proposed API. I just never got any feedback on it when > requested previously. I believe time is not in our favour on this front. If you have patches can you post them, otherwise can you please review the patchset that Remy has posted? Thanks in advance. BR Maryam ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats 2016-04-28 14:56 ` Tahhan, Maryam @ 2016-04-28 15:58 ` David Harton (dharton) 2016-04-29 10:21 ` Remy Horton 0 siblings, 1 reply; 71+ messages in thread From: David Harton (dharton) @ 2016-04-28 15:58 UTC (permalink / raw) To: Tahhan, Maryam, Horton, Remy, dev; +Cc: Mcnamara, John, Van Haaren, Harry > -----Original Message----- > From: Tahhan, Maryam [mailto:maryam.tahhan@intel.com] > Sent: Thursday, April 28, 2016 10:56 AM > To: David Harton (dharton) <dharton@cisco.com>; Horton, Remy > <remy.horton@intel.com>; dev@dpdk.org > Cc: Mcnamara, John <john.mcnamara@intel.com>; Van Haaren, Harry > <harry.van.haaren@intel.com> > Subject: RE: [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from > xstats > > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of David Harton > > (dharton) > > Sent: Wednesday, April 20, 2016 5:04 PM > > To: Horton, Remy <remy.horton@intel.com>; dev@dpdk.org > > Subject: Re: [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations > > from xstats > > > > > -----Original Message----- > > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Remy Horton > > > Sent: Friday, April 15, 2016 10:44 AM > > > To: dev@dpdk.org > > > Subject: [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from > > > xstats > > > > > > The current extended ethernet statistics fetching involve doing > > > several string operations, which causes performance issues if there > > > are lots of statistics and/or network interfaces. This RFC patchset > > > changes the API for xstats to use integer identifiers instead of > > > strings and implements this new API for the ixgbe driver. Others > > drivers to follow. > > > > > > -- > > > > > > Since this will involve API & ABI breakage as previously advertised, > > > there are several design assumptions that need consideration: > > > > > > *) id-name & id-value pairs for both lookup and query Permits > > > out-of-order and non-contigious returning of names/ids/values, even > > > though expected implmentations would in practice return items in > > > sorted order by id. Is this sufficent/desirable future proofing? > > > Idea is to allow possibility of drivers returning partial statistics. > > > > I believe forcing drivers to match to a common id-space will become > > burdensome. If the stats id-space isn't common then matching strings > > is probably just as sufficient as long as drivers don't add/remove > > stats ad hoc between the time the device is initialized and removed. > > I'm not aware of drivers adding/removing the stats ad hoc? The idea is to > have a common-id space otherwise it will be a free for all and we won't > have alignment across the drivers. I don't see it being any more > burdensome than having a common register naming across the board which is > what is there today. The advantage being that you don't have to pull the > strings every time. > > > > > > > > > *) Bulk name-id mapping lookup only > > > At the moment individual lookup is not supported, as this would > > > impose extra overheads on drivers. The assumption is that any end > > > user would fetch all this data once on startup and then cache the > mappings. > > > > I'm not sure I see the value of looking up a single stat from a user > > perspective. I can see where the drivers might say that some stats > > are less disruptive/etc but the user doesn't have that knowledge and > > wouldn't know how to take advantage. Usually all stats are grabbed > > multiple times and the changes noted during debug sessions. > > > > I believe Remy's change doesn't suggest/support individual lookup. It is > just a statement that we don't want to burden drivers with individual > stats lookups. > > > > > > > *) Replacement or additional API > > > This patch replaces the current xstats API, but there is no inherant > > > reason beyond maintainability why this funtionality could not be in > > > addition rather than a replacement. What is consensus on this? > > > > I came to the conclusion that replacing the existing API isn't > > necessary but rather extending it so backwards compatibility could be > > maintained during the previous discussions on this topic. However, if > > we want to go forward with cleaning up in order to reduce the support > > drivers provide I'm all for it. > > > > I still believe the API we develop should follow an "ethtool stats like" > > format as suggested earlier this year: > > > > extern int rte_eth_xstats_names_get(uint8_t port_id, > > struct rte_eth_xstats_name *names, unsigned n); extern int > > rte_eth_xstats_values_get(uint8_t port_id, > > uint64_t *values, unsigned n); > > > > Again, these could be provided alongside the existing API or replace it. > > I'm struggling a bit here. This is really what Remy has posted > http://dpdk.org/dev/patchwork/patch/12094/ or am I missing something > obvious? Maybe I misread the patch series or missed one but I don't see where stats can be obtained without copying strings? This is the real issue I raised originally. Having the ability to get the names without stats is useful, but, the real gain would be obtaining the stats without the names. > > > > > I also like the idea you provided of a separate API to obtain the > > xstats count rather than deriving the count by calling one of the > > above functions with "dummy" values. > > +1 > > > > > Again, I can provide the patches for the changes I've made that align > > with this proposed API. I just never got any feedback on it when > > requested previously. > > I believe time is not in our favour on this front. If you have patches can > you post them, otherwise can you please review the patchset that Remy has > posted? I'm working on it but I have some process I'm navigating. I'm hopeful I'll have the green light within a week if not sooner. I apologize... I'm pushing as hard as I can. If you need to proceed go ahead I completely understand. All I can say is that I have implemented the API above and converted all drivers that supported xstats in v2.2. Any new drivers that have added xstats support since would need to be added. I did not add "get the count" because it wasn't provided in the current API and instead followed the convention but I do believe overtly getting the count it is the better approach. Thanks, Dave ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats 2016-04-28 15:58 ` David Harton (dharton) @ 2016-04-29 10:21 ` Remy Horton 2016-04-29 12:15 ` David Harton (dharton) 0 siblings, 1 reply; 71+ messages in thread From: Remy Horton @ 2016-04-29 10:21 UTC (permalink / raw) To: David Harton (dharton), Tahhan, Maryam, dev Cc: Mcnamara, John, Van Haaren, Harry Morning, On 28/04/2016 16:58, David Harton (dharton) wrote: [..] >>>> *) id-name & id-value pairs for both lookup and query Permits >>>> out-of-order and non-contigious returning of names/ids/values, even >>>> though expected implmentations would in practice return items in >>>> sorted order by id. Is this sufficent/desirable future proofing? >>>> Idea is to allow possibility of drivers returning partial statistics. >>> >>> I believe forcing drivers to match to a common id-space will become >>> burdensome. If the stats id-space isn't common then matching strings >>> is probably just as sufficient as long as drivers don't add/remove >>> stats ad hoc between the time the device is initialized and removed. >> >> I'm not aware of drivers adding/removing the stats ad hoc? The idea is to >> have a common-id space otherwise it will be a free for all and we won't >> have alignment across the drivers. I don't see it being any more >> burdensome than having a common register naming across the board which is >> what is there today. The advantage being that you don't have to pull the >> strings every time. Returning both stats (id,value) and names (id,string) as pairs would allow (amoung other things) common ids but actually having common ids is not an intended goal of mine. I think the whole idea of common ids was implicity vetoed when the idea of ENUMs was thrown out. I opted for both stats and lookup to be provided as pairs because when it comes to APIs, I have a slight preference for having that bit of extra generality. Not sure its really worth it, so might change stats to just use id-indexed integer arrays (ethtool-like basically) rather than a typedef that includes the numeric id. >>>> *) Bulk name-id mapping lookup only [..] >>> I'm not sure I see the value of looking up a single stat from a user >>> perspective. I can see where the drivers might say that some stats >>> are less disruptive/etc but the user doesn't have that knowledge and >>> wouldn't know how to take advantage. Usually all stats are grabbed >>> multiple times and the changes noted during debug sessions. >>> >> >> I believe Remy's change doesn't suggest/support individual lookup. It is >> just a statement that we don't want to burden drivers with individual >> stats lookups. Correct. >>>> *) Replacement or additional API [..] >>> However, if >>> we want to go forward with cleaning up in order to reduce the support >>> drivers provide I'm all for it. Whether we want to do such a cleanup is my open question. > Maybe I misread the patch series or missed one but I don't see where > stats can be obtained without copying strings? This is the real issue I > raised originally. See http://dpdk.org/dev/patchwork/patch/12096/ where xstats[].key is used to lookup string from ptr_names[].name - I didn't delete the name field from rte_eth_xstats because doing so would cause a compile error with the drivers I've not yet converted. > I did not add "get the count" because it wasn't provided in the current API > and instead followed the convention but I do believe overtly getting the > count it is the better approach. I didn't either for the same reason, but if the API is going to be broken, I think it should be added. ..Remy ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats 2016-04-29 10:21 ` Remy Horton @ 2016-04-29 12:15 ` David Harton (dharton) 0 siblings, 0 replies; 71+ messages in thread From: David Harton (dharton) @ 2016-04-29 12:15 UTC (permalink / raw) To: Remy Horton, Tahhan, Maryam, dev; +Cc: Mcnamara, John, Van Haaren, Harry Happy Friday, > -----Original Message----- > From: Remy Horton [mailto:remy.horton@intel.com] > Sent: Friday, April 29, 2016 6:22 AM > To: David Harton (dharton) <dharton@cisco.com>; Tahhan, Maryam > <maryam.tahhan@intel.com>; dev@dpdk.org > Cc: Mcnamara, John <john.mcnamara@intel.com>; Van Haaren, Harry > <harry.van.haaren@intel.com> > Subject: Re: [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from > xstats > > Morning, > > On 28/04/2016 16:58, David Harton (dharton) wrote: [...] > > > Maybe I misread the patch series or missed one but I don't see where > > stats can be obtained without copying strings? This is the real issue > > I raised originally. > > See http://dpdk.org/dev/patchwork/patch/12096/ where xstats[].key is used > to lookup string from ptr_names[].name - I didn't delete the name field > from rte_eth_xstats because doing so would cause a compile error with the > drivers I've not yet converted. Ok, this was one of my fundamental hang ups. I didn't see any gain because of the way the proposal is being introduced. I guess you are saying that not only will drivers be added in future patch series but that you also intend to continue modifying the external API as well. I will start a clean thread and reply/review the provided patches and forgo my work. Cheers, Dave > > > > > I did not add "get the count" because it wasn't provided in the > > current API and instead followed the convention but I do believe > > overtly getting the count it is the better approach. > > I didn't either for the same reason, but if the API is going to be broken, > I think it should be added. > > > ..Remy ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats 2016-04-15 14:44 [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats Remy Horton ` (3 preceding siblings ...) 2016-04-20 16:03 ` [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats David Harton (dharton) @ 2016-04-29 12:52 ` David Harton (dharton) 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 " Remy Horton 5 siblings, 0 replies; 71+ messages in thread From: David Harton (dharton) @ 2016-04-29 12:52 UTC (permalink / raw) To: Remy Horton, dev > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Remy Horton > Sent: Friday, April 15, 2016 10:44 AM > To: dev@dpdk.org > Subject: [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from > xstats > > The current extended ethernet statistics fetching involve doing several > string operations, which causes performance issues if there are lots of > statistics and/or network interfaces. This RFC patchset changes the API > for xstats to use integer identifiers instead of strings and implements > this new API for the ixgbe driver. Others drivers to follow. > > -- > > Since this will involve API & ABI breakage as previously advertised, > there are several design assumptions that need consideration: > > *) id-name & id-value pairs for both lookup and query > Permits out-of-order and non-contigious returning of names/ids/values, > even though expected implmentations would in practice return items in > sorted order by id. Is this sufficent/desirable future proofing? Idea > is to allow possibility of drivers returning partial statistics. I think the key is that the order of the stats must always be honored and if that's the case then an id isn't necessary. However, if others want an id certainly doesn't hurt. I don't see drivers autonomously providing a subset of stats and users can filter out stats they don't want to their presentation layers. > > *) Bulk name-id mapping lookup only > At the moment individual lookup is not supported, as this would impose > extra overheads on drivers. The assumption is that any end user would > fetch all this data once on startup and then cache the mappings. Agreed. Similarly there is no need to return a partial list of stats as the presentation layers can filter. > > *) Replacement or additional API > This patch replaces the current xstats API, but there is no inherant > reason beyond maintainability why this funtionality could not be in > addition rather than a replacement. What is consensus on this? I suggest 3 new functions are added: - get number of xstats - get xstats names - get xstats values This facilitates: - parallel development within the release without breaking current usage - possibility of removing rte_eth_xstats_get() in following release Thanks for moving this forward, Dave > > Comments welcome. > > Remy Horton (3): > rte: change xstats to use integer keys > drivers/net/ixgbe: change xstats to use integer keys > examples/ethtool: add xstats display command > > drivers/net/ixgbe/ixgbe_ethdev.c | 87 > +++++++++++++++++++++++++++++++---- > examples/ethtool/ethtool-app/ethapp.c | 57 +++++++++++++++++++++++ > lib/librte_ether/rte_ethdev.c | 87 > +++++++++++++++++++++++++++++++---- > lib/librte_ether/rte_ethdev.h | 38 +++++++++++++++ > 4 files changed, 252 insertions(+), 17 deletions(-) > > -- > 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [RFC PATCH v2 0/3] Remove string operations from xstats 2016-04-15 14:44 [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats Remy Horton ` (4 preceding siblings ...) 2016-04-29 12:52 ` David Harton (dharton) @ 2016-05-06 11:11 ` Remy Horton 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 1/3] rte: change xstats to use integer keys Remy Horton ` (4 more replies) 5 siblings, 5 replies; 71+ messages in thread From: Remy Horton @ 2016-05-06 11:11 UTC (permalink / raw) To: dev The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This RFC patchset changes the API for xstats to use integer identifiers instead of strings and implements this new API for the ixgbe driver. Others drivers to follow. -- v2 changes: * Fetching xstats count now seperate API function * Added #define constants for some magic numbers * Fixed bug with virtual function count fetching * For non-xstats-supporting drivers, queue stats returned * Some refactoring/cleanups * Removed index assumption from example Remy Horton (3): rte: change xstats to use integer keys drivers/net/ixgbe: change xstats to use integer keys examples/ethtool: add xstats display command drivers/net/ixgbe/ixgbe_ethdev.c | 98 ++++++++++++++++++++++++++++----- examples/ethtool/ethtool-app/ethapp.c | 57 +++++++++++++++++++ lib/librte_ether/rte_ethdev.c | 100 +++++++++++++++++++++++++++++----- lib/librte_ether/rte_ethdev.h | 55 +++++++++++++++++++ 4 files changed, 284 insertions(+), 26 deletions(-) -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [RFC PATCH v2 1/3] rte: change xstats to use integer keys 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 " Remy Horton @ 2016-05-06 11:11 ` Remy Horton 2016-05-09 13:59 ` David Harton (dharton) ` (2 more replies) 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 2/3] drivers/net/ixgbe: change xstats to use integer id Remy Horton ` (3 subsequent siblings) 4 siblings, 3 replies; 71+ messages in thread From: Remy Horton @ 2016-05-06 11:11 UTC (permalink / raw) To: dev Signed-off-by: Remy Horton <remy.horton@intel.com> --- lib/librte_ether/rte_ethdev.c | 100 ++++++++++++++++++++++++++++++++++++------ lib/librte_ether/rte_ethdev.h | 55 +++++++++++++++++++++++ 2 files changed, 142 insertions(+), 13 deletions(-) diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index a31018e..29ba12c 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -112,7 +112,6 @@ static const struct rte_eth_xstats_name_off rte_txq_stats_strings[] = { #define RTE_NB_TXQ_STATS (sizeof(rte_txq_stats_strings) / \ sizeof(rte_txq_stats_strings[0])) - /** * The user application callback description. * @@ -1507,6 +1506,87 @@ rte_eth_stats_reset(uint8_t port_id) dev->data->rx_mbuf_alloc_failed = 0; } +int +rte_eth_xstats_count(uint8_t port_id) +{ + struct rte_eth_dev *dev; + int count; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); + dev = &rte_eth_devices[port_id]; + if (dev->dev_ops->xstats_names != NULL) { + count = (*dev->dev_ops->xstats_names)(dev, NULL, 0); + if (count < 0) + return count; + } else + count = 0; + count += RTE_NB_STATS; + count += dev->data->nb_rx_queues * RTE_NB_RXQ_STATS; + count += dev->data->nb_tx_queues * RTE_NB_TXQ_STATS; + return count; +} + +int +rte_eth_xstats_names(uint8_t port_id, struct rte_eth_xstats_name *ptr_names, + unsigned limit) +{ + struct rte_eth_dev *dev; + int cnt_used_entries; + int cnt_expected_entries; + uint32_t idx, id_queue; + + if (ptr_names == NULL) + return -EINVAL; + cnt_expected_entries = rte_eth_xstats_count(port_id); + if (cnt_expected_entries < 0) + return cnt_expected_entries; + if ((int)limit < cnt_expected_entries) + return -ERANGE; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); + dev = &rte_eth_devices[port_id]; + if (dev->dev_ops->xstats_names != NULL) { + cnt_used_entries = (*dev->dev_ops->xstats_names)( + dev, ptr_names, limit); + if (cnt_used_entries < 0) + return cnt_used_entries; + } else + /* Driver itself does not support extended stats, but + * still have basic stats. + */ + cnt_used_entries = 0; + + for (idx = 0; idx < RTE_NB_STATS; idx++) { + ptr_names[cnt_used_entries].id = cnt_used_entries; + snprintf(ptr_names[cnt_used_entries].name, + sizeof(ptr_names[0].name), + "%s", rte_stats_strings[idx].name); + cnt_used_entries++; + } + for (id_queue = 0; id_queue < dev->data->nb_rx_queues; id_queue++) { + for (idx = 0; idx < RTE_NB_RXQ_STATS; idx++) { + ptr_names[cnt_used_entries].id = cnt_used_entries; + snprintf(ptr_names[cnt_used_entries].name, + sizeof(ptr_names[0].name), + "rx_q%u%s", + id_queue, rte_rxq_stats_strings[idx].name); + cnt_used_entries++; + } + + } + for (id_queue = 0; id_queue < dev->data->nb_tx_queues; id_queue++) { + for (idx = 0; idx < RTE_NB_TXQ_STATS; idx++) { + ptr_names[cnt_used_entries].id = cnt_used_entries; + snprintf(ptr_names[cnt_used_entries].name, + sizeof(ptr_names[0].name), + "tx_q%u%s", + id_queue, rte_txq_stats_strings[idx].name); + cnt_used_entries++; + } + } + return cnt_used_entries; +} + /* retrieve ethdev extended statistics */ int rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, @@ -1551,8 +1631,8 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, stats_ptr = RTE_PTR_ADD(ð_stats, rte_stats_strings[i].offset); val = *stats_ptr; - snprintf(xstats[count].name, sizeof(xstats[count].name), - "%s", rte_stats_strings[i].name); + xstats[count].name[0] = '\0'; + xstats[count].id = count + xcount; xstats[count++].value = val; } @@ -1563,9 +1643,8 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, rte_rxq_stats_strings[i].offset + q * sizeof(uint64_t)); val = *stats_ptr; - snprintf(xstats[count].name, sizeof(xstats[count].name), - "rx_q%u_%s", q, - rte_rxq_stats_strings[i].name); + xstats[count].name[0] = '\0'; + xstats[count].id = count + xcount; xstats[count++].value = val; } } @@ -1577,9 +1656,8 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, rte_txq_stats_strings[i].offset + q * sizeof(uint64_t)); val = *stats_ptr; - snprintf(xstats[count].name, sizeof(xstats[count].name), - "tx_q%u_%s", q, - rte_txq_stats_strings[i].name); + xstats[count].name[0] = '\0'; + xstats[count].id = count + xcount; xstats[count++].value = val; } } @@ -1621,7 +1699,6 @@ set_queue_stats_mapping(uint8_t port_id, uint16_t queue_id, uint8_t stat_idx, (dev, queue_id, stat_idx, is_rx); } - int rte_eth_dev_set_tx_queue_stats_mapping(uint8_t port_id, uint16_t tx_queue_id, uint8_t stat_idx) @@ -1630,7 +1707,6 @@ rte_eth_dev_set_tx_queue_stats_mapping(uint8_t port_id, uint16_t tx_queue_id, STAT_QMAP_TX); } - int rte_eth_dev_set_rx_queue_stats_mapping(uint8_t port_id, uint16_t rx_queue_id, uint8_t stat_idx) @@ -1639,7 +1715,6 @@ rte_eth_dev_set_rx_queue_stats_mapping(uint8_t port_id, uint16_t rx_queue_id, STAT_QMAP_RX); } - void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info) { @@ -1699,7 +1774,6 @@ rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr) ether_addr_copy(&dev->data->mac_addrs[0], mac_addr); } - int rte_eth_dev_get_mtu(uint8_t port_id, uint16_t *mtu) { diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index 022733e..eaeb703 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -941,10 +941,23 @@ struct rte_eth_txq_info { * structure. */ struct rte_eth_xstats { + /* FIXME: Remove name[] once remaining drivers converted */ char name[RTE_ETH_XSTATS_NAME_SIZE]; + uint64_t id; uint64_t value; }; +/** + * A name-key lookup element for extended statistics. + * + * This structure is used to map between names and ID numbers + * for extended ethernet statistics. + */ +struct rte_eth_xstats_name { + char name[RTE_ETH_XSTATS_NAME_SIZE]; + uint64_t id; +}; + #define ETH_DCB_NUM_TCS 8 #define ETH_MAX_VMDQ_POOL 64 @@ -1080,6 +1093,13 @@ typedef int (*eth_xstats_get_t)(struct rte_eth_dev *dev, typedef void (*eth_xstats_reset_t)(struct rte_eth_dev *dev); /**< @internal Reset extended stats of an Ethernet device. */ +typedef int (*eth_xstats_names_t)(struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, unsigned limit); +/**< @internal Get names of extended stats of an Ethernet device. */ + +typedef int (*eth_xstats_count_t)(struct rte_eth_dev *dev); +/**< @internal Get count of extended stats 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, @@ -1427,6 +1447,10 @@ struct eth_dev_ops { eth_stats_reset_t stats_reset; /**< Reset generic device statistics. */ eth_xstats_get_t xstats_get; /**< Get extended device statistics. */ eth_xstats_reset_t xstats_reset; /**< Reset extended device statistics. */ + eth_xstats_names_t xstats_names; + /**< Get names of extended statistics. */ + eth_xstats_count_t xstats_count; + /**< Get number of extended statistics. */ eth_queue_stats_mapping_set_t queue_stats_mapping_set; /**< Configure per queue stat counter mapping. */ eth_dev_infos_get_t dev_infos_get; /**< Get device info. */ @@ -2279,6 +2303,37 @@ int rte_eth_stats_get(uint8_t port_id, struct rte_eth_stats *stats); void rte_eth_stats_reset(uint8_t port_id); /** + * Retrieve names of extended statistics of an Ethernet device. + * + * Names within ptr_strings will be aligned to RTE_ETH_XSTATS_NAME_SIZE and + * will be listed in ascending mapping order. + * + * @param port_id + * The port identifier of the Ethernet device. + * @param ptr_names + * Block of memory to insert names into. Must be at least limit in size. + * @param limit + * Capacity of ptr_strings (number of names). + * @return + * If successful, number of statistics; negative on error. + */ +int rte_eth_xstats_names(uint8_t port_id, struct rte_eth_xstats_name *ptr_names, + unsigned limit); + +/** + * Retrieve number of extended statistics of an Ethernet device. + * + * Names within ptr_strings will be aligned to RTE_ETH_XSTATS_NAME_SIZE and + * will be listed in ascending mapping order. + * + * @param port_id + * The port identifier of the Ethernet device. + * @return + * If successful, number of statistics; negative on error. + */ +int rte_eth_xstats_count(uint8_t port_id); + +/** * Retrieve extended statistics of an Ethernet device. * * @param port_id -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v2 1/3] rte: change xstats to use integer keys 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 1/3] rte: change xstats to use integer keys Remy Horton @ 2016-05-09 13:59 ` David Harton (dharton) 2016-05-10 8:58 ` Remy Horton 2016-05-12 16:17 ` Thomas Monjalon 2016-05-16 10:47 ` Tahhan, Maryam 2016-05-18 8:31 ` Tahhan, Maryam 2 siblings, 2 replies; 71+ messages in thread From: David Harton (dharton) @ 2016-05-09 13:59 UTC (permalink / raw) To: Remy Horton, dev > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Remy Horton > Sent: Friday, May 06, 2016 7:11 AM > To: dev@dpdk.org > Subject: [dpdk-dev] [RFC PATCH v2 1/3] rte: change xstats to use integer > keys > > Signed-off-by: Remy Horton <remy.horton@intel.com> > --- > lib/librte_ether/rte_ethdev.c | 100 ++++++++++++++++++++++++++++++++++++- > ----- > lib/librte_ether/rte_ethdev.h | 55 +++++++++++++++++++++++ > 2 files changed, 142 insertions(+), 13 deletions(-) > > diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c > index a31018e..29ba12c 100644 > --- a/lib/librte_ether/rte_ethdev.c > +++ b/lib/librte_ether/rte_ethdev.c > @@ -112,7 +112,6 @@ static const struct rte_eth_xstats_name_off > rte_txq_stats_strings[] = { > #define RTE_NB_TXQ_STATS (sizeof(rte_txq_stats_strings) / \ > sizeof(rte_txq_stats_strings[0])) > > - > /** > * The user application callback description. > * > @@ -1507,6 +1506,87 @@ rte_eth_stats_reset(uint8_t port_id) > dev->data->rx_mbuf_alloc_failed = 0; > } > > +int > +rte_eth_xstats_count(uint8_t port_id) > +{ > + struct rte_eth_dev *dev; > + int count; > + > + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); > + dev = &rte_eth_devices[port_id]; > + if (dev->dev_ops->xstats_names != NULL) { > + count = (*dev->dev_ops->xstats_names)(dev, NULL, 0); > + if (count < 0) > + return count; > + } else > + count = 0; > + count += RTE_NB_STATS; > + count += dev->data->nb_rx_queues * RTE_NB_RXQ_STATS; > + count += dev->data->nb_tx_queues * RTE_NB_TXQ_STATS; > + return count; > +} > + > +int > +rte_eth_xstats_names(uint8_t port_id, struct rte_eth_xstats_name > *ptr_names, > + unsigned limit) > +{ > + struct rte_eth_dev *dev; > + int cnt_used_entries; > + int cnt_expected_entries; > + uint32_t idx, id_queue; > + > + if (ptr_names == NULL) > + return -EINVAL; > + cnt_expected_entries = rte_eth_xstats_count(port_id); > + if (cnt_expected_entries < 0) > + return cnt_expected_entries; > + if ((int)limit < cnt_expected_entries) > + return -ERANGE; > + > + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); > + dev = &rte_eth_devices[port_id]; > + if (dev->dev_ops->xstats_names != NULL) { > + cnt_used_entries = (*dev->dev_ops->xstats_names)( > + dev, ptr_names, limit); > + if (cnt_used_entries < 0) > + return cnt_used_entries; > + } else > + /* Driver itself does not support extended stats, but > + * still have basic stats. > + */ > + cnt_used_entries = 0; > + > + for (idx = 0; idx < RTE_NB_STATS; idx++) { > + ptr_names[cnt_used_entries].id = cnt_used_entries; > + snprintf(ptr_names[cnt_used_entries].name, > + sizeof(ptr_names[0].name), > + "%s", rte_stats_strings[idx].name); > + cnt_used_entries++; > + } > + for (id_queue = 0; id_queue < dev->data->nb_rx_queues; id_queue++) { > + for (idx = 0; idx < RTE_NB_RXQ_STATS; idx++) { > + ptr_names[cnt_used_entries].id = cnt_used_entries; > + snprintf(ptr_names[cnt_used_entries].name, > + sizeof(ptr_names[0].name), > + "rx_q%u%s", > + id_queue, rte_rxq_stats_strings[idx].name); > + cnt_used_entries++; > + } > + > + } > + for (id_queue = 0; id_queue < dev->data->nb_tx_queues; id_queue++) { > + for (idx = 0; idx < RTE_NB_TXQ_STATS; idx++) { > + ptr_names[cnt_used_entries].id = cnt_used_entries; > + snprintf(ptr_names[cnt_used_entries].name, > + sizeof(ptr_names[0].name), > + "tx_q%u%s", > + id_queue, rte_txq_stats_strings[idx].name); > + cnt_used_entries++; > + } > + } > + return cnt_used_entries; > +} > + > /* retrieve ethdev extended statistics */ int > rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, @@ - > 1551,8 +1631,8 @@ rte_eth_xstats_get(uint8_t port_id, struct > rte_eth_xstats *xstats, > stats_ptr = RTE_PTR_ADD(ð_stats, > rte_stats_strings[i].offset); > val = *stats_ptr; > - snprintf(xstats[count].name, sizeof(xstats[count].name), > - "%s", rte_stats_strings[i].name); > + xstats[count].name[0] = '\0'; > + xstats[count].id = count + xcount; > xstats[count++].value = val; > } > > @@ -1563,9 +1643,8 @@ rte_eth_xstats_get(uint8_t port_id, struct > rte_eth_xstats *xstats, > rte_rxq_stats_strings[i].offset + > q * sizeof(uint64_t)); > val = *stats_ptr; > - snprintf(xstats[count].name, sizeof(xstats[count].name), > - "rx_q%u_%s", q, > - rte_rxq_stats_strings[i].name); > + xstats[count].name[0] = '\0'; > + xstats[count].id = count + xcount; > xstats[count++].value = val; > } > } > @@ -1577,9 +1656,8 @@ rte_eth_xstats_get(uint8_t port_id, struct > rte_eth_xstats *xstats, > rte_txq_stats_strings[i].offset + > q * sizeof(uint64_t)); > val = *stats_ptr; > - snprintf(xstats[count].name, sizeof(xstats[count].name), > - "tx_q%u_%s", q, > - rte_txq_stats_strings[i].name); > + xstats[count].name[0] = '\0'; > + xstats[count].id = count + xcount; > xstats[count++].value = val; > } > } > @@ -1621,7 +1699,6 @@ set_queue_stats_mapping(uint8_t port_id, uint16_t > queue_id, uint8_t stat_idx, > (dev, queue_id, stat_idx, is_rx); > } > > - Not sure how the community feels about white-space only changes. Just mentioning in case some folks get excited about it. One here and a few below. > int > rte_eth_dev_set_tx_queue_stats_mapping(uint8_t port_id, uint16_t > tx_queue_id, > uint8_t stat_idx) > @@ -1630,7 +1707,6 @@ rte_eth_dev_set_tx_queue_stats_mapping(uint8_t > port_id, uint16_t tx_queue_id, > STAT_QMAP_TX); > } > > - > int > rte_eth_dev_set_rx_queue_stats_mapping(uint8_t port_id, uint16_t > rx_queue_id, > uint8_t stat_idx) > @@ -1639,7 +1715,6 @@ rte_eth_dev_set_rx_queue_stats_mapping(uint8_t > port_id, uint16_t rx_queue_id, > STAT_QMAP_RX); > } > > - > void > rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info) > { @@ -1699,7 +1774,6 @@ rte_eth_macaddr_get(uint8_t port_id, struct > ether_addr *mac_addr) > ether_addr_copy(&dev->data->mac_addrs[0], mac_addr); } > > - > int > rte_eth_dev_get_mtu(uint8_t port_id, uint16_t *mtu) { diff --git > a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index > 022733e..eaeb703 100644 > --- a/lib/librte_ether/rte_ethdev.h > +++ b/lib/librte_ether/rte_ethdev.h > @@ -941,10 +941,23 @@ struct rte_eth_txq_info { > * structure. > */ > struct rte_eth_xstats { > + /* FIXME: Remove name[] once remaining drivers converted */ > char name[RTE_ETH_XSTATS_NAME_SIZE]; > + uint64_t id; > uint64_t value; > }; > > +/** > + * A name-key lookup element for extended statistics. > + * > + * This structure is used to map between names and ID numbers > + * for extended ethernet statistics. > + */ > +struct rte_eth_xstats_name { > + char name[RTE_ETH_XSTATS_NAME_SIZE]; > + uint64_t id; > +}; > + > #define ETH_DCB_NUM_TCS 8 > #define ETH_MAX_VMDQ_POOL 64 > > @@ -1080,6 +1093,13 @@ typedef int (*eth_xstats_get_t)(struct rte_eth_dev > *dev, typedef void (*eth_xstats_reset_t)(struct rte_eth_dev *dev); /**< > @internal Reset extended stats of an Ethernet device. */ > > +typedef int (*eth_xstats_names_t)(struct rte_eth_dev *dev, > + struct rte_eth_xstats_name *ptr_names, unsigned limit); /**< > @internal > +Get names of extended stats of an Ethernet device. */ > + > +typedef int (*eth_xstats_count_t)(struct rte_eth_dev *dev); /**< > +@internal Get count of extended stats 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, > @@ -1427,6 +1447,10 @@ struct eth_dev_ops { > eth_stats_reset_t stats_reset; /**< Reset generic device > statistics. */ > eth_xstats_get_t xstats_get; /**< Get extended device > statistics. */ > eth_xstats_reset_t xstats_reset; /**< Reset extended device > statistics. */ > + eth_xstats_names_t xstats_names; > + /**< Get names of extended statistics. */ > + eth_xstats_count_t xstats_count; > + /**< Get number of extended statistics. */ > eth_queue_stats_mapping_set_t queue_stats_mapping_set; > /**< Configure per queue stat counter mapping. */ > eth_dev_infos_get_t dev_infos_get; /**< Get device info. */ > @@ -2279,6 +2303,37 @@ int rte_eth_stats_get(uint8_t port_id, struct > rte_eth_stats *stats); void rte_eth_stats_reset(uint8_t port_id); > > /** > + * Retrieve names of extended statistics of an Ethernet device. > + * > + * Names within ptr_strings will be aligned to RTE_ETH_XSTATS_NAME_SIZE > +and > + * will be listed in ascending mapping order. > + * > + * @param port_id > + * The port identifier of the Ethernet device. > + * @param ptr_names > + * Block of memory to insert names into. Must be at least limit in size. > + * @param limit > + * Capacity of ptr_strings (number of names). > + * @return > + * If successful, number of statistics; negative on error. > + */ > +int rte_eth_xstats_names(uint8_t port_id, struct rte_eth_xstats_name > *ptr_names, > + unsigned limit); > + > +/** > + * Retrieve number of extended statistics of an Ethernet device. > + * > + * Names within ptr_strings will be aligned to RTE_ETH_XSTATS_NAME_SIZE > +and > + * will be listed in ascending mapping order. > + * > + * @param port_id > + * The port identifier of the Ethernet device. > + * @return > + * If successful, number of statistics; negative on error. > + */ > +int rte_eth_xstats_count(uint8_t port_id); > + > +/** > * Retrieve extended statistics of an Ethernet device. > * > * @param port_id > -- > 2.5.5 Acked-by: David Harton <dharton@cisco.com> ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v2 1/3] rte: change xstats to use integer keys 2016-05-09 13:59 ` David Harton (dharton) @ 2016-05-10 8:58 ` Remy Horton 2016-05-12 16:17 ` Thomas Monjalon 1 sibling, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-05-10 8:58 UTC (permalink / raw) To: David Harton (dharton), dev On 09/05/2016 14:59, David Harton (dharton) wrote: [..] >> } >> >> - > > Not sure how the community feels about white-space only changes. > Just mentioning in case some folks get excited about it. One here and a few below. I doubt it'll be showstopper. In any case hoping to get a v3 out that converts the 4 other drivers that have xstats. ..Remy ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v2 1/3] rte: change xstats to use integer keys 2016-05-09 13:59 ` David Harton (dharton) 2016-05-10 8:58 ` Remy Horton @ 2016-05-12 16:17 ` Thomas Monjalon 1 sibling, 0 replies; 71+ messages in thread From: Thomas Monjalon @ 2016-05-12 16:17 UTC (permalink / raw) To: David Harton (dharton), Remy Horton; +Cc: dev 2016-05-09 13:59, David Harton: > > } > > > > - > > Not sure how the community feels about white-space only changes. > Just mentioning in case some folks get excited about it. One here and a few below. It's a trivial cleanup. No problem I think. ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v2 1/3] rte: change xstats to use integer keys 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 1/3] rte: change xstats to use integer keys Remy Horton 2016-05-09 13:59 ` David Harton (dharton) @ 2016-05-16 10:47 ` Tahhan, Maryam 2016-05-18 8:31 ` Tahhan, Maryam 2 siblings, 0 replies; 71+ messages in thread From: Tahhan, Maryam @ 2016-05-16 10:47 UTC (permalink / raw) To: Horton, Remy, dev > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Remy Horton > Sent: Friday, May 6, 2016 12:11 PM > To: dev@dpdk.org > Subject: [dpdk-dev] [RFC PATCH v2 1/3] rte: change xstats to use integer > keys > > Signed-off-by: Remy Horton <remy.horton@intel.com> > --- Acked-by: Maryam Tahhan <maryam.tahhan@intel.com> ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v2 1/3] rte: change xstats to use integer keys 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 1/3] rte: change xstats to use integer keys Remy Horton 2016-05-09 13:59 ` David Harton (dharton) 2016-05-16 10:47 ` Tahhan, Maryam @ 2016-05-18 8:31 ` Tahhan, Maryam 2016-05-18 8:45 ` Remy Horton 2 siblings, 1 reply; 71+ messages in thread From: Tahhan, Maryam @ 2016-05-18 8:31 UTC (permalink / raw) To: Horton, Remy, dev <snip> > uint8_t stat_idx, > @@ -1427,6 +1447,10 @@ struct eth_dev_ops { > eth_stats_reset_t stats_reset; /**< Reset generic device > statistics. */ > eth_xstats_get_t xstats_get; /**< Get extended device > statistics. */ > eth_xstats_reset_t xstats_reset; /**< Reset extended > device statistics. */ > + eth_xstats_names_t xstats_names; > + /**< Get names of extended statistics. */ > + eth_xstats_count_t xstats_count; > + /**< Get number of extended statistics. */ Hi Remy While reviewing the second patch in this patchset I noticed you aren't actually using eth_xstats_count_t xstats_count in the eth_dev_ops to retrieve the count in the driver. Do you still need xstats_count? BR Maryam <snip> ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v2 1/3] rte: change xstats to use integer keys 2016-05-18 8:31 ` Tahhan, Maryam @ 2016-05-18 8:45 ` Remy Horton 0 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-05-18 8:45 UTC (permalink / raw) To: Tahhan, Maryam, dev On 18/05/2016 09:31, Tahhan, Maryam wrote: [..] >> + eth_xstats_count_t xstats_count; >> + /**< Get number of extended statistics. */ > > Hi Remy > While reviewing the second patch in this patchset I noticed you aren't actually using > eth_xstats_count_t xstats_count in the eth_dev_ops to retrieve the count in the driver. > Do you still need xstats_count? Well spotted - bit of dead code that slipped through the net when I decided to use the existing convention for the driver-side interface. Currently working on a v3 that will convert all the drivers, so will fix in that patchset. ..Remy ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [RFC PATCH v2 2/3] drivers/net/ixgbe: change xstats to use integer id 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 " Remy Horton 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 1/3] rte: change xstats to use integer keys Remy Horton @ 2016-05-06 11:11 ` Remy Horton 2016-05-09 14:06 ` David Harton (dharton) 2016-05-18 8:41 ` Tahhan, Maryam 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 3/3] examples/ethtool: add xstats display command Remy Horton ` (2 subsequent siblings) 4 siblings, 2 replies; 71+ messages in thread From: Remy Horton @ 2016-05-06 11:11 UTC (permalink / raw) To: dev Signed-off-by: Remy Horton <remy.horton@intel.com> --- drivers/net/ixgbe/ixgbe_ethdev.c | 98 ++++++++++++++++++++++++++++++++++------ 1 file changed, 85 insertions(+), 13 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c index 3f1ebc1..3ff8bae 100644 --- a/drivers/net/ixgbe/ixgbe_ethdev.c +++ b/drivers/net/ixgbe/ixgbe_ethdev.c @@ -179,6 +179,10 @@ 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_xstats_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, __rte_unused unsigned limit); +static int ixgbevf_dev_xstats_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, __rte_unused unsigned limit); static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id, uint8_t stat_idx, @@ -466,6 +470,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = { .xstats_get = ixgbe_dev_xstats_get, .stats_reset = ixgbe_dev_stats_reset, .xstats_reset = ixgbe_dev_xstats_reset, + .xstats_names = ixgbe_dev_xstats_names, .queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set, .dev_infos_get = ixgbe_dev_info_get, .dev_supported_ptypes_get = ixgbe_dev_supported_ptypes_get, @@ -555,6 +560,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = { .xstats_get = ixgbevf_dev_xstats_get, .stats_reset = ixgbevf_dev_stats_reset, .xstats_reset = ixgbevf_dev_stats_reset, + .xstats_names = ixgbevf_dev_xstats_names, .dev_close = ixgbevf_dev_close, .allmulticast_enable = ixgbevf_dev_allmulticast_enable, .allmulticast_disable = ixgbevf_dev_allmulticast_disable, @@ -685,6 +691,7 @@ static const struct rte_ixgbe_xstats_name_off rte_ixgbe_rxq_strings[] = { #define IXGBE_NB_RXQ_PRIO_STATS (sizeof(rte_ixgbe_rxq_strings) / \ sizeof(rte_ixgbe_rxq_strings[0])) +#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)}, @@ -695,6 +702,7 @@ static const struct rte_ixgbe_xstats_name_off rte_ixgbe_txq_strings[] = { #define IXGBE_NB_TXQ_PRIO_STATS (sizeof(rte_ixgbe_txq_strings) / \ sizeof(rte_ixgbe_txq_strings[0])) +#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)}, @@ -2694,8 +2702,75 @@ ixgbe_dev_stats_reset(struct rte_eth_dev *dev) /* This function calculates the number of xstats based on the current config */ static unsigned ixgbe_xstats_calc_num(void) { - return IXGBE_NB_HW_STATS + (IXGBE_NB_RXQ_PRIO_STATS * 8) + - (IXGBE_NB_TXQ_PRIO_STATS * 8); + return IXGBE_NB_HW_STATS + + (IXGBE_NB_RXQ_PRIO_STATS * IXGBE_NB_RXQ_PRIO_VALUES) + + (IXGBE_NB_TXQ_PRIO_STATS * IXGBE_NB_TXQ_PRIO_VALUES); +} + +static int ixgbe_dev_xstats_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, __rte_unused unsigned limit) +{ + const unsigned cnt_stats = ixgbe_xstats_calc_num(); + unsigned stat, i, count; + + if (ptr_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++) { + ptr_names[count].id = count; + snprintf(ptr_names[count].name, + sizeof(ptr_names[count].name), + "%s", + rte_ixgbe_stats_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++) { + ptr_names[count].id = count; + snprintf(ptr_names[count].name, + sizeof(ptr_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++) { + ptr_names[count].id = count; + snprintf(ptr_names[count].name, + sizeof(ptr_names[count].name), + "tx_priority%u_%s", i, + rte_ixgbe_txq_strings[stat].name); + count++; + } + } + } + return cnt_stats; +} + +static int ixgbevf_dev_xstats_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, unsigned limit) +{ + unsigned i; + + if (limit < IXGBEVF_NB_XSTATS && ptr_names != NULL) + return -ENOMEM; + + if (ptr_names != NULL) + for (i = 0; i < IXGBEVF_NB_XSTATS; i++) + snprintf(ptr_names[i].name, + sizeof(ptr_names[i].name), + "%s", rte_ixgbevf_stats_strings[i].name); + return IXGBEVF_NB_XSTATS; } static int @@ -2731,8 +2806,8 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* 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].id = count; + xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_stats_strings[i].offset); count++; @@ -2740,10 +2815,9 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* RX Priority Stats */ for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) { - for (i = 0; i < 8; i++) { - snprintf(xstats[count].name, sizeof(xstats[count].name), - "rx_priority%u_%s", i, - rte_ixgbe_rxq_strings[stat].name); + for (i = 0; i < IXGBE_NB_RXQ_PRIO_VALUES; i++) { + xstats[count].id = count; + xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_rxq_strings[stat].offset + (sizeof(uint64_t) * i)); @@ -2753,17 +2827,15 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* TX Priority Stats */ for (stat = 0; stat < IXGBE_NB_TXQ_PRIO_STATS; stat++) { - for (i = 0; i < 8; i++) { - snprintf(xstats[count].name, sizeof(xstats[count].name), - "tx_priority%u_%s", i, - rte_ixgbe_txq_strings[stat].name); + for (i = 0; i < IXGBE_NB_TXQ_PRIO_VALUES; i++) { + xstats[count].id = count; + xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_txq_strings[stat].offset + (sizeof(uint64_t) * i)); count++; } } - return count; } -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v2 2/3] drivers/net/ixgbe: change xstats to use integer id 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 2/3] drivers/net/ixgbe: change xstats to use integer id Remy Horton @ 2016-05-09 14:06 ` David Harton (dharton) 2016-05-18 8:41 ` Tahhan, Maryam 1 sibling, 0 replies; 71+ messages in thread From: David Harton (dharton) @ 2016-05-09 14:06 UTC (permalink / raw) To: Remy Horton, dev > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Remy Horton > Sent: Friday, May 06, 2016 7:11 AM > To: dev@dpdk.org > Subject: [dpdk-dev] [RFC PATCH v2 2/3] drivers/net/ixgbe: change xstats to > use integer id > > Signed-off-by: Remy Horton <remy.horton@intel.com> > --- > drivers/net/ixgbe/ixgbe_ethdev.c | 98 ++++++++++++++++++++++++++++++++++- > ----- > 1 file changed, 85 insertions(+), 13 deletions(-) > > diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c > b/drivers/net/ixgbe/ixgbe_ethdev.c > index 3f1ebc1..3ff8bae 100644 > --- a/drivers/net/ixgbe/ixgbe_ethdev.c > +++ b/drivers/net/ixgbe/ixgbe_ethdev.c > @@ -179,6 +179,10 @@ 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_xstats_names(__rte_unused struct rte_eth_dev *dev, > + struct rte_eth_xstats_name *ptr_names, __rte_unused unsigned limit); > +static int ixgbevf_dev_xstats_names(__rte_unused struct rte_eth_dev *dev, > + struct rte_eth_xstats_name *ptr_names, __rte_unused unsigned limit); > static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev, > uint16_t queue_id, > uint8_t stat_idx, > @@ -466,6 +470,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = { > .xstats_get = ixgbe_dev_xstats_get, > .stats_reset = ixgbe_dev_stats_reset, > .xstats_reset = ixgbe_dev_xstats_reset, > + .xstats_names = ixgbe_dev_xstats_names, > .queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set, > .dev_infos_get = ixgbe_dev_info_get, > .dev_supported_ptypes_get = ixgbe_dev_supported_ptypes_get, > @@ -555,6 +560,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = > { > .xstats_get = ixgbevf_dev_xstats_get, > .stats_reset = ixgbevf_dev_stats_reset, > .xstats_reset = ixgbevf_dev_stats_reset, > + .xstats_names = ixgbevf_dev_xstats_names, > .dev_close = ixgbevf_dev_close, > .allmulticast_enable = ixgbevf_dev_allmulticast_enable, > .allmulticast_disable = ixgbevf_dev_allmulticast_disable, > @@ -685,6 +691,7 @@ static const struct rte_ixgbe_xstats_name_off > rte_ixgbe_rxq_strings[] = { > > #define IXGBE_NB_RXQ_PRIO_STATS (sizeof(rte_ixgbe_rxq_strings) / \ > sizeof(rte_ixgbe_rxq_strings[0])) > +#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)}, > @@ -695,6 +702,7 @@ static const struct rte_ixgbe_xstats_name_off > rte_ixgbe_txq_strings[] = { > > #define IXGBE_NB_TXQ_PRIO_STATS (sizeof(rte_ixgbe_txq_strings) / \ > sizeof(rte_ixgbe_txq_strings[0])) > +#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)}, > @@ -2694,8 +2702,75 @@ ixgbe_dev_stats_reset(struct rte_eth_dev *dev) > /* This function calculates the number of xstats based on the current > config */ > static unsigned > ixgbe_xstats_calc_num(void) { > - return IXGBE_NB_HW_STATS + (IXGBE_NB_RXQ_PRIO_STATS * 8) + > - (IXGBE_NB_TXQ_PRIO_STATS * 8); > + return IXGBE_NB_HW_STATS + > + (IXGBE_NB_RXQ_PRIO_STATS * IXGBE_NB_RXQ_PRIO_VALUES) + > + (IXGBE_NB_TXQ_PRIO_STATS * IXGBE_NB_TXQ_PRIO_VALUES); Nice cleanup. > +} > + > +static int ixgbe_dev_xstats_names(__rte_unused struct rte_eth_dev *dev, > + struct rte_eth_xstats_name *ptr_names, __rte_unused unsigned limit) > +{ > + const unsigned cnt_stats = ixgbe_xstats_calc_num(); > + unsigned stat, i, count; > + > + if (ptr_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++) { > + ptr_names[count].id = count; > + snprintf(ptr_names[count].name, > + sizeof(ptr_names[count].name), > + "%s", > + rte_ixgbe_stats_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++) { > + ptr_names[count].id = count; > + snprintf(ptr_names[count].name, > + sizeof(ptr_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++) { > + ptr_names[count].id = count; > + snprintf(ptr_names[count].name, > + sizeof(ptr_names[count].name), > + "tx_priority%u_%s", i, > + rte_ixgbe_txq_strings[stat].name); > + count++; > + } > + } > + } > + return cnt_stats; > +} > + > +static int ixgbevf_dev_xstats_names(__rte_unused struct rte_eth_dev *dev, > + struct rte_eth_xstats_name *ptr_names, unsigned limit) > +{ > + unsigned i; > + > + if (limit < IXGBEVF_NB_XSTATS && ptr_names != NULL) > + return -ENOMEM; > + > + if (ptr_names != NULL) > + for (i = 0; i < IXGBEVF_NB_XSTATS; i++) > + snprintf(ptr_names[i].name, > + sizeof(ptr_names[i].name), > + "%s", rte_ixgbevf_stats_strings[i].name); > + return IXGBEVF_NB_XSTATS; > } > > static int > @@ -2731,8 +2806,8 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct > rte_eth_xstats *xstats, > /* 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].id = count; > + xstats[count].name[0] = '\0'; > xstats[count].value = *(uint64_t *)(((char *)hw_stats) + > rte_ixgbe_stats_strings[i].offset); > count++; > @@ -2740,10 +2815,9 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, > struct rte_eth_xstats *xstats, > > /* RX Priority Stats */ > for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) { > - for (i = 0; i < 8; i++) { > - snprintf(xstats[count].name, sizeof(xstats[count].name), > - "rx_priority%u_%s", i, > - rte_ixgbe_rxq_strings[stat].name); > + for (i = 0; i < IXGBE_NB_RXQ_PRIO_VALUES; i++) { > + xstats[count].id = count; > + xstats[count].name[0] = '\0'; > xstats[count].value = *(uint64_t *)(((char *)hw_stats) + > rte_ixgbe_rxq_strings[stat].offset + > (sizeof(uint64_t) * i)); > @@ -2753,17 +2827,15 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, > struct rte_eth_xstats *xstats, > > /* TX Priority Stats */ > for (stat = 0; stat < IXGBE_NB_TXQ_PRIO_STATS; stat++) { > - for (i = 0; i < 8; i++) { > - snprintf(xstats[count].name, sizeof(xstats[count].name), > - "tx_priority%u_%s", i, > - rte_ixgbe_txq_strings[stat].name); > + for (i = 0; i < IXGBE_NB_TXQ_PRIO_VALUES; i++) { > + xstats[count].id = count; > + xstats[count].name[0] = '\0'; > xstats[count].value = *(uint64_t *)(((char *)hw_stats) + > rte_ixgbe_txq_strings[stat].offset + > (sizeof(uint64_t) * i)); > count++; > } > } > - > return count; > } > > -- > 2.5.5 Acked-by: David Harton <dharton@cisco.com> ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v2 2/3] drivers/net/ixgbe: change xstats to use integer id 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 2/3] drivers/net/ixgbe: change xstats to use integer id Remy Horton 2016-05-09 14:06 ` David Harton (dharton) @ 2016-05-18 8:41 ` Tahhan, Maryam 1 sibling, 0 replies; 71+ messages in thread From: Tahhan, Maryam @ 2016-05-18 8:41 UTC (permalink / raw) To: Horton, Remy, dev > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Remy Horton > Sent: Friday, May 6, 2016 12:11 PM > To: dev@dpdk.org > Subject: [dpdk-dev] [RFC PATCH v2 2/3] drivers/net/ixgbe: change xstats > to use integer id > > Signed-off-by: Remy Horton <remy.horton@intel.com> > --- Acked-by: Maryam Tahhan <maryam.tahhan@intel.com> ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [RFC PATCH v2 3/3] examples/ethtool: add xstats display command 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 " Remy Horton 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 1/3] rte: change xstats to use integer keys Remy Horton 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 2/3] drivers/net/ixgbe: change xstats to use integer id Remy Horton @ 2016-05-06 11:11 ` Remy Horton 2016-05-09 14:08 ` David Harton (dharton) 2016-05-18 8:42 ` Tahhan, Maryam 2016-05-16 10:42 ` [dpdk-dev] [RFC PATCH v2 0/3] Remove string operations from xstats Tahhan, Maryam 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 00/10] " Remy Horton 4 siblings, 2 replies; 71+ messages in thread From: Remy Horton @ 2016-05-06 11:11 UTC (permalink / raw) To: dev Signed-off-by: Remy Horton <remy.horton@intel.com> --- examples/ethtool/ethtool-app/ethapp.c | 57 +++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/examples/ethtool/ethtool-app/ethapp.c b/examples/ethtool/ethtool-app/ethapp.c index 2ed4796..1dc0c35 100644 --- a/examples/ethtool/ethtool-app/ethapp.c +++ b/examples/ethtool/ethtool-app/ethapp.c @@ -98,6 +98,8 @@ cmdline_parse_token_string_t pcmd_rxmode_token_cmd = TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "rxmode"); cmdline_parse_token_string_t pcmd_portstats_token_cmd = TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "portstats"); +cmdline_parse_token_string_t pcmd_xstats_token_cmd = + TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "xstats"); cmdline_parse_token_num_t pcmd_int_token_port = TOKEN_NUM_INITIALIZER(struct pcmd_int_params, port, UINT16); @@ -552,6 +554,49 @@ static void pcmd_portstats_callback(__rte_unused void *ptr_params, printf("Port %i: Error fetching statistics\n", params->port); } +static void pcmd_xstats_callback(__rte_unused void *ptr_params, + __rte_unused struct cmdline *ctx, + __rte_unused void *ptr_data) +{ + struct rte_eth_xstats xstats[256]; + struct pcmd_int_params *params = ptr_params; + int cnt_xstats, idx_xstat, idx_name; + struct rte_eth_xstats_name *ptr_names; + + if (!rte_eth_dev_is_valid_port(params->port)) { + printf("Error: Invalid port number %i\n", params->port); + return; + } + + cnt_xstats = rte_eth_xstats_count(params->port); + if (cnt_xstats < 0) { + printf("Port %i: %s\n", params->port, strerror(-cnt_xstats)); + return; + } + printf("Number of xstats: %i\n", cnt_xstats); + ptr_names = malloc(sizeof(struct rte_eth_xstats_name) * cnt_xstats); + if (cnt_xstats != rte_eth_xstats_names( + params->port, ptr_names, cnt_xstats)) { + printf("Error: Fetched and expected counts mismatch\n"); + return; + } + + cnt_xstats = rte_eth_xstats_get(params->port, xstats, 256); + if (cnt_xstats < 0) { + printf("Error: Unable to get xstats (%s)\n", + strerror(-cnt_xstats)); + return; + } + for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++) + for (idx_name = 0; idx_name < cnt_xstats; idx_name++) + if (ptr_names[idx_name].id == xstats[idx_xstat].id) { + printf("%s: %lu\n", ptr_names[idx_name].name, + xstats[idx_xstat].value); + break; + } + free(ptr_names); +} + static void pcmd_ringparam_callback(__rte_unused void *ptr_params, __rte_unused struct cmdline *ctx, void *ptr_data) @@ -790,6 +835,17 @@ cmdline_parse_inst_t pcmd_portstats = { NULL }, }; +cmdline_parse_inst_t pcmd_xstats = { + .f = pcmd_xstats_callback, + .data = NULL, + .help_str = "xstats <port_id>\n" + " Print port eth xstats", + .tokens = { + (void *)&pcmd_xstats_token_cmd, + (void *)&pcmd_int_token_port, + NULL + }, +}; cmdline_parse_inst_t pcmd_ringparam = { .f = pcmd_ringparam_callback, .data = NULL, @@ -858,6 +914,7 @@ cmdline_parse_ctx_t list_prompt_commands[] = { (cmdline_parse_inst_t *)&pcmd_stop, (cmdline_parse_inst_t *)&pcmd_validate, (cmdline_parse_inst_t *)&pcmd_vlan, + (cmdline_parse_inst_t *)&pcmd_xstats, (cmdline_parse_inst_t *)&pcmd_quit, NULL }; -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v2 3/3] examples/ethtool: add xstats display command 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 3/3] examples/ethtool: add xstats display command Remy Horton @ 2016-05-09 14:08 ` David Harton (dharton) 2016-05-18 8:42 ` Tahhan, Maryam 1 sibling, 0 replies; 71+ messages in thread From: David Harton (dharton) @ 2016-05-09 14:08 UTC (permalink / raw) To: Remy Horton, dev > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Remy Horton > Sent: Friday, May 06, 2016 7:11 AM > To: dev@dpdk.org > Subject: [dpdk-dev] [RFC PATCH v2 3/3] examples/ethtool: add xstats > display command > > Signed-off-by: Remy Horton <remy.horton@intel.com> > --- > examples/ethtool/ethtool-app/ethapp.c | 57 > +++++++++++++++++++++++++++++++++++ > 1 file changed, 57 insertions(+) > > diff --git a/examples/ethtool/ethtool-app/ethapp.c > b/examples/ethtool/ethtool-app/ethapp.c > index 2ed4796..1dc0c35 100644 > --- a/examples/ethtool/ethtool-app/ethapp.c > +++ b/examples/ethtool/ethtool-app/ethapp.c > @@ -98,6 +98,8 @@ cmdline_parse_token_string_t pcmd_rxmode_token_cmd = > TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "rxmode"); > cmdline_parse_token_string_t pcmd_portstats_token_cmd = > TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "portstats"); > +cmdline_parse_token_string_t pcmd_xstats_token_cmd = > + TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "xstats"); > cmdline_parse_token_num_t pcmd_int_token_port = > TOKEN_NUM_INITIALIZER(struct pcmd_int_params, port, UINT16); > > @@ -552,6 +554,49 @@ static void pcmd_portstats_callback(__rte_unused void > *ptr_params, > printf("Port %i: Error fetching statistics\n", params->port); > } > > +static void pcmd_xstats_callback(__rte_unused void *ptr_params, > + __rte_unused struct cmdline *ctx, > + __rte_unused void *ptr_data) > +{ > + struct rte_eth_xstats xstats[256]; > + struct pcmd_int_params *params = ptr_params; > + int cnt_xstats, idx_xstat, idx_name; > + struct rte_eth_xstats_name *ptr_names; > + > + if (!rte_eth_dev_is_valid_port(params->port)) { > + printf("Error: Invalid port number %i\n", params->port); > + return; > + } > + > + cnt_xstats = rte_eth_xstats_count(params->port); > + if (cnt_xstats < 0) { > + printf("Port %i: %s\n", params->port, strerror(-cnt_xstats)); > + return; > + } > + printf("Number of xstats: %i\n", cnt_xstats); > + ptr_names = malloc(sizeof(struct rte_eth_xstats_name) * cnt_xstats); > + if (cnt_xstats != rte_eth_xstats_names( > + params->port, ptr_names, cnt_xstats)) { > + printf("Error: Fetched and expected counts mismatch\n"); > + return; > + } > + > + cnt_xstats = rte_eth_xstats_get(params->port, xstats, 256); > + if (cnt_xstats < 0) { > + printf("Error: Unable to get xstats (%s)\n", > + strerror(-cnt_xstats)); > + return; > + } > + for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++) > + for (idx_name = 0; idx_name < cnt_xstats; idx_name++) > + if (ptr_names[idx_name].id == xstats[idx_xstat].id) { > + printf("%s: %lu\n", ptr_names[idx_name].name, > + xstats[idx_xstat].value); > + break; > + } > + free(ptr_names); > +} > + > static void pcmd_ringparam_callback(__rte_unused void *ptr_params, > __rte_unused struct cmdline *ctx, > void *ptr_data) > @@ -790,6 +835,17 @@ cmdline_parse_inst_t pcmd_portstats = { > NULL > }, > }; > +cmdline_parse_inst_t pcmd_xstats = { > + .f = pcmd_xstats_callback, > + .data = NULL, > + .help_str = "xstats <port_id>\n" > + " Print port eth xstats", > + .tokens = { > + (void *)&pcmd_xstats_token_cmd, > + (void *)&pcmd_int_token_port, > + NULL > + }, > +}; > cmdline_parse_inst_t pcmd_ringparam = { > .f = pcmd_ringparam_callback, > .data = NULL, > @@ -858,6 +914,7 @@ cmdline_parse_ctx_t list_prompt_commands[] = { > (cmdline_parse_inst_t *)&pcmd_stop, > (cmdline_parse_inst_t *)&pcmd_validate, > (cmdline_parse_inst_t *)&pcmd_vlan, > + (cmdline_parse_inst_t *)&pcmd_xstats, > (cmdline_parse_inst_t *)&pcmd_quit, > NULL > }; > -- > 2.5.5 Acked-by: David Harton <dharton@cisco.com> ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v2 3/3] examples/ethtool: add xstats display command 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 3/3] examples/ethtool: add xstats display command Remy Horton 2016-05-09 14:08 ` David Harton (dharton) @ 2016-05-18 8:42 ` Tahhan, Maryam 1 sibling, 0 replies; 71+ messages in thread From: Tahhan, Maryam @ 2016-05-18 8:42 UTC (permalink / raw) To: Horton, Remy, dev > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Remy Horton > Sent: Friday, May 6, 2016 12:11 PM > To: dev@dpdk.org > Subject: [dpdk-dev] [RFC PATCH v2 3/3] examples/ethtool: add xstats > display command > > Signed-off-by: Remy Horton <remy.horton@intel.com> > --- Acked-by: Maryam Tahhan <maryam.tahhan@intel.com> ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v2 0/3] Remove string operations from xstats 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 " Remy Horton ` (2 preceding siblings ...) 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 3/3] examples/ethtool: add xstats display command Remy Horton @ 2016-05-16 10:42 ` Tahhan, Maryam 2016-05-18 10:12 ` Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 00/10] " Remy Horton 4 siblings, 1 reply; 71+ messages in thread From: Tahhan, Maryam @ 2016-05-16 10:42 UTC (permalink / raw) To: Horton, Remy, dev > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Remy Horton > Sent: Friday, May 6, 2016 12:11 PM > To: dev@dpdk.org > Subject: [dpdk-dev] [RFC PATCH v2 0/3] Remove string operations from > xstats > > The current extended ethernet statistics fetching involve doing several > string operations, which causes performance issues if there are lots of > statistics and/or network interfaces. This RFC patchset changes the API > for xstats to use integer identifiers instead of strings and implements this > new API for the ixgbe driver. Others drivers to follow. > > -- > > v2 changes: > * Fetching xstats count now seperate API function > * Added #define constants for some magic numbers > * Fixed bug with virtual function count fetching > * For non-xstats-supporting drivers, queue stats returned > * Some refactoring/cleanups > * Removed index assumption from example > > > Remy Horton (3): > rte: change xstats to use integer keys > drivers/net/ixgbe: change xstats to use integer keys > examples/ethtool: add xstats display command > > drivers/net/ixgbe/ixgbe_ethdev.c | 98 > ++++++++++++++++++++++++++++----- > examples/ethtool/ethtool-app/ethapp.c | 57 +++++++++++++++++++ > lib/librte_ether/rte_ethdev.c | 100 > +++++++++++++++++++++++++++++----- > lib/librte_ether/rte_ethdev.h | 55 +++++++++++++++++++ > 4 files changed, 284 insertions(+), 26 deletions(-) > > -- > 2.5.5 Looks Great overall. Is there a need to update prog_guide/poll_mode_drv.rst with the new mods? BR Maryam ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [RFC PATCH v2 0/3] Remove string operations from xstats 2016-05-16 10:42 ` [dpdk-dev] [RFC PATCH v2 0/3] Remove string operations from xstats Tahhan, Maryam @ 2016-05-18 10:12 ` Remy Horton 0 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-05-18 10:12 UTC (permalink / raw) To: Tahhan, Maryam, dev On 16/05/2016 11:42, Tahhan, Maryam wrote: [..] > > Looks Great overall. Is there a need to update prog_guide/poll_mode_drv.rst with the new mods? Yes it will need updating, as the description of rte_eth_xstats is now incorrect. Will fix in v3.. ..Remy ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v3 00/10] Remove string operations from xstats 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 " Remy Horton ` (3 preceding siblings ...) 2016-05-16 10:42 ` [dpdk-dev] [RFC PATCH v2 0/3] Remove string operations from xstats Tahhan, Maryam @ 2016-05-30 10:48 ` Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 01/10] rte: change xstats to use integer ids Remy Horton ` (11 more replies) 4 siblings, 12 replies; 71+ messages in thread From: Remy Horton @ 2016-05-30 10:48 UTC (permalink / raw) To: dev, Thomas Monjalon, Helin Zhang, Wenzhuo Lu, Jing Chen, Huawei Xie The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patchset changes the API for xstats to use integer identifiers instead of strings and implements this new API for the ixgbe, i40e, e1000, fm10k, and virtio drivers. -- v3 changes: * Corrected ixgbe vf xstats fetching * Added xstats changes to e1000, f10k, and virtio drivers * Added cleanup patch that removes now-redundant name field * Removed ethtool xstats command * Removed unused .xstats_count from eth-dev_ops * Changed test-pmd & proc_info to use new API * Added documentation update * Added missing changes to .map file (affected shared lib builds) v2 changes: * Fetching xstats count now seperate API function * Added #define constants for some magic numbers * Fixed bug with virtual function count fetching * For non-xstats-supporting drivers, queue stats returned * Some refactoring/cleanups * Removed index assumption from example Remy Horton (10): rte: change xstats to use integer ids drivers/net/ixgbe: change xstats to use integer ids drivers/net/e1000: change xstats to use integer ids drivers/net/fm10k: change xstats to use integer ids drivers/net/i40e: change xstats to use integer ids drivers/net/virtio: change xstats to use integer ids app/test-pmd: change xstats to use integer ids app/proc_info: change xstats to use integer ids remove name field from struct rte_eth_xstats doc: update xstats documentation app/proc_info/main.c | 26 ++++++++- app/test-pmd/config.c | 52 +++++++++++++---- doc/guides/prog_guide/poll_mode_drv.rst | 25 +++++++-- drivers/net/e1000/igb_ethdev.c | 50 +++++++++++++++-- drivers/net/fm10k/fm10k_ethdev.c | 52 ++++++++++++++--- drivers/net/i40e/i40e_ethdev.c | 77 +++++++++++++++++++++----- drivers/net/i40e/i40e_ethdev_vf.c | 24 +++++++- drivers/net/ixgbe/ixgbe_ethdev.c | 98 ++++++++++++++++++++++++++++----- drivers/net/virtio/virtio_ethdev.c | 60 +++++++++++++++++--- lib/librte_ether/rte_ethdev.c | 92 ++++++++++++++++++++++++++++--- lib/librte_ether/rte_ethdev.h | 44 ++++++++++++++- lib/librte_ether/rte_ether_version.map | 7 +++ 12 files changed, 527 insertions(+), 80 deletions(-) -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v3 01/10] rte: change xstats to use integer ids 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 00/10] " Remy Horton @ 2016-05-30 10:48 ` Remy Horton 2016-06-08 9:37 ` Thomas Monjalon 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 02/10] drivers/net/ixgbe: " Remy Horton ` (10 subsequent siblings) 11 siblings, 1 reply; 71+ messages in thread From: Remy Horton @ 2016-05-30 10:48 UTC (permalink / raw) To: dev, Thomas Monjalon The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the API for xstats to use integer identifiers instead of strings. Signed-off-by: Remy Horton <remy.horton@intel.com> --- lib/librte_ether/rte_ethdev.c | 95 +++++++++++++++++++++++++++++++--- lib/librte_ether/rte_ethdev.h | 44 ++++++++++++++++ lib/librte_ether/rte_ether_version.map | 7 +++ 3 files changed, 138 insertions(+), 8 deletions(-) diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index e148028..86fb0bc 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -1502,6 +1502,87 @@ rte_eth_stats_reset(uint8_t port_id) dev->data->rx_mbuf_alloc_failed = 0; } +int +rte_eth_xstats_count(uint8_t port_id) +{ + struct rte_eth_dev *dev; + int count; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); + dev = &rte_eth_devices[port_id]; + if (dev->dev_ops->xstats_names != NULL) { + count = (*dev->dev_ops->xstats_names)(dev, NULL, 0); + if (count < 0) + return count; + } else + count = 0; + count += RTE_NB_STATS; + count += dev->data->nb_rx_queues * RTE_NB_RXQ_STATS; + count += dev->data->nb_tx_queues * RTE_NB_TXQ_STATS; + return count; +} + +int +rte_eth_xstats_names(uint8_t port_id, struct rte_eth_xstats_name *ptr_names, + unsigned limit) +{ + struct rte_eth_dev *dev; + int cnt_used_entries; + int cnt_expected_entries; + uint32_t idx, id_queue; + + if (ptr_names == NULL) + return -EINVAL; + cnt_expected_entries = rte_eth_xstats_count(port_id); + if (cnt_expected_entries < 0) + return cnt_expected_entries; + if ((int)limit < cnt_expected_entries) + return -ERANGE; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); + dev = &rte_eth_devices[port_id]; + if (dev->dev_ops->xstats_names != NULL) { + cnt_used_entries = (*dev->dev_ops->xstats_names)( + dev, ptr_names, limit); + if (cnt_used_entries < 0) + return cnt_used_entries; + } else + /* Driver itself does not support extended stats, but + * still have basic stats. + */ + cnt_used_entries = 0; + + for (idx = 0; idx < RTE_NB_STATS; idx++) { + ptr_names[cnt_used_entries].id = cnt_used_entries; + snprintf(ptr_names[cnt_used_entries].name, + sizeof(ptr_names[0].name), + "%s", rte_stats_strings[idx].name); + cnt_used_entries++; + } + for (id_queue = 0; id_queue < dev->data->nb_rx_queues; id_queue++) { + for (idx = 0; idx < RTE_NB_RXQ_STATS; idx++) { + ptr_names[cnt_used_entries].id = cnt_used_entries; + snprintf(ptr_names[cnt_used_entries].name, + sizeof(ptr_names[0].name), + "rx_q%u%s", + id_queue, rte_rxq_stats_strings[idx].name); + cnt_used_entries++; + } + + } + for (id_queue = 0; id_queue < dev->data->nb_tx_queues; id_queue++) { + for (idx = 0; idx < RTE_NB_TXQ_STATS; idx++) { + ptr_names[cnt_used_entries].id = cnt_used_entries; + snprintf(ptr_names[cnt_used_entries].name, + sizeof(ptr_names[0].name), + "tx_q%u%s", + id_queue, rte_txq_stats_strings[idx].name); + cnt_used_entries++; + } + } + return cnt_used_entries; +} + /* retrieve ethdev extended statistics */ int rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, @@ -1546,8 +1627,8 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, stats_ptr = RTE_PTR_ADD(ð_stats, rte_stats_strings[i].offset); val = *stats_ptr; - snprintf(xstats[count].name, sizeof(xstats[count].name), - "%s", rte_stats_strings[i].name); + xstats[count].name[0] = '\0'; + xstats[count].id = count + xcount; xstats[count++].value = val; } @@ -1558,9 +1639,8 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, rte_rxq_stats_strings[i].offset + q * sizeof(uint64_t)); val = *stats_ptr; - snprintf(xstats[count].name, sizeof(xstats[count].name), - "rx_q%u_%s", q, - rte_rxq_stats_strings[i].name); + xstats[count].name[0] = '\0'; + xstats[count].id = count + xcount; xstats[count++].value = val; } } @@ -1572,9 +1652,8 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, rte_txq_stats_strings[i].offset + q * sizeof(uint64_t)); val = *stats_ptr; - snprintf(xstats[count].name, sizeof(xstats[count].name), - "tx_q%u_%s", q, - rte_txq_stats_strings[i].name); + xstats[count].name[0] = '\0'; + xstats[count].id = count + xcount; xstats[count++].value = val; } } diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index 2757510..d663d60 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -915,10 +915,23 @@ struct rte_eth_txq_info { * structure. */ struct rte_eth_xstats { + /* FIXME: Remove name[] once remaining drivers converted */ char name[RTE_ETH_XSTATS_NAME_SIZE]; + uint64_t id; uint64_t value; }; +/** + * A name-key lookup element for extended statistics. + * + * This structure is used to map between names and ID numbers + * for extended ethernet statistics. + */ +struct rte_eth_xstats_name { + char name[RTE_ETH_XSTATS_NAME_SIZE]; + uint64_t id; +}; + #define ETH_DCB_NUM_TCS 8 #define ETH_MAX_VMDQ_POOL 64 @@ -1054,6 +1067,10 @@ typedef int (*eth_xstats_get_t)(struct rte_eth_dev *dev, typedef void (*eth_xstats_reset_t)(struct rte_eth_dev *dev); /**< @internal Reset extended stats of an Ethernet device. */ +typedef int (*eth_xstats_names_t)(struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, unsigned limit); +/**< @internal Get names of extended stats 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, @@ -1401,6 +1418,8 @@ struct eth_dev_ops { eth_stats_reset_t stats_reset; /**< Reset generic device statistics. */ eth_xstats_get_t xstats_get; /**< Get extended device statistics. */ eth_xstats_reset_t xstats_reset; /**< Reset extended device statistics. */ + eth_xstats_names_t xstats_names; + /**< Get names of extended statistics. */ eth_queue_stats_mapping_set_t queue_stats_mapping_set; /**< Configure per queue stat counter mapping. */ eth_dev_infos_get_t dev_infos_get; /**< Get device info. */ @@ -2253,6 +2272,31 @@ int rte_eth_stats_get(uint8_t port_id, struct rte_eth_stats *stats); void rte_eth_stats_reset(uint8_t port_id); /** + * Retrieve names of extended statistics of an Ethernet device. + * + * @param port_id + * The port identifier of the Ethernet device. + * @param ptr_names + * Block of memory to insert names into. Must be at least limit in size. + * @param limit + * Capacity of ptr_strings (number of names). + * @return + * If successful, number of statistics; negative on error. + */ +int rte_eth_xstats_names(uint8_t port_id, struct rte_eth_xstats_name *ptr_names, + unsigned limit); + +/** + * Retrieve number of extended statistics of an Ethernet device. + * + * @param port_id + * The port identifier of the Ethernet device. + * @return + * If successful, number of statistics; negative on error. + */ +int rte_eth_xstats_count(uint8_t port_id); + +/** * Retrieve extended statistics of an Ethernet device. * * @param port_id diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map index 214ecc7..bb339e1 100644 --- a/lib/librte_ether/rte_ether_version.map +++ b/lib/librte_ether/rte_ether_version.map @@ -132,3 +132,10 @@ DPDK_16.04 { rte_eth_tx_buffer_set_err_callback; } DPDK_2.2; + +DPDK_16.07 { + global: + + rte_eth_xstats_names; + rte_eth_xstats_count; +} DPDK_16.04; -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [PATCH v3 01/10] rte: change xstats to use integer ids 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 01/10] rte: change xstats to use integer ids Remy Horton @ 2016-06-08 9:37 ` Thomas Monjalon 2016-06-08 11:16 ` Remy Horton 0 siblings, 1 reply; 71+ messages in thread From: Thomas Monjalon @ 2016-06-08 9:37 UTC (permalink / raw) To: Remy Horton; +Cc: dev 2016-05-30 11:48, Remy Horton: > struct rte_eth_xstats { > + /* FIXME: Remove name[] once remaining drivers converted */ > char name[RTE_ETH_XSTATS_NAME_SIZE]; What is the plan? This field must be deprecated with an attribute. We cannot have 2 different APIs depending of the driver. What are the remaining drivers to convert? > + uint64_t id; > uint64_t value; > }; > > +/** > + * A name-key lookup element for extended statistics. > + * > + * This structure is used to map between names and ID numbers > + * for extended ethernet statistics. > + */ > +struct rte_eth_xstats_name { > + char name[RTE_ETH_XSTATS_NAME_SIZE]; > + uint64_t id; > +}; This structure and the other one (rte_eth_xstats) are badly named. There is only one stat in each. So they should not have the plural form. rte_eth_xstat and rte_eth_xstat_name would be better. [...] > /** > + * Retrieve names of extended statistics of an Ethernet device. > + * > + * @param port_id > + * The port identifier of the Ethernet device. > + * @param ptr_names > + * Block of memory to insert names into. Must be at least limit in size. "xstat_names" would be a better name than "ptr_names". We don't use ptr in the variable names because it doesn't really convey a semantic information. > + * @param limit > + * Capacity of ptr_strings (number of names). We are more used to "size" than "limit". > + * @return > + * If successful, number of statistics; negative on error. > + */ > +int rte_eth_xstats_names(uint8_t port_id, struct rte_eth_xstats_name *ptr_names, Why not rte_eth_xstats_get_names? > + unsigned limit); A (double) indent tab is missing. > + > +/** > + * Retrieve number of extended statistics of an Ethernet device. > + * > + * @param port_id > + * The port identifier of the Ethernet device. > + * @return > + * If successful, number of statistics; negative on error. > + */ > +int rte_eth_xstats_count(uint8_t port_id); This function is useless because we can have the count with rte_eth_xstats_get(p, NULL, 0) By the way it would be more consistent to have the same behaviour in rte_eth_xstats_names(). ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [PATCH v3 01/10] rte: change xstats to use integer ids 2016-06-08 9:37 ` Thomas Monjalon @ 2016-06-08 11:16 ` Remy Horton 2016-06-08 12:22 ` Thomas Monjalon 0 siblings, 1 reply; 71+ messages in thread From: Remy Horton @ 2016-06-08 11:16 UTC (permalink / raw) To: Thomas Monjalon; +Cc: dev 'noon, On 08/06/2016 10:37, Thomas Monjalon wrote: > 2016-05-30 11:48, Remy Horton: >> struct rte_eth_xstats { >> + /* FIXME: Remove name[] once remaining drivers converted */ >> char name[RTE_ETH_XSTATS_NAME_SIZE]; > > What is the plan? This field must be deprecated with an attribute. > We cannot have 2 different APIs depending of the driver. This is where it gets logistically tricky.. Since there's an API/ABI breakage notice in place on this, my own preference would be to have the entire patchset quashed into a single patch. Problem is that rte/app changes (patches 1 & 7-9) are normally applied via master whereas driver changes (patches 2-6) go in via dpdk-next-net - it is not clear to me how patches should be submitted for this case.. > What are the remaining drivers to convert? Opps, none. All relevant drivers are converted.. > This structure and the other one (rte_eth_xstats) are badly named. > There is only one stat in each. So they should not have the plural form. > rte_eth_xstat and rte_eth_xstat_name would be better. I kept rte_eth_xstats as it was the name already in use within DPDK. Will change the other. >> +int rte_eth_xstats_count(uint8_t port_id); > > This function is useless because we can have the count with > rte_eth_xstats_get(p, NULL, 0) > By the way it would be more consistent to have the same behaviour > in rte_eth_xstats_names(). Feedback I got with earlier patches was that a seperate count function was preferable to overloading the fetch function using *data==NULL - is the use of the latter specifically preferred? Other comments noted. ..Remy ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [PATCH v3 01/10] rte: change xstats to use integer ids 2016-06-08 11:16 ` Remy Horton @ 2016-06-08 12:22 ` Thomas Monjalon 0 siblings, 0 replies; 71+ messages in thread From: Thomas Monjalon @ 2016-06-08 12:22 UTC (permalink / raw) To: Remy Horton; +Cc: dev 2016-06-08 12:16, Remy Horton: > 'noon, > > On 08/06/2016 10:37, Thomas Monjalon wrote: > > 2016-05-30 11:48, Remy Horton: > >> struct rte_eth_xstats { > >> + /* FIXME: Remove name[] once remaining drivers converted */ > >> char name[RTE_ETH_XSTATS_NAME_SIZE]; > > > > What is the plan? This field must be deprecated with an attribute. > > We cannot have 2 different APIs depending of the driver. > > This is where it gets logistically tricky.. > > Since there's an API/ABI breakage notice in place on this, my own > preference would be to have the entire patchset quashed into a single > patch. Problem is that rte/app changes (patches 1 & 7-9) are normally > applied via master whereas driver changes (patches 2-6) go in via > dpdk-next-net - it is not clear to me how patches should be submitted > for this case.. Misunderstanding here. Patches are fine and will be integrated in the main tree because they are not only some drivers changes. I was talking about the old API with name in rte_eth_xstats. I have not seen the patch 9 which removes it. > >> +int rte_eth_xstats_count(uint8_t port_id); > > > > This function is useless because we can have the count with > > rte_eth_xstats_get(p, NULL, 0) > > By the way it would be more consistent to have the same behaviour > > in rte_eth_xstats_names(). > > Feedback I got with earlier patches was that a seperate count function > was preferable to overloading the fetch function using *data==NULL - is > the use of the latter specifically preferred? I prefer the fetch/NULL style to get a count. It also handles nicely the fetch error because of a too small buffer. ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v3 02/10] drivers/net/ixgbe: change xstats to use integer ids 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 00/10] " Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 01/10] rte: change xstats to use integer ids Remy Horton @ 2016-05-30 10:48 ` Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 03/10] drivers/net/e1000: " Remy Horton ` (9 subsequent siblings) 11 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-05-30 10:48 UTC (permalink / raw) To: dev, Helin Zhang The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the ixgbe driver to use the new API that seperates name string and value queries. Signed-off-by: Remy Horton <remy.horton@intel.com> --- drivers/net/ixgbe/ixgbe_ethdev.c | 101 +++++++++++++++++++++++++++++++++------ 1 file changed, 86 insertions(+), 15 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c index a2b170b..bb5940b 100644 --- a/drivers/net/ixgbe/ixgbe_ethdev.c +++ b/drivers/net/ixgbe/ixgbe_ethdev.c @@ -179,6 +179,10 @@ 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_xstats_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, __rte_unused unsigned limit); +static int ixgbevf_dev_xstats_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, __rte_unused unsigned limit); static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev, uint16_t queue_id, uint8_t stat_idx, @@ -466,6 +470,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = { .xstats_get = ixgbe_dev_xstats_get, .stats_reset = ixgbe_dev_stats_reset, .xstats_reset = ixgbe_dev_xstats_reset, + .xstats_names = ixgbe_dev_xstats_names, .queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set, .dev_infos_get = ixgbe_dev_info_get, .dev_supported_ptypes_get = ixgbe_dev_supported_ptypes_get, @@ -555,6 +560,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = { .xstats_get = ixgbevf_dev_xstats_get, .stats_reset = ixgbevf_dev_stats_reset, .xstats_reset = ixgbevf_dev_stats_reset, + .xstats_names = ixgbevf_dev_xstats_names, .dev_close = ixgbevf_dev_close, .allmulticast_enable = ixgbevf_dev_allmulticast_enable, .allmulticast_disable = ixgbevf_dev_allmulticast_disable, @@ -685,6 +691,7 @@ static const struct rte_ixgbe_xstats_name_off rte_ixgbe_rxq_strings[] = { #define IXGBE_NB_RXQ_PRIO_STATS (sizeof(rte_ixgbe_rxq_strings) / \ sizeof(rte_ixgbe_rxq_strings[0])) +#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)}, @@ -695,6 +702,7 @@ static const struct rte_ixgbe_xstats_name_off rte_ixgbe_txq_strings[] = { #define IXGBE_NB_TXQ_PRIO_STATS (sizeof(rte_ixgbe_txq_strings) / \ sizeof(rte_ixgbe_txq_strings[0])) +#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)}, @@ -2695,8 +2703,75 @@ ixgbe_dev_stats_reset(struct rte_eth_dev *dev) /* This function calculates the number of xstats based on the current config */ static unsigned ixgbe_xstats_calc_num(void) { - return IXGBE_NB_HW_STATS + (IXGBE_NB_RXQ_PRIO_STATS * 8) + - (IXGBE_NB_TXQ_PRIO_STATS * 8); + return IXGBE_NB_HW_STATS + + (IXGBE_NB_RXQ_PRIO_STATS * IXGBE_NB_RXQ_PRIO_VALUES) + + (IXGBE_NB_TXQ_PRIO_STATS * IXGBE_NB_TXQ_PRIO_VALUES); +} + +static int ixgbe_dev_xstats_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, __rte_unused unsigned limit) +{ + const unsigned cnt_stats = ixgbe_xstats_calc_num(); + unsigned stat, i, count; + + if (ptr_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++) { + ptr_names[count].id = count; + snprintf(ptr_names[count].name, + sizeof(ptr_names[count].name), + "%s", + rte_ixgbe_stats_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++) { + ptr_names[count].id = count; + snprintf(ptr_names[count].name, + sizeof(ptr_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++) { + ptr_names[count].id = count; + snprintf(ptr_names[count].name, + sizeof(ptr_names[count].name), + "tx_priority%u_%s", i, + rte_ixgbe_txq_strings[stat].name); + count++; + } + } + } + return cnt_stats; +} + +static int ixgbevf_dev_xstats_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, unsigned limit) +{ + unsigned i; + + if (limit < IXGBEVF_NB_XSTATS && ptr_names != NULL) + return -ENOMEM; + + if (ptr_names != NULL) + for (i = 0; i < IXGBEVF_NB_XSTATS; i++) + snprintf(ptr_names[i].name, + sizeof(ptr_names[i].name), + "%s", rte_ixgbevf_stats_strings[i].name); + return IXGBEVF_NB_XSTATS; } static int @@ -2732,8 +2807,8 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* 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].id = count; + xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_stats_strings[i].offset); count++; @@ -2741,10 +2816,9 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* RX Priority Stats */ for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) { - for (i = 0; i < 8; i++) { - snprintf(xstats[count].name, sizeof(xstats[count].name), - "rx_priority%u_%s", i, - rte_ixgbe_rxq_strings[stat].name); + for (i = 0; i < IXGBE_NB_RXQ_PRIO_VALUES; i++) { + xstats[count].id = count; + xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_rxq_strings[stat].offset + (sizeof(uint64_t) * i)); @@ -2754,17 +2828,15 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* TX Priority Stats */ for (stat = 0; stat < IXGBE_NB_TXQ_PRIO_STATS; stat++) { - for (i = 0; i < 8; i++) { - snprintf(xstats[count].name, sizeof(xstats[count].name), - "tx_priority%u_%s", i, - rte_ixgbe_txq_strings[stat].name); + for (i = 0; i < IXGBE_NB_TXQ_PRIO_VALUES; i++) { + xstats[count].id = count; + xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_txq_strings[stat].offset + (sizeof(uint64_t) * i)); count++; } } - return count; } @@ -2829,8 +2901,7 @@ ixgbevf_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* 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].id = i; xstats[i].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbevf_stats_strings[i].offset); } -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v3 03/10] drivers/net/e1000: change xstats to use integer ids 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 00/10] " Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 01/10] rte: change xstats to use integer ids Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 02/10] drivers/net/ixgbe: " Remy Horton @ 2016-05-30 10:48 ` Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 04/10] drivers/net/fm10k: " Remy Horton ` (8 subsequent siblings) 11 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-05-30 10:48 UTC (permalink / raw) To: dev, Wenzhuo Lu The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the e1000 driver to use the new API that seperates name string and value queries. Signed-off-by: Remy Horton <remy.horton@intel.com> --- drivers/net/e1000/igb_ethdev.c | 52 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c index f0921ee..6d5e46f 100644 --- a/drivers/net/e1000/igb_ethdev.c +++ b/drivers/net/e1000/igb_ethdev.c @@ -100,6 +100,9 @@ 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 int eth_igb_xstats_names(struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, + unsigned limit); 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, @@ -165,6 +168,9 @@ 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 int eth_igbvf_xstats_names(struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, + unsigned limit); 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); @@ -324,6 +330,7 @@ static const struct eth_dev_ops eth_igb_ops = { .link_update = eth_igb_link_update, .stats_get = eth_igb_stats_get, .xstats_get = eth_igb_xstats_get, + .xstats_names = eth_igb_xstats_names, .stats_reset = eth_igb_stats_reset, .xstats_reset = eth_igb_xstats_reset, .dev_infos_get = eth_igb_infos_get, @@ -385,6 +392,7 @@ static const struct eth_dev_ops igbvf_eth_dev_ops = { .link_update = eth_igb_link_update, .stats_get = eth_igbvf_stats_get, .xstats_get = eth_igbvf_xstats_get, + .xstats_names = eth_igbvf_xstats_names, .stats_reset = eth_igbvf_stats_reset, .xstats_reset = eth_igbvf_stats_reset, .vlan_filter_set = igbvf_vlan_filter_set, @@ -1691,6 +1699,26 @@ eth_igb_xstats_reset(struct rte_eth_dev *dev) memset(stats, 0, sizeof(*stats)); } +static int eth_igb_xstats_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, + __rte_unused unsigned limit) +{ + unsigned i; + + if (ptr_names == NULL) + return IGB_NB_XSTATS; + + /* Note: limit checked in rte_eth_xstats_names() */ + + for (i = 0; i < IGB_NB_XSTATS; i++) { + snprintf(ptr_names[i].name, sizeof(ptr_names[i].name), + "%s", rte_igb_stats_strings[i].name); + ptr_names[i].id = i; + } + + return IGB_NB_XSTATS; +} + static int eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned n) @@ -1713,8 +1741,8 @@ eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* 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].name[0] = '\0'; + xstats[i].id = i; xstats[i].value = *(uint64_t *)(((char *)hw_stats) + rte_igb_stats_strings[i].offset); } @@ -1762,6 +1790,22 @@ igbvf_read_stats_registers(struct e1000_hw *hw, struct e1000_vf_stats *hw_stats) hw_stats->last_gotlbc, hw_stats->gotlbc); } +static int eth_igbvf_xstats_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, + __rte_unused unsigned limit) +{ + unsigned i; + + if (ptr_names != NULL) + for (i = 0; i < IGBVF_NB_XSTATS; i++) { + snprintf(ptr_names[i].name, + sizeof(ptr_names[i].name), "%s", + rte_igbvf_stats_strings[i].name); + ptr_names[i].id = i; + } + return IGBVF_NB_XSTATS; +} + static int eth_igbvf_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned n) @@ -1780,8 +1824,8 @@ eth_igbvf_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *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].name[0] = '\0'; + xstats[i].id = i; xstats[i].value = *(uint64_t *)(((char *)hw_stats) + rte_igbvf_stats_strings[i].offset); } -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v3 04/10] drivers/net/fm10k: change xstats to use integer ids 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 00/10] " Remy Horton ` (2 preceding siblings ...) 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 03/10] drivers/net/e1000: " Remy Horton @ 2016-05-30 10:48 ` Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 05/10] drivers/net/i40e: " Remy Horton ` (7 subsequent siblings) 11 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-05-30 10:48 UTC (permalink / raw) To: dev, Jing Chen The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the fm10k driver to use the new API that seperates name string and value queries. Signed-off-by: Remy Horton <remy.horton@intel.com> --- drivers/net/fm10k/fm10k_ethdev.c | 55 +++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c index c2d377f..179441d 100644 --- a/drivers/net/fm10k/fm10k_ethdev.c +++ b/drivers/net/fm10k/fm10k_ethdev.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2013-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2013-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -1256,6 +1256,47 @@ fm10k_link_update(struct rte_eth_dev *dev, return 0; } +static int fm10k_xstats_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, __rte_unused unsigned limit) +{ + unsigned i, q; + unsigned count = 0; + + if (ptr_names != NULL) { + /* Note: limit checked in rte_eth_xstats_names() */ + + /* Global stats */ + for (i = 0; i < FM10K_NB_HW_XSTATS; i++) { + snprintf(ptr_names[count].name, + sizeof(ptr_names[count].name), + "%s", fm10k_hw_stats_strings[count].name); + ptr_names[count].id = count; + count++; + } + + /* PF queue stats */ + for (q = 0; q < FM10K_MAX_QUEUES_PF; q++) { + for (i = 0; i < FM10K_NB_RX_Q_XSTATS; i++) { + snprintf(ptr_names[count].name, + sizeof(ptr_names[count].name), + "rx_q%u_%s", q, + fm10k_hw_stats_rx_q_strings[i].name); + ptr_names[count].id = count; + count++; + } + for (i = 0; i < FM10K_NB_TX_Q_XSTATS; i++) { + snprintf(ptr_names[count].name, + sizeof(ptr_names[count].name), + "tx_q%u_%s", q, + fm10k_hw_stats_tx_q_strings[i].name); + ptr_names[count].id = count; + count++; + } + } + } + return FM10K_NB_XSTATS; +} + static int fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned n) @@ -1269,8 +1310,7 @@ fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *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].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + fm10k_hw_stats_strings[count].offset); count++; @@ -1279,18 +1319,14 @@ fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* 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].name[0] = '\0'; 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].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)&hw_stats->q[q]) + fm10k_hw_stats_tx_q_strings[i].offset); @@ -2629,6 +2665,7 @@ static const struct eth_dev_ops fm10k_eth_dev_ops = { .allmulticast_disable = fm10k_dev_allmulticast_disable, .stats_get = fm10k_stats_get, .xstats_get = fm10k_xstats_get, + .xstats_names = fm10k_xstats_names, .stats_reset = fm10k_stats_reset, .xstats_reset = fm10k_stats_reset, .link_update = fm10k_link_update, -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v3 05/10] drivers/net/i40e: change xstats to use integer ids 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 00/10] " Remy Horton ` (3 preceding siblings ...) 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 04/10] drivers/net/fm10k: " Remy Horton @ 2016-05-30 10:48 ` Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 06/10] drivers/net/virtio: " Remy Horton ` (6 subsequent siblings) 11 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-05-30 10:48 UTC (permalink / raw) To: dev, Helin Zhang The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the i40e driver to use the new API that seperates name string and value queries. Signed-off-by: Remy Horton <remy.horton@intel.com> --- drivers/net/i40e/i40e_ethdev.c | 81 ++++++++++++++++++++++++++++++++------- drivers/net/i40e/i40e_ethdev_vf.c | 25 ++++++++++-- 2 files changed, 89 insertions(+), 17 deletions(-) diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 24777d5..e0ce695 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -306,6 +306,9 @@ 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 int i40e_dev_xstats_names(struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, + unsigned limit); static void i40e_dev_stats_reset(struct rte_eth_dev *dev); static int i40e_dev_queue_stats_mapping_set(struct rte_eth_dev *dev, uint16_t queue_id, @@ -467,6 +470,7 @@ static const struct eth_dev_ops i40e_eth_dev_ops = { .link_update = i40e_dev_link_update, .stats_get = i40e_dev_stats_get, .xstats_get = i40e_dev_xstats_get, + .xstats_names = i40e_dev_xstats_names, .stats_reset = i40e_dev_stats_reset, .xstats_reset = i40e_dev_stats_reset, .queue_stats_mapping_set = i40e_dev_queue_stats_mapping_set, @@ -2205,6 +2209,59 @@ i40e_xstats_calc_num(void) (I40E_NB_TXQ_PRIO_XSTATS * 8); } +static int i40e_dev_xstats_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, + __rte_unused unsigned limit) +{ + unsigned count = 0; + unsigned i, prio; + + if (ptr_names == NULL) + return i40e_xstats_calc_num(); + + /* Note: limit checked in rte_eth_xstats_names() */ + + /* Get stats from i40e_eth_stats struct */ + for (i = 0; i < I40E_NB_ETH_XSTATS; i++) { + snprintf(ptr_names[count].name, sizeof(ptr_names[count].name), + "%s", rte_i40e_stats_strings[i].name); + ptr_names[count].id = count; + count++; + } + + /* Get individiual stats from i40e_hw_port struct */ + for (i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) { + snprintf(ptr_names[count].name, + sizeof(ptr_names[count].name), + "%s", rte_i40e_hw_port_strings[i].name); + ptr_names[count].id = count; + count++; + } + + for (i = 0; i < I40E_NB_RXQ_PRIO_XSTATS; i++) { + for (prio = 0; prio < 8; prio++) { + snprintf(ptr_names[count].name, + sizeof(ptr_names[count].name), + "rx_priority%u_%s", prio, + rte_i40e_rxq_prio_strings[i].name); + ptr_names[count].id = count; + count++; + } + } + + for (i = 0; i < I40E_NB_TXQ_PRIO_XSTATS; i++) { + for (prio = 0; prio < 8; prio++) { + snprintf(ptr_names[count].name, + sizeof(ptr_names[count].name), + "tx_priority%u_%s", prio, + rte_i40e_txq_prio_strings[i].name); + ptr_names[count].id = count; + count++; + } + } + return count; +} + static int i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned n) @@ -2227,8 +2284,8 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* 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].name[0] = '\0'; + xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)&hw_stats->eth) + rte_i40e_stats_strings[i].offset); count++; @@ -2236,19 +2293,17 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* 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].name[0] = '\0'; + xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + - rte_i40e_hw_port_strings[i].offset); + rte_i40e_hw_port_strings[i].offset); count++; } for (i = 0; i < I40E_NB_RXQ_PRIO_XSTATS; i++) { for (prio = 0; prio < 8; prio++) { - snprintf(xstats[count].name, - sizeof(xstats[count].name), - "rx_priority%u_%s", prio, - rte_i40e_rxq_prio_strings[i].name); + xstats[count].name[0] = '\0'; + xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_i40e_rxq_prio_strings[i].offset + @@ -2259,10 +2314,8 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, for (i = 0; i < I40E_NB_TXQ_PRIO_XSTATS; i++) { for (prio = 0; prio < 8; prio++) { - snprintf(xstats[count].name, - sizeof(xstats[count].name), - "tx_priority%u_%s", prio, - rte_i40e_txq_prio_strings[i].name); + xstats[count].name[0] = '\0'; + xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_i40e_txq_prio_strings[i].offset + diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c index 90682ac..c3301c5 100644 --- a/drivers/net/i40e/i40e_ethdev_vf.c +++ b/drivers/net/i40e/i40e_ethdev_vf.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -112,6 +112,9 @@ 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 int i40evf_dev_xstats_names(struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, + unsigned limit); 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); @@ -196,6 +199,7 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = { .link_update = i40evf_dev_link_update, .stats_get = i40evf_dev_stats_get, .xstats_get = i40evf_dev_xstats_get, + .xstats_names = i40evf_dev_xstats_names, .xstats_reset = i40evf_dev_xstats_reset, .dev_close = i40evf_dev_close, .dev_infos_get = i40evf_dev_info_get, @@ -984,6 +988,21 @@ i40evf_dev_xstats_reset(struct rte_eth_dev *dev) vf->vsi.eth_stats_offset = vf->vsi.eth_stats; } +static int i40evf_dev_xstats_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, + __rte_unused unsigned limit) +{ + unsigned i; + + if (ptr_names != NULL) + for (i = 0; i < I40EVF_NB_XSTATS; i++) { + snprintf(ptr_names[i].name, sizeof(ptr_names[i].name), + "%s", rte_i40evf_stats_strings[i].name); + ptr_names[i].id = i; + } + return I40EVF_NB_XSTATS; +} + static int i40evf_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned n) { @@ -1003,8 +1022,8 @@ static int i40evf_dev_xstats_get(struct rte_eth_dev *dev, /* 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].name[0] = '\0'; + xstats[i].id = i; xstats[i].value = *(uint64_t *)(((char *)pstats) + rte_i40evf_stats_strings[i].offset); } -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v3 06/10] drivers/net/virtio: change xstats to use integer ids 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 00/10] " Remy Horton ` (4 preceding siblings ...) 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 05/10] drivers/net/i40e: " Remy Horton @ 2016-05-30 10:48 ` Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 07/10] app/test-pmd: " Remy Horton ` (5 subsequent siblings) 11 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-05-30 10:48 UTC (permalink / raw) To: dev, Huawei Xie The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the virtio driver to use the new API that seperates name string and value queries. Signed-off-by: Remy Horton <remy.horton@intel.com> --- drivers/net/virtio/virtio_ethdev.c | 62 +++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c index c3fb628..9d549de 100644 --- a/drivers/net/virtio/virtio_ethdev.c +++ b/drivers/net/virtio/virtio_ethdev.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -80,6 +80,9 @@ 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 int virtio_dev_xstats_names(struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, + unsigned limit); 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, @@ -615,6 +618,7 @@ 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, + .xstats_names = virtio_dev_xstats_names, .stats_reset = virtio_dev_stats_reset, .xstats_reset = virtio_dev_stats_reset, .link_update = virtio_dev_link_update, @@ -708,6 +712,52 @@ virtio_update_stats(struct rte_eth_dev *dev, struct rte_eth_stats *stats) stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed; } +static int virtio_dev_xstats_names(struct rte_eth_dev *dev, + struct rte_eth_xstats_name *ptr_names, + __rte_unused unsigned limit) +{ + unsigned i; + unsigned count = 0; + unsigned t; + + unsigned nstats = dev->data->nb_tx_queues * VIRTIO_NB_Q_XSTATS + + dev->data->nb_rx_queues * VIRTIO_NB_Q_XSTATS; + + if (ptr_names == NULL) { + /* Note: limit checked in rte_eth_xstats_names() */ + + for (i = 0; i < dev->data->nb_rx_queues; i++) { + struct virtqueue *rxvq = dev->data->rx_queues[i]; + if (rxvq == NULL) + continue; + for (t = 0; t < VIRTIO_NB_Q_XSTATS; t++) { + snprintf(ptr_names[count].name, + sizeof(ptr_names[count].name), + "rx_q%u_%s", i, + rte_virtio_q_stat_strings[t].name); + ptr_names[count].id = count; + count++; + } + } + + for (i = 0; i < dev->data->nb_tx_queues; i++) { + struct virtqueue *txvq = dev->data->tx_queues[i]; + if (txvq == NULL) + continue; + for (t = 0; t < VIRTIO_NB_Q_XSTATS; t++) { + snprintf(ptr_names[count].name, + sizeof(ptr_names[count].name), + "tx_q%u_%s", i, + rte_virtio_q_stat_strings[t].name); + ptr_names[count].id = count; + count++; + } + } + return count; + } + return nstats; +} + static int virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned n) @@ -730,9 +780,8 @@ virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, 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].name[0] = '\0'; + xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)rxvq) + rte_virtio_q_stat_strings[t].offset); count++; @@ -748,9 +797,8 @@ virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, 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].name[0] = '\0'; + xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)txvq) + rte_virtio_q_stat_strings[t].offset); count++; -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v3 07/10] app/test-pmd: change xstats to use integer ids 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 00/10] " Remy Horton ` (5 preceding siblings ...) 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 06/10] drivers/net/virtio: " Remy Horton @ 2016-05-30 10:48 ` Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 08/10] app/proc_info: " Remy Horton ` (4 subsequent siblings) 11 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-05-30 10:48 UTC (permalink / raw) To: dev, Pablo de Lara The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the test-pmd application to use the new API that seperates name string and value queries. Signed-off-by: Remy Horton <remy.horton@intel.com> --- app/test-pmd/config.c | 52 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 1c552e4..3ba5679 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -233,28 +233,56 @@ void nic_xstats_display(portid_t port_id) { struct rte_eth_xstats *xstats; - int len, ret, i; + int cnt_xstats, idx_xstat, idx_name; + struct rte_eth_xstats_name *ptr_names; printf("###### NIC extended statistics for port %-2d\n", port_id); + if (!rte_eth_dev_is_valid_port(port_id)) { + printf("Error: Invalid port number %i\n", port_id); + return; + } + + /* Get count */ + cnt_xstats = rte_eth_xstats_count(port_id); + if (cnt_xstats < 0) { + printf("Error: Cannot get count of xstats\n"); + return; + } - len = rte_eth_xstats_get(port_id, NULL, 0); - if (len < 0) { - printf("Cannot get xstats count\n"); + /* Get id-name lookup table */ + ptr_names = malloc(sizeof(struct rte_eth_xstats_name) * cnt_xstats); + if (ptr_names == NULL) { + printf("Cannot allocate memory for xstats lookup\n"); return; } - xstats = malloc(sizeof(xstats[0]) * len); + if (cnt_xstats != rte_eth_xstats_names( + port_id, ptr_names, cnt_xstats)) { + printf("Error: Cannot get xstats lookup\n"); + return; + } + + /* Get stats themselves */ + xstats = malloc(sizeof(struct rte_eth_xstats) * cnt_xstats); if (xstats == NULL) { printf("Cannot allocate memory for xstats\n"); + free(ptr_names); return; } - ret = rte_eth_xstats_get(port_id, xstats, len); - if (ret < 0 || ret > len) { - printf("Cannot get xstats\n"); - free(xstats); + if (cnt_xstats != rte_eth_xstats_get(port_id, xstats, cnt_xstats)) { + printf("Error: Unable to get xstats\n"); return; } - for (i = 0; i < len; i++) - printf("%s: %"PRIu64"\n", xstats[i].name, xstats[i].value); + + /* Display xstats */ + for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++) + for (idx_name = 0; idx_name < cnt_xstats; idx_name++) + if (ptr_names[idx_name].id == xstats[idx_xstat].id) { + printf("%s: %"PRIu64"\n", + ptr_names[idx_name].name, + xstats[idx_xstat].value); + break; + } + free(ptr_names); free(xstats); } -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v3 08/10] app/proc_info: change xstats to use integer ids 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 00/10] " Remy Horton ` (6 preceding siblings ...) 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 07/10] app/test-pmd: " Remy Horton @ 2016-05-30 10:48 ` Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 09/10] remove name field from struct rte_eth_xstats Remy Horton ` (3 subsequent siblings) 11 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-05-30 10:48 UTC (permalink / raw) To: dev, Maryam Tahhan The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the proc_info application to use the new API that seperates name string and value queries. Signed-off-by: Remy Horton <remy.horton@intel.com> --- app/proc_info/main.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/app/proc_info/main.c b/app/proc_info/main.c index 5f83092..ef71fcf 100644 --- a/app/proc_info/main.c +++ b/app/proc_info/main.c @@ -1,7 +1,7 @@ /* * BSD LICENSE * - * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -243,11 +243,13 @@ nic_stats_clear(uint8_t port_id) static void nic_xstats_display(uint8_t port_id) { + struct rte_eth_xstats_name *ptr_names; struct rte_eth_xstats *xstats; int len, ret, i; + int idx_name; static const char *nic_stats_border = "########################"; - len = rte_eth_xstats_get(port_id, NULL, 0); + len = rte_eth_xstats_count(port_id); if (len < 0) { printf("Cannot get xstats count\n"); return; @@ -258,6 +260,18 @@ nic_xstats_display(uint8_t port_id) return; } + ptr_names = malloc(sizeof(struct rte_eth_xstats_name) * len); + if (ptr_names == NULL) { + printf("Cannot allocate memory for xstat names\n"); + free(xstats); + return; + } + if (len != rte_eth_xstats_names( + port_id, ptr_names, len)) { + printf("Cannot get xstat names\n"); + return; + } + printf("###### NIC extended statistics for port %-2d #########\n", port_id); printf("%s############################\n", @@ -270,11 +284,17 @@ nic_xstats_display(uint8_t port_id) } for (i = 0; i < len; i++) - printf("%s: %"PRIu64"\n", xstats[i].name, xstats[i].value); + for (idx_name = 0; idx_name < len; idx_name++) + if (ptr_names[idx_name].id == xstats[i].id) { + printf("%s: %lu\n", ptr_names[idx_name].name, + xstats[i].value); + break; + } printf("%s############################\n", nic_stats_border); free(xstats); + free(ptr_names); } static void -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v3 09/10] remove name field from struct rte_eth_xstats 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 00/10] " Remy Horton ` (7 preceding siblings ...) 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 08/10] app/proc_info: " Remy Horton @ 2016-05-30 10:48 ` Remy Horton 2016-06-08 12:23 ` Thomas Monjalon 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 10/10] doc: update xstats documentation Remy Horton ` (2 subsequent siblings) 11 siblings, 1 reply; 71+ messages in thread From: Remy Horton @ 2016-05-30 10:48 UTC (permalink / raw) To: dev, Thomas Monjalon, Helin Zhang, Wenzhuo Lu, Jing Chen, Huawei Xie The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch removes the name field and all its usage of the old API. Signed-off-by: Remy Horton <remy.horton@intel.com> --- drivers/net/e1000/igb_ethdev.c | 2 -- drivers/net/fm10k/fm10k_ethdev.c | 3 --- drivers/net/i40e/i40e_ethdev.c | 4 ---- drivers/net/i40e/i40e_ethdev_vf.c | 1 - drivers/net/ixgbe/ixgbe_ethdev.c | 3 --- drivers/net/virtio/virtio_ethdev.c | 2 -- lib/librte_ether/rte_ethdev.c | 3 --- lib/librte_ether/rte_ethdev.h | 2 -- 8 files changed, 20 deletions(-) diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c index 6d5e46f..2bfd3f8 100644 --- a/drivers/net/e1000/igb_ethdev.c +++ b/drivers/net/e1000/igb_ethdev.c @@ -1741,7 +1741,6 @@ eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* Extended stats */ for (i = 0; i < IGB_NB_XSTATS; i++) { - xstats[i].name[0] = '\0'; xstats[i].id = i; xstats[i].value = *(uint64_t *)(((char *)hw_stats) + rte_igb_stats_strings[i].offset); @@ -1824,7 +1823,6 @@ eth_igbvf_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, return 0; for (i = 0; i < IGBVF_NB_XSTATS; i++) { - xstats[i].name[0] = '\0'; xstats[i].id = i; xstats[i].value = *(uint64_t *)(((char *)hw_stats) + rte_igbvf_stats_strings[i].offset); diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c index 179441d..be7431d 100644 --- a/drivers/net/fm10k/fm10k_ethdev.c +++ b/drivers/net/fm10k/fm10k_ethdev.c @@ -1310,7 +1310,6 @@ fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* Global stats */ for (i = 0; i < FM10K_NB_HW_XSTATS; i++) { - xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + fm10k_hw_stats_strings[count].offset); count++; @@ -1319,14 +1318,12 @@ fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* PF queue stats */ for (q = 0; q < FM10K_MAX_QUEUES_PF; q++) { for (i = 0; i < FM10K_NB_RX_Q_XSTATS; i++) { - xstats[count].name[0] = '\0'; 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++) { - xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)&hw_stats->q[q]) + fm10k_hw_stats_tx_q_strings[i].offset); diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index e0ce695..cc77370 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -2284,7 +2284,6 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* Get stats from i40e_eth_stats struct */ for (i = 0; i < I40E_NB_ETH_XSTATS; i++) { - xstats[count].name[0] = '\0'; xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)&hw_stats->eth) + rte_i40e_stats_strings[i].offset); @@ -2293,7 +2292,6 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* Get individiual stats from i40e_hw_port struct */ for (i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) { - xstats[count].name[0] = '\0'; xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_i40e_hw_port_strings[i].offset); @@ -2302,7 +2300,6 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, for (i = 0; i < I40E_NB_RXQ_PRIO_XSTATS; i++) { for (prio = 0; prio < 8; prio++) { - xstats[count].name[0] = '\0'; xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + @@ -2314,7 +2311,6 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, for (i = 0; i < I40E_NB_TXQ_PRIO_XSTATS; i++) { for (prio = 0; prio < 8; prio++) { - xstats[count].name[0] = '\0'; xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c index c3301c5..ad6238d 100644 --- a/drivers/net/i40e/i40e_ethdev_vf.c +++ b/drivers/net/i40e/i40e_ethdev_vf.c @@ -1022,7 +1022,6 @@ static int i40evf_dev_xstats_get(struct rte_eth_dev *dev, /* loop over xstats array and values from pstats */ for (i = 0; i < I40EVF_NB_XSTATS; i++) { - xstats[i].name[0] = '\0'; xstats[i].id = i; xstats[i].value = *(uint64_t *)(((char *)pstats) + rte_i40evf_stats_strings[i].offset); diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c index bb5940b..4c121ba 100644 --- a/drivers/net/ixgbe/ixgbe_ethdev.c +++ b/drivers/net/ixgbe/ixgbe_ethdev.c @@ -2808,7 +2808,6 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, count = 0; for (i = 0; i < IXGBE_NB_HW_STATS; i++) { xstats[count].id = count; - xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_stats_strings[i].offset); count++; @@ -2818,7 +2817,6 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) { for (i = 0; i < IXGBE_NB_RXQ_PRIO_VALUES; i++) { xstats[count].id = count; - xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_rxq_strings[stat].offset + (sizeof(uint64_t) * i)); @@ -2830,7 +2828,6 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, for (stat = 0; stat < IXGBE_NB_TXQ_PRIO_STATS; stat++) { for (i = 0; i < IXGBE_NB_TXQ_PRIO_VALUES; i++) { xstats[count].id = count; - xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_txq_strings[stat].offset + (sizeof(uint64_t) * i)); diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c index 9d549de..bfd3748 100644 --- a/drivers/net/virtio/virtio_ethdev.c +++ b/drivers/net/virtio/virtio_ethdev.c @@ -780,7 +780,6 @@ virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned t; for (t = 0; t < VIRTIO_NB_Q_XSTATS; t++) { - xstats[count].name[0] = '\0'; xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)rxvq) + rte_virtio_q_stat_strings[t].offset); @@ -797,7 +796,6 @@ virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned t; for (t = 0; t < VIRTIO_NB_Q_XSTATS; t++) { - xstats[count].name[0] = '\0'; xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)txvq) + rte_virtio_q_stat_strings[t].offset); diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index 86fb0bc..0a533e6 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -1627,7 +1627,6 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, stats_ptr = RTE_PTR_ADD(ð_stats, rte_stats_strings[i].offset); val = *stats_ptr; - xstats[count].name[0] = '\0'; xstats[count].id = count + xcount; xstats[count++].value = val; } @@ -1639,7 +1638,6 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, rte_rxq_stats_strings[i].offset + q * sizeof(uint64_t)); val = *stats_ptr; - xstats[count].name[0] = '\0'; xstats[count].id = count + xcount; xstats[count++].value = val; } @@ -1652,7 +1650,6 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, rte_txq_stats_strings[i].offset + q * sizeof(uint64_t)); val = *stats_ptr; - xstats[count].name[0] = '\0'; xstats[count].id = count + xcount; xstats[count++].value = val; } diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index d663d60..a82794d 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -915,8 +915,6 @@ struct rte_eth_txq_info { * structure. */ struct rte_eth_xstats { - /* FIXME: Remove name[] once remaining drivers converted */ - char name[RTE_ETH_XSTATS_NAME_SIZE]; uint64_t id; uint64_t value; }; -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [PATCH v3 09/10] remove name field from struct rte_eth_xstats 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 09/10] remove name field from struct rte_eth_xstats Remy Horton @ 2016-06-08 12:23 ` Thomas Monjalon 0 siblings, 0 replies; 71+ messages in thread From: Thomas Monjalon @ 2016-06-08 12:23 UTC (permalink / raw) To: Remy Horton; +Cc: dev, Helin Zhang, Wenzhuo Lu, Jing Chen, Huawei Xie 2016-05-30 11:48, Remy Horton: > struct rte_eth_xstats { > - /* FIXME: Remove name[] once remaining drivers converted */ > - char name[RTE_ETH_XSTATS_NAME_SIZE]; > uint64_t id; > uint64_t value; > }; While changing the content of this struct, it can be the opportunity to fix its name from rte_eth_xstats to rte_eth_xstat. ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v3 10/10] doc: update xstats documentation 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 00/10] " Remy Horton ` (8 preceding siblings ...) 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 09/10] remove name field from struct rte_eth_xstats Remy Horton @ 2016-05-30 10:48 ` Remy Horton 2016-06-09 8:48 ` Mcnamara, John 2016-06-06 12:45 ` [dpdk-dev] [PATCH v3 00/10] Remove string operations from xstats David Harton (dharton) 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 0/8] " Remy Horton 11 siblings, 1 reply; 71+ messages in thread From: Remy Horton @ 2016-05-30 10:48 UTC (permalink / raw) To: dev Signed-off-by: Remy Horton <remy.horton@intel.com> --- doc/guides/prog_guide/poll_mode_drv.rst | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/doc/guides/prog_guide/poll_mode_drv.rst b/doc/guides/prog_guide/poll_mode_drv.rst index 7698692..6cd86dd 100644 --- a/doc/guides/prog_guide/poll_mode_drv.rst +++ b/doc/guides/prog_guide/poll_mode_drv.rst @@ -299,10 +299,27 @@ 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. +of statistics. Accessing these from application programs is done via three +functions: + +* ``rte_eth_xstats_count``: Fetches the number of extended statistics. +* ``rte_eth_xstats_get``: Fills in an array of ``struct rte_eth_xstats`` + with extended statistics. +* ``rte_eth_xstats_names``: Fills in an array of ``struct rte_eth_name`` + with extended statistic name lookup information. + +Each ``struct rte_eth_xstats`` contains an identifier and value pair, and +each ``struct rte_eth_xstats_name`` contains an identifier and string pair. +Each identifier within ``struct rte_eth_xstats`` must have a corresponding +entry in ``struct rte_eth_xstats_name`` with a matching identifier. These +identifiers, as well as the number of extended statistic exposed, must +remain constant during runtime. + +Note that extended statistic identifiers are driver-specific, and hence +might not be the same for different ports. Although it is expected that +drivers will make the identifiers used within ``struct rte_eth_xstats`` and +``struct rte_eth_xstats_name`` entries match the entries' array index, this +property should not be relied on by applications for lookups. 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 -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [PATCH v3 10/10] doc: update xstats documentation 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 10/10] doc: update xstats documentation Remy Horton @ 2016-06-09 8:48 ` Mcnamara, John 0 siblings, 0 replies; 71+ messages in thread From: Mcnamara, John @ 2016-06-09 8:48 UTC (permalink / raw) To: Horton, Remy, dev > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Remy Horton > Sent: Monday, May 30, 2016 11:48 AM > To: dev@dpdk.org > Subject: [dpdk-dev] [PATCH v3 10/10] doc: update xstats documentation > > Signed-off-by: Remy Horton <remy.horton@intel.com> Good clear update. Acked-by: John McNamara <john.mcnamara@intel.com> ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [PATCH v3 00/10] Remove string operations from xstats 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 00/10] " Remy Horton ` (9 preceding siblings ...) 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 10/10] doc: update xstats documentation Remy Horton @ 2016-06-06 12:45 ` David Harton (dharton) 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 0/8] " Remy Horton 11 siblings, 0 replies; 71+ messages in thread From: David Harton (dharton) @ 2016-06-06 12:45 UTC (permalink / raw) To: Remy Horton, dev, Thomas Monjalon, Helin Zhang, Wenzhuo Lu, Jing Chen, Huawei Xie Acked-by: David Harton <dharton@cisco.com> > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Remy Horton > Sent: Monday, May 30, 2016 6:48 AM > To: dev@dpdk.org; Thomas Monjalon <thomas.monjalon@6wind.com>; Helin Zhang > <helin.zhang@intel.com>; Wenzhuo Lu <wenzhuo.lu@intel.com>; Jing Chen > <jing.d.chen@intel.com>; Huawei Xie <huawei.xie@intel.com> > Subject: [dpdk-dev] [PATCH v3 00/10] Remove string operations from xstats > > The current extended ethernet statistics fetching involve doing several > string operations, which causes performance issues if there are lots of > statistics and/or network interfaces. This patchset changes the API for > xstats to use integer identifiers instead of strings and implements > this new API for the ixgbe, i40e, e1000, fm10k, and virtio drivers. > > -- > > v3 changes: > * Corrected ixgbe vf xstats fetching > * Added xstats changes to e1000, f10k, and virtio drivers > * Added cleanup patch that removes now-redundant name field > * Removed ethtool xstats command > * Removed unused .xstats_count from eth-dev_ops > * Changed test-pmd & proc_info to use new API > * Added documentation update > * Added missing changes to .map file (affected shared lib builds) > > v2 changes: > * Fetching xstats count now seperate API function > * Added #define constants for some magic numbers > * Fixed bug with virtual function count fetching > * For non-xstats-supporting drivers, queue stats returned > * Some refactoring/cleanups > * Removed index assumption from example > > Remy Horton (10): > rte: change xstats to use integer ids > drivers/net/ixgbe: change xstats to use integer ids > drivers/net/e1000: change xstats to use integer ids > drivers/net/fm10k: change xstats to use integer ids > drivers/net/i40e: change xstats to use integer ids > drivers/net/virtio: change xstats to use integer ids > app/test-pmd: change xstats to use integer ids > app/proc_info: change xstats to use integer ids > remove name field from struct rte_eth_xstats > doc: update xstats documentation > > app/proc_info/main.c | 26 ++++++++- > app/test-pmd/config.c | 52 +++++++++++++---- > doc/guides/prog_guide/poll_mode_drv.rst | 25 +++++++-- > drivers/net/e1000/igb_ethdev.c | 50 +++++++++++++++-- > drivers/net/fm10k/fm10k_ethdev.c | 52 ++++++++++++++--- > drivers/net/i40e/i40e_ethdev.c | 77 +++++++++++++++++++++----- > drivers/net/i40e/i40e_ethdev_vf.c | 24 +++++++- > drivers/net/ixgbe/ixgbe_ethdev.c | 98 > ++++++++++++++++++++++++++++----- > drivers/net/virtio/virtio_ethdev.c | 60 +++++++++++++++++--- > lib/librte_ether/rte_ethdev.c | 92 > ++++++++++++++++++++++++++++--- > lib/librte_ether/rte_ethdev.h | 44 ++++++++++++++- > lib/librte_ether/rte_ether_version.map | 7 +++ > 12 files changed, 527 insertions(+), 80 deletions(-) > > -- > 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v4 0/8] Remove string operations from xstats 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 00/10] " Remy Horton ` (10 preceding siblings ...) 2016-06-06 12:45 ` [dpdk-dev] [PATCH v3 00/10] Remove string operations from xstats David Harton (dharton) @ 2016-06-13 15:51 ` Remy Horton 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 1/8] rte: change xstats to use integer ids Remy Horton ` (8 more replies) 11 siblings, 9 replies; 71+ messages in thread From: Remy Horton @ 2016-06-13 15:51 UTC (permalink / raw) To: dev, Thomas Monjalon, Helin Zhang, Wenzhuo Lu, Jing Chen, Huawei Xie, John McNamara The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patchset changes the API for xstats to use integer identifiers instead of strings and implements this new API for the ixgbe, i40e, e1000, fm10k, and virtio drivers. -- v4 changes: * rte_eth_xstats_count() removed * rte_eth_xstats_names() changed to rte_eth_xstats_get_names() * struct rte_eth_xstats_name renamed to rte_eth_xstat_name * struct rte_eth_xstats renamed to rte_eth_xstat * struct rte_eth_dev: .xstats_names renamed to .xstats_get_names * Other minor local variable name changes * Documentation updates due to renames * API changeover patches squashed v3 changes: * Corrected ixgbe vf xstats fetching * Added xstats changes to e1000, f10k, and virtio drivers * Added cleanup patch that removes now-redundant name field * Removed ethtool xstats command * Removed unused .xstats_count from eth-dev_ops * Changed test-pmd & proc_info to use new API * Added documentation update * Added missing changes to .map file (affected shared lib builds) v2 changes: * Fetching xstats count now seperate API function * Added #define constants for some magic numbers * Fixed bug with virtual function count fetching * For non-xstats-supporting drivers, queue stats returned * Some refactoring/cleanups * Removed index assumption from example Remy Horton (8): rte: change xstats to use integer ids drivers/net/ixgbe: change xstats to use integer ids drivers/net/e1000: change xstats to use integer ids drivers/net/fm10k: change xstats to use integer ids drivers/net/i40e: change xstats to use integer ids drivers/net/virtio: change xstats to use integer ids rte: change xstats usage to new API doc: update xstats documentation app/proc_info/main.c | 29 +++++++-- app/test-pmd/config.c | 54 ++++++++++++---- doc/guides/prog_guide/poll_mode_drv.rst | 25 ++++++-- drivers/net/e1000/igb_ethdev.c | 58 ++++++++++++++--- drivers/net/fm10k/fm10k_ethdev.c | 54 +++++++++++++--- drivers/net/i40e/i40e_ethdev.c | 82 +++++++++++++++++++----- drivers/net/i40e/i40e_ethdev_vf.c | 29 +++++++-- drivers/net/ixgbe/ixgbe_ethdev.c | 106 ++++++++++++++++++++++++++------ drivers/net/virtio/virtio_ethdev.c | 64 ++++++++++++++++--- lib/librte_ether/rte_ethdev.c | 93 +++++++++++++++++++++++++--- lib/librte_ether/rte_ethdev.h | 42 +++++++++++-- lib/librte_ether/rte_ether_version.map | 7 +++ 12 files changed, 542 insertions(+), 101 deletions(-) -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v4 1/8] rte: change xstats to use integer ids 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 0/8] " Remy Horton @ 2016-06-13 15:51 ` Remy Horton 2016-06-15 9:19 ` Thomas Monjalon 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 2/8] drivers/net/ixgbe: " Remy Horton ` (7 subsequent siblings) 8 siblings, 1 reply; 71+ messages in thread From: Remy Horton @ 2016-06-13 15:51 UTC (permalink / raw) To: dev, Thomas Monjalon Signed-off-by: Remy Horton <remy.horton@intel.com> --- lib/librte_ether/rte_ethdev.c | 94 +++++++++++++++++++++++++++++++--- lib/librte_ether/rte_ethdev.h | 35 +++++++++++++ lib/librte_ether/rte_ether_version.map | 7 +++ 3 files changed, 128 insertions(+), 8 deletions(-) diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index e148028..79a01cc 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -1502,6 +1502,86 @@ rte_eth_stats_reset(uint8_t port_id) dev->data->rx_mbuf_alloc_failed = 0; } +static int +get_xstats_count(uint8_t port_id) +{ + struct rte_eth_dev *dev; + int count; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); + dev = &rte_eth_devices[port_id]; + if (dev->dev_ops->xstats_get_names != NULL) { + count = (*dev->dev_ops->xstats_get_names)(dev, NULL, 0); + if (count < 0) + return count; + } else + count = 0; + count += RTE_NB_STATS; + count += dev->data->nb_rx_queues * RTE_NB_RXQ_STATS; + count += dev->data->nb_tx_queues * RTE_NB_TXQ_STATS; + return count; +} + +int +rte_eth_xstats_get_names(uint8_t port_id, + struct rte_eth_xstat_name *xstats_names, + unsigned size) +{ + struct rte_eth_dev *dev; + int cnt_used_entries; + int cnt_expected_entries; + uint32_t idx, id_queue; + + cnt_expected_entries = get_xstats_count(port_id); + if (xstats_names == NULL || cnt_expected_entries < 0) + return cnt_expected_entries; + if ((int)size < cnt_expected_entries) + return -ERANGE; + + /* port_id checked in get_xstats_count() */ + dev = &rte_eth_devices[port_id]; + if (dev->dev_ops->xstats_get_names != NULL) { + cnt_used_entries = (*dev->dev_ops->xstats_get_names)( + dev, xstats_names, size); + if (cnt_used_entries < 0) + return cnt_used_entries; + } else + /* Driver itself does not support extended stats, but + * still have basic stats. + */ + cnt_used_entries = 0; + + for (idx = 0; idx < RTE_NB_STATS; idx++) { + xstats_names[cnt_used_entries].id = cnt_used_entries; + snprintf(xstats_names[cnt_used_entries].name, + sizeof(xstats_names[0].name), + "%s", rte_stats_strings[idx].name); + cnt_used_entries++; + } + for (id_queue = 0; id_queue < dev->data->nb_rx_queues; id_queue++) { + for (idx = 0; idx < RTE_NB_RXQ_STATS; idx++) { + xstats_names[cnt_used_entries].id = cnt_used_entries; + 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++; + } + + } + for (id_queue = 0; id_queue < dev->data->nb_tx_queues; id_queue++) { + for (idx = 0; idx < RTE_NB_TXQ_STATS; idx++) { + xstats_names[cnt_used_entries].id = cnt_used_entries; + 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++; + } + } + return cnt_used_entries; +} + /* retrieve ethdev extended statistics */ int rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, @@ -1546,8 +1626,8 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, stats_ptr = RTE_PTR_ADD(ð_stats, rte_stats_strings[i].offset); val = *stats_ptr; - snprintf(xstats[count].name, sizeof(xstats[count].name), - "%s", rte_stats_strings[i].name); + xstats[count].name[0] = '\0'; + xstats[count].id = count + xcount; xstats[count++].value = val; } @@ -1558,9 +1638,8 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, rte_rxq_stats_strings[i].offset + q * sizeof(uint64_t)); val = *stats_ptr; - snprintf(xstats[count].name, sizeof(xstats[count].name), - "rx_q%u_%s", q, - rte_rxq_stats_strings[i].name); + xstats[count].name[0] = '\0'; + xstats[count].id = count + xcount; xstats[count++].value = val; } } @@ -1572,9 +1651,8 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, rte_txq_stats_strings[i].offset + q * sizeof(uint64_t)); val = *stats_ptr; - snprintf(xstats[count].name, sizeof(xstats[count].name), - "tx_q%u_%s", q, - rte_txq_stats_strings[i].name); + xstats[count].name[0] = '\0'; + xstats[count].id = count + xcount; xstats[count++].value = val; } } diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index 2757510..7d8ce3c 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -916,9 +916,21 @@ struct rte_eth_txq_info { */ struct rte_eth_xstats { char name[RTE_ETH_XSTATS_NAME_SIZE]; + uint64_t id; uint64_t value; }; +/** + * A name-key lookup element for extended statistics. + * + * This structure is used to map between names and ID numbers + * for extended ethernet statistics. + */ +struct rte_eth_xstat_name { + char name[RTE_ETH_XSTATS_NAME_SIZE]; + uint64_t id; +}; + #define ETH_DCB_NUM_TCS 8 #define ETH_MAX_VMDQ_POOL 64 @@ -1054,6 +1066,10 @@ typedef int (*eth_xstats_get_t)(struct rte_eth_dev *dev, typedef void (*eth_xstats_reset_t)(struct rte_eth_dev *dev); /**< @internal Reset extended stats of an Ethernet device. */ +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_queue_stats_mapping_set_t)(struct rte_eth_dev *dev, uint16_t queue_id, uint8_t stat_idx, @@ -1401,6 +1417,8 @@ struct eth_dev_ops { eth_stats_reset_t stats_reset; /**< Reset generic device statistics. */ eth_xstats_get_t xstats_get; /**< Get extended device statistics. */ eth_xstats_reset_t xstats_reset; /**< Reset extended device statistics. */ + eth_xstats_get_names_t xstats_get_names; + /**< Get names of extended statistics. */ eth_queue_stats_mapping_set_t queue_stats_mapping_set; /**< Configure per queue stat counter mapping. */ eth_dev_infos_get_t dev_infos_get; /**< Get device info. */ @@ -2253,6 +2271,23 @@ int rte_eth_stats_get(uint8_t port_id, struct rte_eth_stats *stats); void rte_eth_stats_reset(uint8_t port_id); /** + * Retrieve names of extended statistics of an Ethernet device. + * + * @param port_id + * The port identifier of the Ethernet device. + * @param xstats_names + * Block of memory to insert names into. Must be at least size in capacity. + * If set to NULL, function returns required capacity. + * @param size + * Capacity of xstats_names (number of names). + * @return + * If successful, number of statistics; negative on error. + */ +int rte_eth_xstats_get_names(uint8_t port_id, + struct rte_eth_xstat_name *xstats_names, + unsigned size); + +/** * Retrieve extended statistics of an Ethernet device. * * @param port_id diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map index 214ecc7..bb339e1 100644 --- a/lib/librte_ether/rte_ether_version.map +++ b/lib/librte_ether/rte_ether_version.map @@ -132,3 +132,10 @@ DPDK_16.04 { rte_eth_tx_buffer_set_err_callback; } DPDK_2.2; + +DPDK_16.07 { + global: + + rte_eth_xstats_names; + rte_eth_xstats_count; +} DPDK_16.04; -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [PATCH v4 1/8] rte: change xstats to use integer ids 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 1/8] rte: change xstats to use integer ids Remy Horton @ 2016-06-15 9:19 ` Thomas Monjalon 0 siblings, 0 replies; 71+ messages in thread From: Thomas Monjalon @ 2016-06-15 9:19 UTC (permalink / raw) To: Remy Horton; +Cc: dev 2016-06-13 16:51, Remy Horton: > Signed-off-by: Remy Horton <remy.horton@intel.com> Please insert an explanation of why this change is needed. [...] > /** > + * Retrieve names of extended statistics of an Ethernet device. > + * > + * @param port_id > + * The port identifier of the Ethernet device. > + * @param xstats_names > + * Block of memory to insert names into. Must be at least size in capacity. > + * If set to NULL, function returns required capacity. > + * @param size > + * Capacity of xstats_names (number of names). > + * @return > + * If successful, number of statistics; negative on error. > + */ Like in rte_eth_xstats_get(), it should return a positive value if size is not big enough. > +int rte_eth_xstats_get_names(uint8_t port_id, > + struct rte_eth_xstat_name *xstats_names, > + unsigned size); [...] > +DPDK_16.07 { > + global: > + > + rte_eth_xstats_names; > + rte_eth_xstats_count; > +} DPDK_16.04; Wrong functions. ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v4 2/8] drivers/net/ixgbe: change xstats to use integer ids 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 0/8] " Remy Horton 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 1/8] rte: change xstats to use integer ids Remy Horton @ 2016-06-13 15:51 ` Remy Horton 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 3/8] drivers/net/e1000: " Remy Horton ` (6 subsequent siblings) 8 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-06-13 15:51 UTC (permalink / raw) To: dev, Helin Zhang, Thomas Monjalon The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the ixgbe driver to use the new API that seperates name string and value queries. Signed-off-by: Remy Horton <remy.horton@intel.com> --- drivers/net/ixgbe/ixgbe_ethdev.c | 101 +++++++++++++++++++++++++++++++++------ 1 file changed, 86 insertions(+), 15 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c index a2b170b..9e73492 100644 --- a/drivers/net/ixgbe/ixgbe_ethdev.c +++ b/drivers/net/ixgbe/ixgbe_ethdev.c @@ -179,6 +179,10 @@ 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_xstats_get_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, __rte_unused unsigned limit); +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, uint16_t queue_id, uint8_t stat_idx, @@ -466,6 +470,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = { .xstats_get = ixgbe_dev_xstats_get, .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, .dev_infos_get = ixgbe_dev_info_get, .dev_supported_ptypes_get = ixgbe_dev_supported_ptypes_get, @@ -555,6 +560,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = { .xstats_get = ixgbevf_dev_xstats_get, .stats_reset = ixgbevf_dev_stats_reset, .xstats_reset = ixgbevf_dev_stats_reset, + .xstats_get_names = ixgbevf_dev_xstats_get_names, .dev_close = ixgbevf_dev_close, .allmulticast_enable = ixgbevf_dev_allmulticast_enable, .allmulticast_disable = ixgbevf_dev_allmulticast_disable, @@ -685,6 +691,7 @@ static const struct rte_ixgbe_xstats_name_off rte_ixgbe_rxq_strings[] = { #define IXGBE_NB_RXQ_PRIO_STATS (sizeof(rte_ixgbe_rxq_strings) / \ sizeof(rte_ixgbe_rxq_strings[0])) +#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)}, @@ -695,6 +702,7 @@ static const struct rte_ixgbe_xstats_name_off rte_ixgbe_txq_strings[] = { #define IXGBE_NB_TXQ_PRIO_STATS (sizeof(rte_ixgbe_txq_strings) / \ sizeof(rte_ixgbe_txq_strings[0])) +#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)}, @@ -2695,8 +2703,75 @@ ixgbe_dev_stats_reset(struct rte_eth_dev *dev) /* This function calculates the number of xstats based on the current config */ static unsigned ixgbe_xstats_calc_num(void) { - return IXGBE_NB_HW_STATS + (IXGBE_NB_RXQ_PRIO_STATS * 8) + - (IXGBE_NB_TXQ_PRIO_STATS * 8); + return IXGBE_NB_HW_STATS + + (IXGBE_NB_RXQ_PRIO_STATS * IXGBE_NB_RXQ_PRIO_VALUES) + + (IXGBE_NB_TXQ_PRIO_STATS * IXGBE_NB_TXQ_PRIO_VALUES); +} + +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) +{ + const unsigned cnt_stats = ixgbe_xstats_calc_num(); + unsigned 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++) { + xstats_names[count].id = count; + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "%s", + rte_ixgbe_stats_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++) { + xstats_names[count].id = count; + 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++) { + xstats_names[count].id = count; + 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) +{ + unsigned i; + + if (limit < IXGBEVF_NB_XSTATS && xstats_names != NULL) + return -ENOMEM; + + if (xstats_names != NULL) + for (i = 0; i < IXGBEVF_NB_XSTATS; i++) + snprintf(xstats_names[i].name, + sizeof(xstats_names[i].name), + "%s", rte_ixgbevf_stats_strings[i].name); + return IXGBEVF_NB_XSTATS; } static int @@ -2732,8 +2807,8 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* 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].id = count; + xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_stats_strings[i].offset); count++; @@ -2741,10 +2816,9 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* RX Priority Stats */ for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) { - for (i = 0; i < 8; i++) { - snprintf(xstats[count].name, sizeof(xstats[count].name), - "rx_priority%u_%s", i, - rte_ixgbe_rxq_strings[stat].name); + for (i = 0; i < IXGBE_NB_RXQ_PRIO_VALUES; i++) { + xstats[count].id = count; + xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_rxq_strings[stat].offset + (sizeof(uint64_t) * i)); @@ -2754,17 +2828,15 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* TX Priority Stats */ for (stat = 0; stat < IXGBE_NB_TXQ_PRIO_STATS; stat++) { - for (i = 0; i < 8; i++) { - snprintf(xstats[count].name, sizeof(xstats[count].name), - "tx_priority%u_%s", i, - rte_ixgbe_txq_strings[stat].name); + for (i = 0; i < IXGBE_NB_TXQ_PRIO_VALUES; i++) { + xstats[count].id = count; + xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_txq_strings[stat].offset + (sizeof(uint64_t) * i)); count++; } } - return count; } @@ -2829,8 +2901,7 @@ ixgbevf_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* 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].id = i; xstats[i].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbevf_stats_strings[i].offset); } -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v4 3/8] drivers/net/e1000: change xstats to use integer ids 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 0/8] " Remy Horton 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 1/8] rte: change xstats to use integer ids Remy Horton 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 2/8] drivers/net/ixgbe: " Remy Horton @ 2016-06-13 15:51 ` Remy Horton 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 4/8] drivers/net/fm10k: " Remy Horton ` (5 subsequent siblings) 8 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-06-13 15:51 UTC (permalink / raw) To: dev, Wenzhuo Lu, Thomas Monjalon The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the e1000 driver to use the new API that seperates name string and value queries. Signed-off-by: Remy Horton <remy.horton@intel.com> --- drivers/net/e1000/igb_ethdev.c | 52 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c index f0921ee..dffa04f 100644 --- a/drivers/net/e1000/igb_ethdev.c +++ b/drivers/net/e1000/igb_ethdev.c @@ -100,6 +100,9 @@ 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 int eth_igb_xstats_get_names(struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + unsigned limit); 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, @@ -165,6 +168,9 @@ 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 int eth_igbvf_xstats_get_names(struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + unsigned limit); 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); @@ -324,6 +330,7 @@ static const struct eth_dev_ops eth_igb_ops = { .link_update = eth_igb_link_update, .stats_get = eth_igb_stats_get, .xstats_get = eth_igb_xstats_get, + .xstats_get_names = eth_igb_xstats_get_names, .stats_reset = eth_igb_stats_reset, .xstats_reset = eth_igb_xstats_reset, .dev_infos_get = eth_igb_infos_get, @@ -385,6 +392,7 @@ static const struct eth_dev_ops igbvf_eth_dev_ops = { .link_update = eth_igb_link_update, .stats_get = eth_igbvf_stats_get, .xstats_get = eth_igbvf_xstats_get, + .xstats_get_names = eth_igbvf_xstats_get_names, .stats_reset = eth_igbvf_stats_reset, .xstats_reset = eth_igbvf_stats_reset, .vlan_filter_set = igbvf_vlan_filter_set, @@ -1691,6 +1699,26 @@ eth_igb_xstats_reset(struct rte_eth_dev *dev) memset(stats, 0, sizeof(*stats)); } +static int eth_igb_xstats_get_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + __rte_unused unsigned limit) +{ + unsigned i; + + if (xstats_names == NULL) + return IGB_NB_XSTATS; + + /* Note: limit checked in rte_eth_xstats_names() */ + + for (i = 0; i < IGB_NB_XSTATS; i++) { + snprintf(xstats_names[i].name, sizeof(xstats_names[i].name), + "%s", rte_igb_stats_strings[i].name); + xstats_names[i].id = i; + } + + return IGB_NB_XSTATS; +} + static int eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned n) @@ -1713,8 +1741,8 @@ eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* 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].name[0] = '\0'; + xstats[i].id = i; xstats[i].value = *(uint64_t *)(((char *)hw_stats) + rte_igb_stats_strings[i].offset); } @@ -1762,6 +1790,22 @@ igbvf_read_stats_registers(struct e1000_hw *hw, struct e1000_vf_stats *hw_stats) hw_stats->last_gotlbc, hw_stats->gotlbc); } +static int eth_igbvf_xstats_get_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + __rte_unused unsigned limit) +{ + unsigned i; + + if (xstats_names != NULL) + for (i = 0; i < IGBVF_NB_XSTATS; i++) { + snprintf(xstats_names[i].name, + sizeof(xstats_names[i].name), "%s", + rte_igbvf_stats_strings[i].name); + xstats_names[i].id = i; + } + return IGBVF_NB_XSTATS; +} + static int eth_igbvf_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned n) @@ -1780,8 +1824,8 @@ eth_igbvf_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *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].name[0] = '\0'; + xstats[i].id = i; xstats[i].value = *(uint64_t *)(((char *)hw_stats) + rte_igbvf_stats_strings[i].offset); } -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v4 4/8] drivers/net/fm10k: change xstats to use integer ids 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 0/8] " Remy Horton ` (2 preceding siblings ...) 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 3/8] drivers/net/e1000: " Remy Horton @ 2016-06-13 15:51 ` Remy Horton 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 5/8] drivers/net/i40e: " Remy Horton ` (4 subsequent siblings) 8 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-06-13 15:51 UTC (permalink / raw) To: dev, Jing Chen, Thomas Monjalon The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the fm10k driver to use the new API that seperates name string and value queries. Signed-off-by: Remy Horton <remy.horton@intel.com> --- drivers/net/fm10k/fm10k_ethdev.c | 55 +++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c index c2d377f..e07c1ec 100644 --- a/drivers/net/fm10k/fm10k_ethdev.c +++ b/drivers/net/fm10k/fm10k_ethdev.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2013-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2013-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -1256,6 +1256,47 @@ fm10k_link_update(struct rte_eth_dev *dev, return 0; } +static int fm10k_xstats_get_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, __rte_unused unsigned limit) +{ + unsigned i, q; + unsigned count = 0; + + if (xstats_names != NULL) { + /* Note: limit checked in rte_eth_xstats_names() */ + + /* Global stats */ + for (i = 0; i < FM10K_NB_HW_XSTATS; i++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "%s", fm10k_hw_stats_strings[count].name); + xstats_names[count].id = count; + 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_names[count].name, + sizeof(xstats_names[count].name), + "rx_q%u_%s", q, + fm10k_hw_stats_rx_q_strings[i].name); + xstats_names[count].id = count; + count++; + } + for (i = 0; i < FM10K_NB_TX_Q_XSTATS; i++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "tx_q%u_%s", q, + fm10k_hw_stats_tx_q_strings[i].name); + xstats_names[count].id = count; + count++; + } + } + } + return FM10K_NB_XSTATS; +} + static int fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned n) @@ -1269,8 +1310,7 @@ fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *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].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + fm10k_hw_stats_strings[count].offset); count++; @@ -1279,18 +1319,14 @@ fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* 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].name[0] = '\0'; 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].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)&hw_stats->q[q]) + fm10k_hw_stats_tx_q_strings[i].offset); @@ -2629,6 +2665,7 @@ static const struct eth_dev_ops fm10k_eth_dev_ops = { .allmulticast_disable = fm10k_dev_allmulticast_disable, .stats_get = fm10k_stats_get, .xstats_get = fm10k_xstats_get, + .xstats_get_names = fm10k_xstats_get_names, .stats_reset = fm10k_stats_reset, .xstats_reset = fm10k_stats_reset, .link_update = fm10k_link_update, -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v4 5/8] drivers/net/i40e: change xstats to use integer ids 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 0/8] " Remy Horton ` (3 preceding siblings ...) 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 4/8] drivers/net/fm10k: " Remy Horton @ 2016-06-13 15:51 ` Remy Horton 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 6/8] drivers/net/virtio: " Remy Horton ` (3 subsequent siblings) 8 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-06-13 15:51 UTC (permalink / raw) To: dev, Helin Zhang, Thomas Monjalon The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the i40e driver to use the new API that seperates name string and value queries. Signed-off-by: Remy Horton <remy.horton@intel.com> --- drivers/net/i40e/i40e_ethdev.c | 82 ++++++++++++++++++++++++++++++++------- drivers/net/i40e/i40e_ethdev_vf.c | 26 +++++++++++-- 2 files changed, 91 insertions(+), 17 deletions(-) diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 24777d5..d712bbe 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -306,6 +306,9 @@ 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 int i40e_dev_xstats_get_names(struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + unsigned limit); static void i40e_dev_stats_reset(struct rte_eth_dev *dev); static int i40e_dev_queue_stats_mapping_set(struct rte_eth_dev *dev, uint16_t queue_id, @@ -467,6 +470,7 @@ static const struct eth_dev_ops i40e_eth_dev_ops = { .link_update = i40e_dev_link_update, .stats_get = i40e_dev_stats_get, .xstats_get = i40e_dev_xstats_get, + .xstats_get_names = i40e_dev_xstats_get_names, .stats_reset = i40e_dev_stats_reset, .xstats_reset = i40e_dev_stats_reset, .queue_stats_mapping_set = i40e_dev_queue_stats_mapping_set, @@ -2205,6 +2209,60 @@ i40e_xstats_calc_num(void) (I40E_NB_TXQ_PRIO_XSTATS * 8); } +static int i40e_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + __rte_unused unsigned limit) +{ + unsigned count = 0; + unsigned i, prio; + + if (xstats_names == NULL) + return i40e_xstats_calc_num(); + + /* Note: limit checked in rte_eth_xstats_names() */ + + /* Get stats from i40e_eth_stats struct */ + for (i = 0; i < I40E_NB_ETH_XSTATS; i++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "%s", rte_i40e_stats_strings[i].name); + xstats_names[count].id = count; + count++; + } + + /* Get individiual stats from i40e_hw_port struct */ + for (i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "%s", rte_i40e_hw_port_strings[i].name); + xstats_names[count].id = count; + count++; + } + + for (i = 0; i < I40E_NB_RXQ_PRIO_XSTATS; i++) { + for (prio = 0; prio < 8; prio++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "rx_priority%u_%s", prio, + rte_i40e_rxq_prio_strings[i].name); + xstats_names[count].id = count; + count++; + } + } + + for (i = 0; i < I40E_NB_TXQ_PRIO_XSTATS; i++) { + for (prio = 0; prio < 8; prio++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "tx_priority%u_%s", prio, + rte_i40e_txq_prio_strings[i].name); + xstats_names[count].id = count; + count++; + } + } + return count; +} + static int i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned n) @@ -2227,8 +2285,8 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* 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].name[0] = '\0'; + xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)&hw_stats->eth) + rte_i40e_stats_strings[i].offset); count++; @@ -2236,19 +2294,17 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* 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].name[0] = '\0'; + xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + - rte_i40e_hw_port_strings[i].offset); + rte_i40e_hw_port_strings[i].offset); count++; } for (i = 0; i < I40E_NB_RXQ_PRIO_XSTATS; i++) { for (prio = 0; prio < 8; prio++) { - snprintf(xstats[count].name, - sizeof(xstats[count].name), - "rx_priority%u_%s", prio, - rte_i40e_rxq_prio_strings[i].name); + xstats[count].name[0] = '\0'; + xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_i40e_rxq_prio_strings[i].offset + @@ -2259,10 +2315,8 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, for (i = 0; i < I40E_NB_TXQ_PRIO_XSTATS; i++) { for (prio = 0; prio < 8; prio++) { - snprintf(xstats[count].name, - sizeof(xstats[count].name), - "tx_priority%u_%s", prio, - rte_i40e_txq_prio_strings[i].name); + xstats[count].name[0] = '\0'; + xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_i40e_txq_prio_strings[i].offset + diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c index 90682ac..4c5e45e 100644 --- a/drivers/net/i40e/i40e_ethdev_vf.c +++ b/drivers/net/i40e/i40e_ethdev_vf.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -112,6 +112,9 @@ 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 int i40evf_dev_xstats_get_names(struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + unsigned limit); 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); @@ -196,6 +199,7 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = { .link_update = i40evf_dev_link_update, .stats_get = i40evf_dev_stats_get, .xstats_get = i40evf_dev_xstats_get, + .xstats_get_names = i40evf_dev_xstats_get_names, .xstats_reset = i40evf_dev_xstats_reset, .dev_close = i40evf_dev_close, .dev_infos_get = i40evf_dev_info_get, @@ -984,6 +988,22 @@ i40evf_dev_xstats_reset(struct rte_eth_dev *dev) vf->vsi.eth_stats_offset = vf->vsi.eth_stats; } +static int i40evf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + __rte_unused unsigned limit) +{ + unsigned i; + + if (xstats_names != NULL) + for (i = 0; i < I40EVF_NB_XSTATS; i++) { + snprintf(xstats_names[i].name, + sizeof(xstats_names[i].name), + "%s", rte_i40evf_stats_strings[i].name); + xstats_names[i].id = i; + } + return I40EVF_NB_XSTATS; +} + static int i40evf_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned n) { @@ -1003,8 +1023,8 @@ static int i40evf_dev_xstats_get(struct rte_eth_dev *dev, /* 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].name[0] = '\0'; + xstats[i].id = i; xstats[i].value = *(uint64_t *)(((char *)pstats) + rte_i40evf_stats_strings[i].offset); } -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v4 6/8] drivers/net/virtio: change xstats to use integer ids 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 0/8] " Remy Horton ` (4 preceding siblings ...) 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 5/8] drivers/net/i40e: " Remy Horton @ 2016-06-13 15:51 ` Remy Horton 2016-06-13 15:52 ` [dpdk-dev] [PATCH v4 7/8] rte: change xstats usage to new API Remy Horton ` (2 subsequent siblings) 8 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-06-13 15:51 UTC (permalink / raw) To: dev, Huawei Xie, Thomas Monjalon The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the virtio driver to use the new API that seperates name string and value queries. Signed-off-by: Remy Horton <remy.horton@intel.com> --- drivers/net/virtio/virtio_ethdev.c | 62 +++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c index c3fb628..83df025 100644 --- a/drivers/net/virtio/virtio_ethdev.c +++ b/drivers/net/virtio/virtio_ethdev.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -80,6 +80,9 @@ 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 int virtio_dev_xstats_get_names(struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + unsigned limit); 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, @@ -615,6 +618,7 @@ 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, + .xstats_get_names = virtio_dev_xstats_get_names, .stats_reset = virtio_dev_stats_reset, .xstats_reset = virtio_dev_stats_reset, .link_update = virtio_dev_link_update, @@ -708,6 +712,52 @@ virtio_update_stats(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_names(struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + __rte_unused unsigned limit) +{ + unsigned i; + unsigned count = 0; + unsigned t; + + unsigned nstats = dev->data->nb_tx_queues * VIRTIO_NB_Q_XSTATS + + dev->data->nb_rx_queues * VIRTIO_NB_Q_XSTATS; + + if (xstats_names == NULL) { + /* Note: limit checked in rte_eth_xstats_names() */ + + for (i = 0; i < dev->data->nb_rx_queues; i++) { + struct virtqueue *rxvq = dev->data->rx_queues[i]; + if (rxvq == NULL) + continue; + for (t = 0; t < VIRTIO_NB_Q_XSTATS; t++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "rx_q%u_%s", i, + rte_virtio_q_stat_strings[t].name); + xstats_names[count].id = count; + count++; + } + } + + for (i = 0; i < dev->data->nb_tx_queues; i++) { + struct virtqueue *txvq = dev->data->tx_queues[i]; + if (txvq == NULL) + continue; + for (t = 0; t < VIRTIO_NB_Q_XSTATS; t++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "tx_q%u_%s", i, + rte_virtio_q_stat_strings[t].name); + xstats_names[count].id = count; + count++; + } + } + return count; + } + return nstats; +} + static int virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned n) @@ -730,9 +780,8 @@ virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, 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].name[0] = '\0'; + xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)rxvq) + rte_virtio_q_stat_strings[t].offset); count++; @@ -748,9 +797,8 @@ virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, 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].name[0] = '\0'; + xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)txvq) + rte_virtio_q_stat_strings[t].offset); count++; -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v4 7/8] rte: change xstats usage to new API 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 0/8] " Remy Horton ` (5 preceding siblings ...) 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 6/8] drivers/net/virtio: " Remy Horton @ 2016-06-13 15:52 ` Remy Horton 2016-06-15 9:13 ` Thomas Monjalon 2016-06-13 15:52 ` [dpdk-dev] [PATCH v4 8/8] doc: update xstats documentation Remy Horton 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 0/7] Remove string operations from xstats Remy Horton 8 siblings, 1 reply; 71+ messages in thread From: Remy Horton @ 2016-06-13 15:52 UTC (permalink / raw) To: dev, Pablo de Lara, Maryam Tahhan, Thomas Monjalon, Helin Zhang, Wenzhuo Lu, Jing Chen, Huawei Xie The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the test-pmd and proc_info applications to use the new xstats API, and removes deprecated code associated with the old API. Signed-off-by: Remy Horton <remy.horton@intel.com> --- app/proc_info/main.c | 29 +++++++++++++++++--- app/test-pmd/config.c | 54 +++++++++++++++++++++++++++++--------- drivers/net/e1000/igb_ethdev.c | 10 +++---- drivers/net/fm10k/fm10k_ethdev.c | 5 +--- drivers/net/i40e/i40e_ethdev.c | 8 ++---- drivers/net/i40e/i40e_ethdev_vf.c | 5 ++-- drivers/net/ixgbe/ixgbe_ethdev.c | 11 +++----- drivers/net/virtio/virtio_ethdev.c | 6 ++--- lib/librte_ether/rte_ethdev.c | 5 +--- lib/librte_ether/rte_ethdev.h | 7 +++-- 10 files changed, 85 insertions(+), 55 deletions(-) diff --git a/app/proc_info/main.c b/app/proc_info/main.c index 5f83092..f2063fa 100644 --- a/app/proc_info/main.c +++ b/app/proc_info/main.c @@ -1,7 +1,7 @@ /* * BSD LICENSE * - * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -243,11 +243,13 @@ nic_stats_clear(uint8_t port_id) static void nic_xstats_display(uint8_t port_id) { - struct rte_eth_xstats *xstats; + struct rte_eth_xstat_name *xstats_names; + struct rte_eth_xstat *xstats; int len, ret, i; + int idx_name; static const char *nic_stats_border = "########################"; - len = rte_eth_xstats_get(port_id, NULL, 0); + len = rte_eth_xstats_get_names(port_id, NULL, 0); if (len < 0) { printf("Cannot get xstats count\n"); return; @@ -258,6 +260,18 @@ nic_xstats_display(uint8_t port_id) return; } + xstats_names = malloc(sizeof(struct rte_eth_xstat_name) * len); + if (xstats_names == NULL) { + printf("Cannot allocate memory for xstat names\n"); + free(xstats); + return; + } + if (len != rte_eth_xstats_get_names( + port_id, xstats_names, len)) { + printf("Cannot get xstat names\n"); + return; + } + printf("###### NIC extended statistics for port %-2d #########\n", port_id); printf("%s############################\n", @@ -270,11 +284,18 @@ nic_xstats_display(uint8_t port_id) } for (i = 0; i < len; i++) - printf("%s: %"PRIu64"\n", xstats[i].name, xstats[i].value); + for (idx_name = 0; idx_name < len; idx_name++) + if (xstats_names[idx_name].id == xstats[i].id) { + printf("%s: %"PRIu64"\n", + xstats_names[idx_name].name, + xstats[i].value); + break; + } printf("%s############################\n", nic_stats_border); free(xstats); + free(xstats_names); } static void diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 1c552e4..8ddec07 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -232,29 +232,57 @@ nic_stats_clear(portid_t port_id) void nic_xstats_display(portid_t port_id) { - struct rte_eth_xstats *xstats; - int len, ret, i; + struct rte_eth_xstat *xstats; + int cnt_xstats, idx_xstat, idx_name; + struct rte_eth_xstat_name *xstats_names; printf("###### NIC extended statistics for port %-2d\n", port_id); + if (!rte_eth_dev_is_valid_port(port_id)) { + printf("Error: Invalid port number %i\n", port_id); + return; + } + + /* 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; + } - len = rte_eth_xstats_get(port_id, NULL, 0); - if (len < 0) { - printf("Cannot get xstats count\n"); + /* 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; } - xstats = malloc(sizeof(xstats[0]) * len); + if (cnt_xstats != rte_eth_xstats_get_names( + port_id, xstats_names, cnt_xstats)) { + printf("Error: Cannot get xstats lookup\n"); + 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; } - ret = rte_eth_xstats_get(port_id, xstats, len); - if (ret < 0 || ret > len) { - printf("Cannot get xstats\n"); - free(xstats); + if (cnt_xstats != rte_eth_xstats_get(port_id, xstats, cnt_xstats)) { + printf("Error: Unable to get xstats\n"); return; } - for (i = 0; i < len; i++) - printf("%s: %"PRIu64"\n", xstats[i].name, xstats[i].value); + + /* Display xstats */ + for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++) + for (idx_name = 0; idx_name < cnt_xstats; idx_name++) + if (xstats_names[idx_name].id == xstats[idx_xstat].id) { + printf("%s: %"PRIu64"\n", + xstats_names[idx_name].name, + xstats[idx_xstat].value); + break; + } + free(xstats_names); free(xstats); } diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c index dffa04f..b822992 100644 --- a/drivers/net/e1000/igb_ethdev.c +++ b/drivers/net/e1000/igb_ethdev.c @@ -99,7 +99,7 @@ static int eth_igb_link_update(struct rte_eth_dev *dev, 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); + struct rte_eth_xstat *xstats, unsigned n); static int eth_igb_xstats_get_names(struct rte_eth_dev *dev, struct rte_eth_xstat_name *xstats_names, unsigned limit); @@ -167,7 +167,7 @@ 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 int eth_igbvf_xstats_get(struct rte_eth_dev *dev, - struct rte_eth_xstats *xstats, unsigned n); + struct rte_eth_xstat *xstats, unsigned n); static int eth_igbvf_xstats_get_names(struct rte_eth_dev *dev, struct rte_eth_xstat_name *xstats_names, unsigned limit); @@ -1720,7 +1720,7 @@ 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_xstats *xstats, +eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, unsigned n) { struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); @@ -1741,7 +1741,6 @@ eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* Extended stats */ for (i = 0; i < IGB_NB_XSTATS; i++) { - xstats[i].name[0] = '\0'; xstats[i].id = i; xstats[i].value = *(uint64_t *)(((char *)hw_stats) + rte_igb_stats_strings[i].offset); @@ -1807,7 +1806,7 @@ static int eth_igbvf_xstats_get_names(__rte_unused struct rte_eth_dev *dev, } static int -eth_igbvf_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, +eth_igbvf_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, unsigned n) { struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); @@ -1824,7 +1823,6 @@ eth_igbvf_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, return 0; for (i = 0; i < IGBVF_NB_XSTATS; i++) { - xstats[i].name[0] = '\0'; xstats[i].id = i; xstats[i].value = *(uint64_t *)(((char *)hw_stats) + rte_igbvf_stats_strings[i].offset); diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c index e07c1ec..ce053b0 100644 --- a/drivers/net/fm10k/fm10k_ethdev.c +++ b/drivers/net/fm10k/fm10k_ethdev.c @@ -1298,7 +1298,7 @@ static int fm10k_xstats_get_names(__rte_unused struct rte_eth_dev *dev, } static int -fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, +fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, unsigned n) { struct fm10k_hw_stats *hw_stats = @@ -1310,7 +1310,6 @@ fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* Global stats */ for (i = 0; i < FM10K_NB_HW_XSTATS; i++) { - xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + fm10k_hw_stats_strings[count].offset); count++; @@ -1319,14 +1318,12 @@ fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* PF queue stats */ for (q = 0; q < FM10K_MAX_QUEUES_PF; q++) { for (i = 0; i < FM10K_NB_RX_Q_XSTATS; i++) { - xstats[count].name[0] = '\0'; 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++) { - xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)&hw_stats->q[q]) + fm10k_hw_stats_tx_q_strings[i].offset); diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index d712bbe..f94ad87 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -305,7 +305,7 @@ 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); + struct rte_eth_xstat *xstats, unsigned n); static int i40e_dev_xstats_get_names(struct rte_eth_dev *dev, struct rte_eth_xstat_name *xstats_names, unsigned limit); @@ -2264,7 +2264,7 @@ static int i40e_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, } static int -i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, +i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, unsigned n) { struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); @@ -2285,7 +2285,6 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* Get stats from i40e_eth_stats struct */ for (i = 0; i < I40E_NB_ETH_XSTATS; i++) { - xstats[count].name[0] = '\0'; xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)&hw_stats->eth) + rte_i40e_stats_strings[i].offset); @@ -2294,7 +2293,6 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* Get individiual stats from i40e_hw_port struct */ for (i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) { - xstats[count].name[0] = '\0'; xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_i40e_hw_port_strings[i].offset); @@ -2303,7 +2301,6 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, for (i = 0; i < I40E_NB_RXQ_PRIO_XSTATS; i++) { for (prio = 0; prio < 8; prio++) { - xstats[count].name[0] = '\0'; xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + @@ -2315,7 +2312,6 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, for (i = 0; i < I40E_NB_TXQ_PRIO_XSTATS; i++) { for (prio = 0; prio < 8; prio++) { - xstats[count].name[0] = '\0'; xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c index 4c5e45e..37af399 100644 --- a/drivers/net/i40e/i40e_ethdev_vf.c +++ b/drivers/net/i40e/i40e_ethdev_vf.c @@ -111,7 +111,7 @@ static int i40evf_dev_link_update(struct rte_eth_dev *dev, 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); + struct rte_eth_xstat *xstats, unsigned n); static int i40evf_dev_xstats_get_names(struct rte_eth_dev *dev, struct rte_eth_xstat_name *xstats_names, unsigned limit); @@ -1005,7 +1005,7 @@ static int i40evf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, } static int i40evf_dev_xstats_get(struct rte_eth_dev *dev, - struct rte_eth_xstats *xstats, unsigned n) + struct rte_eth_xstat *xstats, unsigned n) { int ret; unsigned i; @@ -1023,7 +1023,6 @@ static int i40evf_dev_xstats_get(struct rte_eth_dev *dev, /* loop over xstats array and values from pstats */ for (i = 0; i < I40EVF_NB_XSTATS; i++) { - xstats[i].name[0] = '\0'; xstats[i].id = i; xstats[i].value = *(uint64_t *)(((char *)pstats) + rte_i40evf_stats_strings[i].offset); diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c index 9e73492..125c257 100644 --- a/drivers/net/ixgbe/ixgbe_ethdev.c +++ b/drivers/net/ixgbe/ixgbe_ethdev.c @@ -174,9 +174,9 @@ static int ixgbe_dev_link_update(struct rte_eth_dev *dev, 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); + struct rte_eth_xstat *xstats, unsigned n); static int ixgbevf_dev_xstats_get(struct rte_eth_dev *dev, - struct rte_eth_xstats *xstats, unsigned n); + 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_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, @@ -2775,7 +2775,7 @@ static int ixgbevf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, } static int -ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, +ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, unsigned n) { struct ixgbe_hw *hw = @@ -2808,7 +2808,6 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, count = 0; for (i = 0; i < IXGBE_NB_HW_STATS; i++) { xstats[count].id = count; - xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_stats_strings[i].offset); count++; @@ -2818,7 +2817,6 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) { for (i = 0; i < IXGBE_NB_RXQ_PRIO_VALUES; i++) { xstats[count].id = count; - xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_rxq_strings[stat].offset + (sizeof(uint64_t) * i)); @@ -2830,7 +2828,6 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, for (stat = 0; stat < IXGBE_NB_TXQ_PRIO_STATS; stat++) { for (i = 0; i < IXGBE_NB_TXQ_PRIO_VALUES; i++) { xstats[count].id = count; - xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_txq_strings[stat].offset + (sizeof(uint64_t) * i)); @@ -2884,7 +2881,7 @@ ixgbevf_update_stats(struct rte_eth_dev *dev) } static int -ixgbevf_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, +ixgbevf_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, unsigned n) { struct ixgbevf_hw_stats *hw_stats = (struct ixgbevf_hw_stats *) diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c index 83df025..a833740 100644 --- a/drivers/net/virtio/virtio_ethdev.c +++ b/drivers/net/virtio/virtio_ethdev.c @@ -79,7 +79,7 @@ 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 int virtio_dev_xstats_get(struct rte_eth_dev *dev, - struct rte_eth_xstats *xstats, unsigned n); + struct rte_eth_xstat *xstats, unsigned n); static int virtio_dev_xstats_get_names(struct rte_eth_dev *dev, struct rte_eth_xstat_name *xstats_names, unsigned limit); @@ -759,7 +759,7 @@ static int virtio_dev_xstats_get_names(struct rte_eth_dev *dev, } static int -virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, +virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, unsigned n) { unsigned i; @@ -780,7 +780,6 @@ virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned t; for (t = 0; t < VIRTIO_NB_Q_XSTATS; t++) { - xstats[count].name[0] = '\0'; xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)rxvq) + rte_virtio_q_stat_strings[t].offset); @@ -797,7 +796,6 @@ virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned t; for (t = 0; t < VIRTIO_NB_Q_XSTATS; t++) { - xstats[count].name[0] = '\0'; xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)txvq) + rte_virtio_q_stat_strings[t].offset); diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index 79a01cc..afe1291 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -1584,7 +1584,7 @@ rte_eth_xstats_get_names(uint8_t port_id, /* retrieve ethdev extended statistics */ int -rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, +rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstat *xstats, unsigned n) { struct rte_eth_stats eth_stats; @@ -1626,7 +1626,6 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, stats_ptr = RTE_PTR_ADD(ð_stats, rte_stats_strings[i].offset); val = *stats_ptr; - xstats[count].name[0] = '\0'; xstats[count].id = count + xcount; xstats[count++].value = val; } @@ -1638,7 +1637,6 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, rte_rxq_stats_strings[i].offset + q * sizeof(uint64_t)); val = *stats_ptr; - xstats[count].name[0] = '\0'; xstats[count].id = count + xcount; xstats[count++].value = val; } @@ -1651,7 +1649,6 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, rte_txq_stats_strings[i].offset + q * sizeof(uint64_t)); val = *stats_ptr; - xstats[count].name[0] = '\0'; xstats[count].id = count + xcount; xstats[count++].value = val; } diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index 7d8ce3c..76b9d61 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -914,8 +914,7 @@ struct rte_eth_txq_info { * statistics that are not provided in the generic rte_eth_stats * structure. */ -struct rte_eth_xstats { - char name[RTE_ETH_XSTATS_NAME_SIZE]; +struct rte_eth_xstat { uint64_t id; uint64_t value; }; @@ -1060,7 +1059,7 @@ typedef void (*eth_stats_reset_t)(struct rte_eth_dev *dev); /**< @internal Reset global I/O statistics of an Ethernet device to 0. */ typedef int (*eth_xstats_get_t)(struct rte_eth_dev *dev, - struct rte_eth_xstats *stats, unsigned n); + struct rte_eth_xstat *stats, unsigned n); /**< @internal Get extended stats of an Ethernet device. */ typedef void (*eth_xstats_reset_t)(struct rte_eth_dev *dev); @@ -2308,7 +2307,7 @@ int rte_eth_xstats_get_names(uint8_t port_id, * shall not be used by the caller. * - negative value on error (invalid port id) */ -int rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, +int rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstat *xstats, unsigned n); /** -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [PATCH v4 7/8] rte: change xstats usage to new API 2016-06-13 15:52 ` [dpdk-dev] [PATCH v4 7/8] rte: change xstats usage to new API Remy Horton @ 2016-06-15 9:13 ` Thomas Monjalon 0 siblings, 0 replies; 71+ messages in thread From: Thomas Monjalon @ 2016-06-15 9:13 UTC (permalink / raw) To: Remy Horton Cc: dev, Pablo de Lara, Maryam Tahhan, Helin Zhang, Wenzhuo Lu, Jing Chen, Huawei Xie 2016-06-13 16:52, Remy Horton: > The current extended ethernet statistics fetching involve doing several > string operations, which causes performance issues if there are lots of > statistics and/or network interfaces. This patch changes the test-pmd > and proc_info applications to use the new xstats API, and removes > deprecated code associated with the old API. There is something wrong which lead to this error: undefined reference to `rte_eth_xstats_get_names' ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v4 8/8] doc: update xstats documentation 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 0/8] " Remy Horton ` (6 preceding siblings ...) 2016-06-13 15:52 ` [dpdk-dev] [PATCH v4 7/8] rte: change xstats usage to new API Remy Horton @ 2016-06-13 15:52 ` Remy Horton 2016-06-14 14:06 ` Mcnamara, John 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 0/7] Remove string operations from xstats Remy Horton 8 siblings, 1 reply; 71+ messages in thread From: Remy Horton @ 2016-06-13 15:52 UTC (permalink / raw) To: dev, John McNamara, Thomas Monjalon Signed-off-by: Remy Horton <remy.horton@intel.com> --- doc/guides/prog_guide/poll_mode_drv.rst | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/doc/guides/prog_guide/poll_mode_drv.rst b/doc/guides/prog_guide/poll_mode_drv.rst index 7698692..802fb8f 100644 --- a/doc/guides/prog_guide/poll_mode_drv.rst +++ b/doc/guides/prog_guide/poll_mode_drv.rst @@ -299,10 +299,27 @@ 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. +of statistics. Accessing these from application programs is done via two +functions: + +* ``rte_eth_xstats_get``: Fills in an array of ``struct rte_eth_xstat`` + with extended statistics. +* ``rte_eth_xstats_get_names``: Fills in an array of + ``struct rte_eth_xstat_name`` with extended statistic name lookup + information. + +Each ``struct rte_eth_xstat`` contains an identifier and value pair, and +each ``struct rte_eth_xstat_name`` contains an identifier and string pair. +Each identifier within ``struct rte_eth_xstat`` must have a corresponding +entry in ``struct rte_eth_xstat_name`` with a matching identifier. These +identifiers, as well as the number of extended statistic exposed, must +remain constant during runtime. + +Note that extended statistic identifiers are driver-specific, and hence +might not be the same for different ports. Although it is expected that +drivers will make the identifiers used within ``struct rte_eth_xstat`` and +``struct rte_eth_xstat_name`` entries match the entries' array index, this +property should not be relied on by applications for lookups. 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 -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [PATCH v4 8/8] doc: update xstats documentation 2016-06-13 15:52 ` [dpdk-dev] [PATCH v4 8/8] doc: update xstats documentation Remy Horton @ 2016-06-14 14:06 ` Mcnamara, John 0 siblings, 0 replies; 71+ messages in thread From: Mcnamara, John @ 2016-06-14 14:06 UTC (permalink / raw) To: Horton, Remy, dev, Thomas Monjalon > -----Original Message----- > From: Horton, Remy > Sent: Monday, June 13, 2016 4:52 PM > To: dev@dpdk.org; Mcnamara, John <john.mcnamara@intel.com>; Thomas > Monjalon <thomas.monjalon@6wind.com> > Subject: [PATCH v4 8/8] doc: update xstats documentation > > Signed-off-by: Remy Horton <remy.horton@intel.com> Acked-by: John McNamara <john.mcnamara@intel.com> ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v5 0/7] Remove string operations from xstats 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 0/8] " Remy Horton ` (7 preceding siblings ...) 2016-06-13 15:52 ` [dpdk-dev] [PATCH v4 8/8] doc: update xstats documentation Remy Horton @ 2016-06-15 15:25 ` Remy Horton 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 1/7] rte: change xstats to use integer ids Remy Horton ` (7 more replies) 8 siblings, 8 replies; 71+ messages in thread From: Remy Horton @ 2016-06-15 15:25 UTC (permalink / raw) To: dev, Thomas Monjalon, John McNamara The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patchset changes the API for xstats to use integer identifiers instead of strings and implements this new API for the ixgbe, i40e, e1000, fm10k, and virtio drivers. -- v5 changes: * Missing .map file change added (broke shared builds) * rte_eth_xstats_get_names(): Changed buffer-too-small return value * Missing commit description added * Documentation patch squashed (had been ACK'd) v4 changes: * rte_eth_xstats_count() removed * rte_eth_xstats_names() changed to rte_eth_xstats_get_names() * struct rte_eth_xstats_name renamed to rte_eth_xstat_name * struct rte_eth_xstats renamed to rte_eth_xstat * struct rte_eth_dev: .xstats_names renamed to .xstats_get_names * Other minor local variable name changes * Documentation updates due to renames * API changeover patches squashed v3 changes: * Corrected ixgbe vf xstats fetching * Added xstats changes to e1000, f10k, and virtio drivers * Added cleanup patch that removes now-redundant name field * Removed ethtool xstats command * Removed unused .xstats_count from eth-dev_ops * Changed test-pmd & proc_info to use new API * Added documentation update * Added missing changes to .map file (affected shared lib builds) v2 changes: * Fetching xstats count now seperate API function * Added #define constants for some magic numbers * Fixed bug with virtual function count fetching * For non-xstats-supporting drivers, queue stats returned * Some refactoring/cleanups * Removed index assumption from example Remy Horton (7): rte: change xstats to use integer ids drivers/net/ixgbe: change xstats to use integer ids drivers/net/e1000: change xstats to use integer ids drivers/net/fm10k: change xstats to use integer ids drivers/net/i40e: change xstats to use integer ids drivers/net/virtio: change xstats to use integer ids rte: change xstats usage to new API app/proc_info/main.c | 29 +++++++-- app/test-pmd/config.c | 54 ++++++++++++---- doc/guides/prog_guide/poll_mode_drv.rst | 25 ++++++-- drivers/net/e1000/igb_ethdev.c | 58 ++++++++++++++--- drivers/net/fm10k/fm10k_ethdev.c | 54 +++++++++++++--- drivers/net/i40e/i40e_ethdev.c | 82 +++++++++++++++++++----- drivers/net/i40e/i40e_ethdev_vf.c | 29 +++++++-- drivers/net/ixgbe/ixgbe_ethdev.c | 106 ++++++++++++++++++++++++++------ drivers/net/virtio/virtio_ethdev.c | 64 ++++++++++++++++--- lib/librte_ether/rte_ethdev.c | 92 ++++++++++++++++++++++++--- lib/librte_ether/rte_ethdev.h | 48 +++++++++++++-- lib/librte_ether/rte_ether_version.map | 6 ++ 12 files changed, 546 insertions(+), 101 deletions(-) -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v5 1/7] rte: change xstats to use integer ids 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 0/7] Remove string operations from xstats Remy Horton @ 2016-06-15 15:25 ` Remy Horton 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 2/7] drivers/net/ixgbe: " Remy Horton ` (6 subsequent siblings) 7 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-06-15 15:25 UTC (permalink / raw) To: dev, Thomas Monjalon, John McNamara The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the xstats functions to instead use a numeric identifier rather than a string, and adds the ability to retrieve identifier-to-string mappings. Signed-off-by: Remy Horton <remy.horton@intel.com> --- doc/guides/prog_guide/poll_mode_drv.rst | 25 +++++++-- lib/librte_ether/rte_ethdev.c | 93 ++++++++++++++++++++++++++++++--- lib/librte_ether/rte_ethdev.h | 41 +++++++++++++++ lib/librte_ether/rte_ether_version.map | 6 +++ 4 files changed, 153 insertions(+), 12 deletions(-) diff --git a/doc/guides/prog_guide/poll_mode_drv.rst b/doc/guides/prog_guide/poll_mode_drv.rst index 7698692..802fb8f 100644 --- a/doc/guides/prog_guide/poll_mode_drv.rst +++ b/doc/guides/prog_guide/poll_mode_drv.rst @@ -299,10 +299,27 @@ 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. +of statistics. Accessing these from application programs is done via two +functions: + +* ``rte_eth_xstats_get``: Fills in an array of ``struct rte_eth_xstat`` + with extended statistics. +* ``rte_eth_xstats_get_names``: Fills in an array of + ``struct rte_eth_xstat_name`` with extended statistic name lookup + information. + +Each ``struct rte_eth_xstat`` contains an identifier and value pair, and +each ``struct rte_eth_xstat_name`` contains an identifier and string pair. +Each identifier within ``struct rte_eth_xstat`` must have a corresponding +entry in ``struct rte_eth_xstat_name`` with a matching identifier. These +identifiers, as well as the number of extended statistic exposed, must +remain constant during runtime. + +Note that extended statistic identifiers are driver-specific, and hence +might not be the same for different ports. Although it is expected that +drivers will make the identifiers used within ``struct rte_eth_xstat`` and +``struct rte_eth_xstat_name`` entries match the entries' array index, this +property should not be relied on by applications for lookups. 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 diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index e148028..98e5efb 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -1502,6 +1502,85 @@ rte_eth_stats_reset(uint8_t port_id) dev->data->rx_mbuf_alloc_failed = 0; } +static int +get_xstats_count(uint8_t port_id) +{ + struct rte_eth_dev *dev; + int count; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL); + dev = &rte_eth_devices[port_id]; + if (dev->dev_ops->xstats_get_names != NULL) { + count = (*dev->dev_ops->xstats_get_names)(dev, NULL, 0); + if (count < 0) + return count; + } else + count = 0; + count += RTE_NB_STATS; + count += dev->data->nb_rx_queues * RTE_NB_RXQ_STATS; + count += dev->data->nb_tx_queues * RTE_NB_TXQ_STATS; + return count; +} + +int +rte_eth_xstats_get_names(uint8_t port_id, + struct rte_eth_xstat_name *xstats_names, + unsigned size) +{ + struct rte_eth_dev *dev; + int cnt_used_entries; + int cnt_expected_entries; + uint32_t idx, id_queue; + + cnt_expected_entries = get_xstats_count(port_id); + 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]; + if (dev->dev_ops->xstats_get_names != NULL) { + cnt_used_entries = (*dev->dev_ops->xstats_get_names)( + dev, xstats_names, size); + if (cnt_used_entries < 0) + return cnt_used_entries; + } else + /* Driver itself does not support extended stats, but + * still have basic stats. + */ + cnt_used_entries = 0; + + for (idx = 0; idx < RTE_NB_STATS; idx++) { + xstats_names[cnt_used_entries].id = cnt_used_entries; + snprintf(xstats_names[cnt_used_entries].name, + sizeof(xstats_names[0].name), + "%s", rte_stats_strings[idx].name); + cnt_used_entries++; + } + for (id_queue = 0; id_queue < dev->data->nb_rx_queues; id_queue++) { + for (idx = 0; idx < RTE_NB_RXQ_STATS; idx++) { + xstats_names[cnt_used_entries].id = cnt_used_entries; + 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++; + } + + } + for (id_queue = 0; id_queue < dev->data->nb_tx_queues; id_queue++) { + for (idx = 0; idx < RTE_NB_TXQ_STATS; idx++) { + xstats_names[cnt_used_entries].id = cnt_used_entries; + 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++; + } + } + return cnt_used_entries; +} + /* retrieve ethdev extended statistics */ int rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, @@ -1546,8 +1625,8 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, stats_ptr = RTE_PTR_ADD(ð_stats, rte_stats_strings[i].offset); val = *stats_ptr; - snprintf(xstats[count].name, sizeof(xstats[count].name), - "%s", rte_stats_strings[i].name); + xstats[count].name[0] = '\0'; + xstats[count].id = count + xcount; xstats[count++].value = val; } @@ -1558,9 +1637,8 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, rte_rxq_stats_strings[i].offset + q * sizeof(uint64_t)); val = *stats_ptr; - snprintf(xstats[count].name, sizeof(xstats[count].name), - "rx_q%u_%s", q, - rte_rxq_stats_strings[i].name); + xstats[count].name[0] = '\0'; + xstats[count].id = count + xcount; xstats[count++].value = val; } } @@ -1572,9 +1650,8 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, rte_txq_stats_strings[i].offset + q * sizeof(uint64_t)); val = *stats_ptr; - snprintf(xstats[count].name, sizeof(xstats[count].name), - "tx_q%u_%s", q, - rte_txq_stats_strings[i].name); + xstats[count].name[0] = '\0'; + xstats[count].id = count + xcount; xstats[count++].value = val; } } diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index 2757510..5de86b8 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -916,9 +916,21 @@ struct rte_eth_txq_info { */ struct rte_eth_xstats { char name[RTE_ETH_XSTATS_NAME_SIZE]; + uint64_t id; uint64_t value; }; +/** + * A name-key lookup element for extended statistics. + * + * This structure is used to map between names and ID numbers + * for extended ethernet statistics. + */ +struct rte_eth_xstat_name { + char name[RTE_ETH_XSTATS_NAME_SIZE]; + uint64_t id; +}; + #define ETH_DCB_NUM_TCS 8 #define ETH_MAX_VMDQ_POOL 64 @@ -1054,6 +1066,10 @@ typedef int (*eth_xstats_get_t)(struct rte_eth_dev *dev, typedef void (*eth_xstats_reset_t)(struct rte_eth_dev *dev); /**< @internal Reset extended stats of an Ethernet device. */ +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_queue_stats_mapping_set_t)(struct rte_eth_dev *dev, uint16_t queue_id, uint8_t stat_idx, @@ -1401,6 +1417,8 @@ struct eth_dev_ops { eth_stats_reset_t stats_reset; /**< Reset generic device statistics. */ eth_xstats_get_t xstats_get; /**< Get extended device statistics. */ eth_xstats_reset_t xstats_reset; /**< Reset extended device statistics. */ + eth_xstats_get_names_t xstats_get_names; + /**< Get names of extended statistics. */ eth_queue_stats_mapping_set_t queue_stats_mapping_set; /**< Configure per queue stat counter mapping. */ eth_dev_infos_get_t dev_infos_get; /**< Get device info. */ @@ -2253,6 +2271,29 @@ int rte_eth_stats_get(uint8_t port_id, struct rte_eth_stats *stats); void rte_eth_stats_reset(uint8_t port_id); /** + * Retrieve names of extended statistics of an Ethernet device. + * + * @param port_id + * The port identifier of the Ethernet device. + * @param xstats_names + * Block of memory to insert names into. Must be at least size in capacity. + * If set to NULL, function returns required capacity. + * @param size + * Capacity of xstats_names (number of names). + * @return + * - positive value lower or equal to size: success. The return value + * is the number of entries filled in the stats table. + * - 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. + * - negative value on error (invalid port id) + */ +int rte_eth_xstats_get_names(uint8_t port_id, + struct rte_eth_xstat_name *xstats_names, + unsigned size); + +/** * Retrieve extended statistics of an Ethernet device. * * @param port_id diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map index 214ecc7..722b4d6 100644 --- a/lib/librte_ether/rte_ether_version.map +++ b/lib/librte_ether/rte_ether_version.map @@ -132,3 +132,9 @@ DPDK_16.04 { rte_eth_tx_buffer_set_err_callback; } DPDK_2.2; + +DPDK_16.07 { + global: + + rte_eth_xstats_get_names; +} DPDK_16.04; -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v5 2/7] drivers/net/ixgbe: change xstats to use integer ids 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 0/7] Remove string operations from xstats Remy Horton 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 1/7] rte: change xstats to use integer ids Remy Horton @ 2016-06-15 15:25 ` Remy Horton 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 3/7] drivers/net/e1000: " Remy Horton ` (5 subsequent siblings) 7 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-06-15 15:25 UTC (permalink / raw) To: dev, Thomas Monjalon The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the ixgbe driver to use the new API that seperates name string and value queries. Signed-off-by: Remy Horton <remy.horton@intel.com> --- drivers/net/ixgbe/ixgbe_ethdev.c | 101 +++++++++++++++++++++++++++++++++------ 1 file changed, 86 insertions(+), 15 deletions(-) diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c index a2b170b..9e73492 100644 --- a/drivers/net/ixgbe/ixgbe_ethdev.c +++ b/drivers/net/ixgbe/ixgbe_ethdev.c @@ -179,6 +179,10 @@ 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_xstats_get_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, __rte_unused unsigned limit); +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, uint16_t queue_id, uint8_t stat_idx, @@ -466,6 +470,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = { .xstats_get = ixgbe_dev_xstats_get, .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, .dev_infos_get = ixgbe_dev_info_get, .dev_supported_ptypes_get = ixgbe_dev_supported_ptypes_get, @@ -555,6 +560,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = { .xstats_get = ixgbevf_dev_xstats_get, .stats_reset = ixgbevf_dev_stats_reset, .xstats_reset = ixgbevf_dev_stats_reset, + .xstats_get_names = ixgbevf_dev_xstats_get_names, .dev_close = ixgbevf_dev_close, .allmulticast_enable = ixgbevf_dev_allmulticast_enable, .allmulticast_disable = ixgbevf_dev_allmulticast_disable, @@ -685,6 +691,7 @@ static const struct rte_ixgbe_xstats_name_off rte_ixgbe_rxq_strings[] = { #define IXGBE_NB_RXQ_PRIO_STATS (sizeof(rte_ixgbe_rxq_strings) / \ sizeof(rte_ixgbe_rxq_strings[0])) +#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)}, @@ -695,6 +702,7 @@ static const struct rte_ixgbe_xstats_name_off rte_ixgbe_txq_strings[] = { #define IXGBE_NB_TXQ_PRIO_STATS (sizeof(rte_ixgbe_txq_strings) / \ sizeof(rte_ixgbe_txq_strings[0])) +#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)}, @@ -2695,8 +2703,75 @@ ixgbe_dev_stats_reset(struct rte_eth_dev *dev) /* This function calculates the number of xstats based on the current config */ static unsigned ixgbe_xstats_calc_num(void) { - return IXGBE_NB_HW_STATS + (IXGBE_NB_RXQ_PRIO_STATS * 8) + - (IXGBE_NB_TXQ_PRIO_STATS * 8); + return IXGBE_NB_HW_STATS + + (IXGBE_NB_RXQ_PRIO_STATS * IXGBE_NB_RXQ_PRIO_VALUES) + + (IXGBE_NB_TXQ_PRIO_STATS * IXGBE_NB_TXQ_PRIO_VALUES); +} + +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) +{ + const unsigned cnt_stats = ixgbe_xstats_calc_num(); + unsigned 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++) { + xstats_names[count].id = count; + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "%s", + rte_ixgbe_stats_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++) { + xstats_names[count].id = count; + 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++) { + xstats_names[count].id = count; + 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) +{ + unsigned i; + + if (limit < IXGBEVF_NB_XSTATS && xstats_names != NULL) + return -ENOMEM; + + if (xstats_names != NULL) + for (i = 0; i < IXGBEVF_NB_XSTATS; i++) + snprintf(xstats_names[i].name, + sizeof(xstats_names[i].name), + "%s", rte_ixgbevf_stats_strings[i].name); + return IXGBEVF_NB_XSTATS; } static int @@ -2732,8 +2807,8 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* 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].id = count; + xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_stats_strings[i].offset); count++; @@ -2741,10 +2816,9 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* RX Priority Stats */ for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) { - for (i = 0; i < 8; i++) { - snprintf(xstats[count].name, sizeof(xstats[count].name), - "rx_priority%u_%s", i, - rte_ixgbe_rxq_strings[stat].name); + for (i = 0; i < IXGBE_NB_RXQ_PRIO_VALUES; i++) { + xstats[count].id = count; + xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_rxq_strings[stat].offset + (sizeof(uint64_t) * i)); @@ -2754,17 +2828,15 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* TX Priority Stats */ for (stat = 0; stat < IXGBE_NB_TXQ_PRIO_STATS; stat++) { - for (i = 0; i < 8; i++) { - snprintf(xstats[count].name, sizeof(xstats[count].name), - "tx_priority%u_%s", i, - rte_ixgbe_txq_strings[stat].name); + for (i = 0; i < IXGBE_NB_TXQ_PRIO_VALUES; i++) { + xstats[count].id = count; + xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_txq_strings[stat].offset + (sizeof(uint64_t) * i)); count++; } } - return count; } @@ -2829,8 +2901,7 @@ ixgbevf_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* 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].id = i; xstats[i].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbevf_stats_strings[i].offset); } -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v5 3/7] drivers/net/e1000: change xstats to use integer ids 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 0/7] Remove string operations from xstats Remy Horton 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 1/7] rte: change xstats to use integer ids Remy Horton 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 2/7] drivers/net/ixgbe: " Remy Horton @ 2016-06-15 15:25 ` Remy Horton 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 4/7] drivers/net/fm10k: " Remy Horton ` (4 subsequent siblings) 7 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-06-15 15:25 UTC (permalink / raw) To: dev, Thomas Monjalon The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the e1000 driver to use the new API that seperates name string and value queries. Signed-off-by: Remy Horton <remy.horton@intel.com> --- drivers/net/e1000/igb_ethdev.c | 52 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c index f0921ee..dffa04f 100644 --- a/drivers/net/e1000/igb_ethdev.c +++ b/drivers/net/e1000/igb_ethdev.c @@ -100,6 +100,9 @@ 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 int eth_igb_xstats_get_names(struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + unsigned limit); 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, @@ -165,6 +168,9 @@ 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 int eth_igbvf_xstats_get_names(struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + unsigned limit); 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); @@ -324,6 +330,7 @@ static const struct eth_dev_ops eth_igb_ops = { .link_update = eth_igb_link_update, .stats_get = eth_igb_stats_get, .xstats_get = eth_igb_xstats_get, + .xstats_get_names = eth_igb_xstats_get_names, .stats_reset = eth_igb_stats_reset, .xstats_reset = eth_igb_xstats_reset, .dev_infos_get = eth_igb_infos_get, @@ -385,6 +392,7 @@ static const struct eth_dev_ops igbvf_eth_dev_ops = { .link_update = eth_igb_link_update, .stats_get = eth_igbvf_stats_get, .xstats_get = eth_igbvf_xstats_get, + .xstats_get_names = eth_igbvf_xstats_get_names, .stats_reset = eth_igbvf_stats_reset, .xstats_reset = eth_igbvf_stats_reset, .vlan_filter_set = igbvf_vlan_filter_set, @@ -1691,6 +1699,26 @@ eth_igb_xstats_reset(struct rte_eth_dev *dev) memset(stats, 0, sizeof(*stats)); } +static int eth_igb_xstats_get_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + __rte_unused unsigned limit) +{ + unsigned i; + + if (xstats_names == NULL) + return IGB_NB_XSTATS; + + /* Note: limit checked in rte_eth_xstats_names() */ + + for (i = 0; i < IGB_NB_XSTATS; i++) { + snprintf(xstats_names[i].name, sizeof(xstats_names[i].name), + "%s", rte_igb_stats_strings[i].name); + xstats_names[i].id = i; + } + + return IGB_NB_XSTATS; +} + static int eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned n) @@ -1713,8 +1741,8 @@ eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* 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].name[0] = '\0'; + xstats[i].id = i; xstats[i].value = *(uint64_t *)(((char *)hw_stats) + rte_igb_stats_strings[i].offset); } @@ -1762,6 +1790,22 @@ igbvf_read_stats_registers(struct e1000_hw *hw, struct e1000_vf_stats *hw_stats) hw_stats->last_gotlbc, hw_stats->gotlbc); } +static int eth_igbvf_xstats_get_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + __rte_unused unsigned limit) +{ + unsigned i; + + if (xstats_names != NULL) + for (i = 0; i < IGBVF_NB_XSTATS; i++) { + snprintf(xstats_names[i].name, + sizeof(xstats_names[i].name), "%s", + rte_igbvf_stats_strings[i].name); + xstats_names[i].id = i; + } + return IGBVF_NB_XSTATS; +} + static int eth_igbvf_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned n) @@ -1780,8 +1824,8 @@ eth_igbvf_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *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].name[0] = '\0'; + xstats[i].id = i; xstats[i].value = *(uint64_t *)(((char *)hw_stats) + rte_igbvf_stats_strings[i].offset); } -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v5 4/7] drivers/net/fm10k: change xstats to use integer ids 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 0/7] Remove string operations from xstats Remy Horton ` (2 preceding siblings ...) 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 3/7] drivers/net/e1000: " Remy Horton @ 2016-06-15 15:25 ` Remy Horton 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 5/7] drivers/net/i40e: " Remy Horton ` (3 subsequent siblings) 7 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-06-15 15:25 UTC (permalink / raw) To: dev, Thomas Monjalon The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the fm10k driver to use the new API that seperates name string and value queries. Signed-off-by: Remy Horton <remy.horton@intel.com> --- drivers/net/fm10k/fm10k_ethdev.c | 55 +++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c index c2d377f..e07c1ec 100644 --- a/drivers/net/fm10k/fm10k_ethdev.c +++ b/drivers/net/fm10k/fm10k_ethdev.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2013-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2013-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -1256,6 +1256,47 @@ fm10k_link_update(struct rte_eth_dev *dev, return 0; } +static int fm10k_xstats_get_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, __rte_unused unsigned limit) +{ + unsigned i, q; + unsigned count = 0; + + if (xstats_names != NULL) { + /* Note: limit checked in rte_eth_xstats_names() */ + + /* Global stats */ + for (i = 0; i < FM10K_NB_HW_XSTATS; i++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "%s", fm10k_hw_stats_strings[count].name); + xstats_names[count].id = count; + 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_names[count].name, + sizeof(xstats_names[count].name), + "rx_q%u_%s", q, + fm10k_hw_stats_rx_q_strings[i].name); + xstats_names[count].id = count; + count++; + } + for (i = 0; i < FM10K_NB_TX_Q_XSTATS; i++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "tx_q%u_%s", q, + fm10k_hw_stats_tx_q_strings[i].name); + xstats_names[count].id = count; + count++; + } + } + } + return FM10K_NB_XSTATS; +} + static int fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned n) @@ -1269,8 +1310,7 @@ fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *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].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + fm10k_hw_stats_strings[count].offset); count++; @@ -1279,18 +1319,14 @@ fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* 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].name[0] = '\0'; 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].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)&hw_stats->q[q]) + fm10k_hw_stats_tx_q_strings[i].offset); @@ -2629,6 +2665,7 @@ static const struct eth_dev_ops fm10k_eth_dev_ops = { .allmulticast_disable = fm10k_dev_allmulticast_disable, .stats_get = fm10k_stats_get, .xstats_get = fm10k_xstats_get, + .xstats_get_names = fm10k_xstats_get_names, .stats_reset = fm10k_stats_reset, .xstats_reset = fm10k_stats_reset, .link_update = fm10k_link_update, -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v5 5/7] drivers/net/i40e: change xstats to use integer ids 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 0/7] Remove string operations from xstats Remy Horton ` (3 preceding siblings ...) 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 4/7] drivers/net/fm10k: " Remy Horton @ 2016-06-15 15:25 ` Remy Horton 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 6/7] drivers/net/virtio: " Remy Horton ` (2 subsequent siblings) 7 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-06-15 15:25 UTC (permalink / raw) To: dev, Thomas Monjalon The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the i40e driver to use the new API that seperates name string and value queries. Signed-off-by: Remy Horton <remy.horton@intel.com> --- drivers/net/i40e/i40e_ethdev.c | 82 ++++++++++++++++++++++++++++++++------- drivers/net/i40e/i40e_ethdev_vf.c | 26 +++++++++++-- 2 files changed, 91 insertions(+), 17 deletions(-) diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 24777d5..d712bbe 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -306,6 +306,9 @@ 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 int i40e_dev_xstats_get_names(struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + unsigned limit); static void i40e_dev_stats_reset(struct rte_eth_dev *dev); static int i40e_dev_queue_stats_mapping_set(struct rte_eth_dev *dev, uint16_t queue_id, @@ -467,6 +470,7 @@ static const struct eth_dev_ops i40e_eth_dev_ops = { .link_update = i40e_dev_link_update, .stats_get = i40e_dev_stats_get, .xstats_get = i40e_dev_xstats_get, + .xstats_get_names = i40e_dev_xstats_get_names, .stats_reset = i40e_dev_stats_reset, .xstats_reset = i40e_dev_stats_reset, .queue_stats_mapping_set = i40e_dev_queue_stats_mapping_set, @@ -2205,6 +2209,60 @@ i40e_xstats_calc_num(void) (I40E_NB_TXQ_PRIO_XSTATS * 8); } +static int i40e_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + __rte_unused unsigned limit) +{ + unsigned count = 0; + unsigned i, prio; + + if (xstats_names == NULL) + return i40e_xstats_calc_num(); + + /* Note: limit checked in rte_eth_xstats_names() */ + + /* Get stats from i40e_eth_stats struct */ + for (i = 0; i < I40E_NB_ETH_XSTATS; i++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "%s", rte_i40e_stats_strings[i].name); + xstats_names[count].id = count; + count++; + } + + /* Get individiual stats from i40e_hw_port struct */ + for (i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "%s", rte_i40e_hw_port_strings[i].name); + xstats_names[count].id = count; + count++; + } + + for (i = 0; i < I40E_NB_RXQ_PRIO_XSTATS; i++) { + for (prio = 0; prio < 8; prio++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "rx_priority%u_%s", prio, + rte_i40e_rxq_prio_strings[i].name); + xstats_names[count].id = count; + count++; + } + } + + for (i = 0; i < I40E_NB_TXQ_PRIO_XSTATS; i++) { + for (prio = 0; prio < 8; prio++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "tx_priority%u_%s", prio, + rte_i40e_txq_prio_strings[i].name); + xstats_names[count].id = count; + count++; + } + } + return count; +} + static int i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned n) @@ -2227,8 +2285,8 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* 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].name[0] = '\0'; + xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)&hw_stats->eth) + rte_i40e_stats_strings[i].offset); count++; @@ -2236,19 +2294,17 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* 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].name[0] = '\0'; + xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + - rte_i40e_hw_port_strings[i].offset); + rte_i40e_hw_port_strings[i].offset); count++; } for (i = 0; i < I40E_NB_RXQ_PRIO_XSTATS; i++) { for (prio = 0; prio < 8; prio++) { - snprintf(xstats[count].name, - sizeof(xstats[count].name), - "rx_priority%u_%s", prio, - rte_i40e_rxq_prio_strings[i].name); + xstats[count].name[0] = '\0'; + xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_i40e_rxq_prio_strings[i].offset + @@ -2259,10 +2315,8 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, for (i = 0; i < I40E_NB_TXQ_PRIO_XSTATS; i++) { for (prio = 0; prio < 8; prio++) { - snprintf(xstats[count].name, - sizeof(xstats[count].name), - "tx_priority%u_%s", prio, - rte_i40e_txq_prio_strings[i].name); + xstats[count].name[0] = '\0'; + xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_i40e_txq_prio_strings[i].offset + diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c index 90682ac..4c5e45e 100644 --- a/drivers/net/i40e/i40e_ethdev_vf.c +++ b/drivers/net/i40e/i40e_ethdev_vf.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -112,6 +112,9 @@ 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 int i40evf_dev_xstats_get_names(struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + unsigned limit); 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); @@ -196,6 +199,7 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = { .link_update = i40evf_dev_link_update, .stats_get = i40evf_dev_stats_get, .xstats_get = i40evf_dev_xstats_get, + .xstats_get_names = i40evf_dev_xstats_get_names, .xstats_reset = i40evf_dev_xstats_reset, .dev_close = i40evf_dev_close, .dev_infos_get = i40evf_dev_info_get, @@ -984,6 +988,22 @@ i40evf_dev_xstats_reset(struct rte_eth_dev *dev) vf->vsi.eth_stats_offset = vf->vsi.eth_stats; } +static int i40evf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + __rte_unused unsigned limit) +{ + unsigned i; + + if (xstats_names != NULL) + for (i = 0; i < I40EVF_NB_XSTATS; i++) { + snprintf(xstats_names[i].name, + sizeof(xstats_names[i].name), + "%s", rte_i40evf_stats_strings[i].name); + xstats_names[i].id = i; + } + return I40EVF_NB_XSTATS; +} + static int i40evf_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned n) { @@ -1003,8 +1023,8 @@ static int i40evf_dev_xstats_get(struct rte_eth_dev *dev, /* 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].name[0] = '\0'; + xstats[i].id = i; xstats[i].value = *(uint64_t *)(((char *)pstats) + rte_i40evf_stats_strings[i].offset); } -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v5 6/7] drivers/net/virtio: change xstats to use integer ids 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 0/7] Remove string operations from xstats Remy Horton ` (4 preceding siblings ...) 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 5/7] drivers/net/i40e: " Remy Horton @ 2016-06-15 15:25 ` Remy Horton 2016-06-20 10:43 ` Yuanhan Liu 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 7/7] rte: change xstats usage to new API Remy Horton 2016-06-16 16:02 ` [dpdk-dev] [PATCH v5 0/7] Remove string operations from xstats Thomas Monjalon 7 siblings, 1 reply; 71+ messages in thread From: Remy Horton @ 2016-06-15 15:25 UTC (permalink / raw) To: dev, Thomas Monjalon The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the virtio driver to use the new API that seperates name string and value queries. Signed-off-by: Remy Horton <remy.horton@intel.com> --- drivers/net/virtio/virtio_ethdev.c | 62 +++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c index c3fb628..83df025 100644 --- a/drivers/net/virtio/virtio_ethdev.c +++ b/drivers/net/virtio/virtio_ethdev.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -80,6 +80,9 @@ 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 int virtio_dev_xstats_get_names(struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + unsigned limit); 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, @@ -615,6 +618,7 @@ 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, + .xstats_get_names = virtio_dev_xstats_get_names, .stats_reset = virtio_dev_stats_reset, .xstats_reset = virtio_dev_stats_reset, .link_update = virtio_dev_link_update, @@ -708,6 +712,52 @@ virtio_update_stats(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_names(struct rte_eth_dev *dev, + struct rte_eth_xstat_name *xstats_names, + __rte_unused unsigned limit) +{ + unsigned i; + unsigned count = 0; + unsigned t; + + unsigned nstats = dev->data->nb_tx_queues * VIRTIO_NB_Q_XSTATS + + dev->data->nb_rx_queues * VIRTIO_NB_Q_XSTATS; + + if (xstats_names == NULL) { + /* Note: limit checked in rte_eth_xstats_names() */ + + for (i = 0; i < dev->data->nb_rx_queues; i++) { + struct virtqueue *rxvq = dev->data->rx_queues[i]; + if (rxvq == NULL) + continue; + for (t = 0; t < VIRTIO_NB_Q_XSTATS; t++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "rx_q%u_%s", i, + rte_virtio_q_stat_strings[t].name); + xstats_names[count].id = count; + count++; + } + } + + for (i = 0; i < dev->data->nb_tx_queues; i++) { + struct virtqueue *txvq = dev->data->tx_queues[i]; + if (txvq == NULL) + continue; + for (t = 0; t < VIRTIO_NB_Q_XSTATS; t++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "tx_q%u_%s", i, + rte_virtio_q_stat_strings[t].name); + xstats_names[count].id = count; + count++; + } + } + return count; + } + return nstats; +} + static int virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned n) @@ -730,9 +780,8 @@ virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, 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].name[0] = '\0'; + xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)rxvq) + rte_virtio_q_stat_strings[t].offset); count++; @@ -748,9 +797,8 @@ virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, 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].name[0] = '\0'; + xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)txvq) + rte_virtio_q_stat_strings[t].offset); count++; -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [PATCH v5 6/7] drivers/net/virtio: change xstats to use integer ids 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 6/7] drivers/net/virtio: " Remy Horton @ 2016-06-20 10:43 ` Yuanhan Liu 0 siblings, 0 replies; 71+ messages in thread From: Yuanhan Liu @ 2016-06-20 10:43 UTC (permalink / raw) To: Remy Horton; +Cc: dev, Thomas Monjalon On Wed, Jun 15, 2016 at 04:25:32PM +0100, Remy Horton wrote: > > +static int virtio_dev_xstats_get_names(struct rte_eth_dev *dev, > + struct rte_eth_xstat_name *xstats_names, > + __rte_unused unsigned limit) > +{ > + unsigned i; > + unsigned count = 0; > + unsigned t; > + > + unsigned nstats = dev->data->nb_tx_queues * VIRTIO_NB_Q_XSTATS + > + dev->data->nb_rx_queues * VIRTIO_NB_Q_XSTATS; > + > + if (xstats_names == NULL) { > + /* Note: limit checked in rte_eth_xstats_names() */ > + That crashes testpmd while I run "show port xstats 0" with virtio PMD. Will send a fix soon. BTW, would you CC to the maintainer for corresponding subsystems next time, say CC me for virtio/vhost changes? --yliu > + for (i = 0; i < dev->data->nb_rx_queues; i++) { > + struct virtqueue *rxvq = dev->data->rx_queues[i]; > + if (rxvq == NULL) > + continue; > + for (t = 0; t < VIRTIO_NB_Q_XSTATS; t++) { > + snprintf(xstats_names[count].name, > + sizeof(xstats_names[count].name), > + "rx_q%u_%s", i, > + rte_virtio_q_stat_strings[t].name); > + xstats_names[count].id = count; > + count++; > + } > + } > + > + for (i = 0; i < dev->data->nb_tx_queues; i++) { > + struct virtqueue *txvq = dev->data->tx_queues[i]; > + if (txvq == NULL) > + continue; > + for (t = 0; t < VIRTIO_NB_Q_XSTATS; t++) { > + snprintf(xstats_names[count].name, > + sizeof(xstats_names[count].name), > + "tx_q%u_%s", i, > + rte_virtio_q_stat_strings[t].name); > + xstats_names[count].id = count; > + count++; > + } > + } > + return count; > + } > + return nstats; > +} ^ permalink raw reply [flat|nested] 71+ messages in thread
* [dpdk-dev] [PATCH v5 7/7] rte: change xstats usage to new API 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 0/7] Remove string operations from xstats Remy Horton ` (5 preceding siblings ...) 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 6/7] drivers/net/virtio: " Remy Horton @ 2016-06-15 15:25 ` Remy Horton 2016-06-16 16:02 ` [dpdk-dev] [PATCH v5 0/7] Remove string operations from xstats Thomas Monjalon 7 siblings, 0 replies; 71+ messages in thread From: Remy Horton @ 2016-06-15 15:25 UTC (permalink / raw) To: dev, Thomas Monjalon The current extended ethernet statistics fetching involve doing several string operations, which causes performance issues if there are lots of statistics and/or network interfaces. This patch changes the test-pmd and proc_info applications to use the new xstats API, and removes deprecated code associated with the old API. Signed-off-by: Remy Horton <remy.horton@intel.com> --- app/proc_info/main.c | 29 +++++++++++++++++--- app/test-pmd/config.c | 54 +++++++++++++++++++++++++++++--------- drivers/net/e1000/igb_ethdev.c | 10 +++---- drivers/net/fm10k/fm10k_ethdev.c | 5 +--- drivers/net/i40e/i40e_ethdev.c | 8 ++---- drivers/net/i40e/i40e_ethdev_vf.c | 5 ++-- drivers/net/ixgbe/ixgbe_ethdev.c | 11 +++----- drivers/net/virtio/virtio_ethdev.c | 6 ++--- lib/librte_ether/rte_ethdev.c | 5 +--- lib/librte_ether/rte_ethdev.h | 7 +++-- 10 files changed, 85 insertions(+), 55 deletions(-) diff --git a/app/proc_info/main.c b/app/proc_info/main.c index 5f83092..f2063fa 100644 --- a/app/proc_info/main.c +++ b/app/proc_info/main.c @@ -1,7 +1,7 @@ /* * BSD LICENSE * - * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -243,11 +243,13 @@ nic_stats_clear(uint8_t port_id) static void nic_xstats_display(uint8_t port_id) { - struct rte_eth_xstats *xstats; + struct rte_eth_xstat_name *xstats_names; + struct rte_eth_xstat *xstats; int len, ret, i; + int idx_name; static const char *nic_stats_border = "########################"; - len = rte_eth_xstats_get(port_id, NULL, 0); + len = rte_eth_xstats_get_names(port_id, NULL, 0); if (len < 0) { printf("Cannot get xstats count\n"); return; @@ -258,6 +260,18 @@ nic_xstats_display(uint8_t port_id) return; } + xstats_names = malloc(sizeof(struct rte_eth_xstat_name) * len); + if (xstats_names == NULL) { + printf("Cannot allocate memory for xstat names\n"); + free(xstats); + return; + } + if (len != rte_eth_xstats_get_names( + port_id, xstats_names, len)) { + printf("Cannot get xstat names\n"); + return; + } + printf("###### NIC extended statistics for port %-2d #########\n", port_id); printf("%s############################\n", @@ -270,11 +284,18 @@ nic_xstats_display(uint8_t port_id) } for (i = 0; i < len; i++) - printf("%s: %"PRIu64"\n", xstats[i].name, xstats[i].value); + for (idx_name = 0; idx_name < len; idx_name++) + if (xstats_names[idx_name].id == xstats[i].id) { + printf("%s: %"PRIu64"\n", + xstats_names[idx_name].name, + xstats[i].value); + break; + } printf("%s############################\n", nic_stats_border); free(xstats); + free(xstats_names); } static void diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 1c552e4..8ddec07 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -232,29 +232,57 @@ nic_stats_clear(portid_t port_id) void nic_xstats_display(portid_t port_id) { - struct rte_eth_xstats *xstats; - int len, ret, i; + struct rte_eth_xstat *xstats; + int cnt_xstats, idx_xstat, idx_name; + struct rte_eth_xstat_name *xstats_names; printf("###### NIC extended statistics for port %-2d\n", port_id); + if (!rte_eth_dev_is_valid_port(port_id)) { + printf("Error: Invalid port number %i\n", port_id); + return; + } + + /* 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; + } - len = rte_eth_xstats_get(port_id, NULL, 0); - if (len < 0) { - printf("Cannot get xstats count\n"); + /* 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; } - xstats = malloc(sizeof(xstats[0]) * len); + if (cnt_xstats != rte_eth_xstats_get_names( + port_id, xstats_names, cnt_xstats)) { + printf("Error: Cannot get xstats lookup\n"); + 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; } - ret = rte_eth_xstats_get(port_id, xstats, len); - if (ret < 0 || ret > len) { - printf("Cannot get xstats\n"); - free(xstats); + if (cnt_xstats != rte_eth_xstats_get(port_id, xstats, cnt_xstats)) { + printf("Error: Unable to get xstats\n"); return; } - for (i = 0; i < len; i++) - printf("%s: %"PRIu64"\n", xstats[i].name, xstats[i].value); + + /* Display xstats */ + for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++) + for (idx_name = 0; idx_name < cnt_xstats; idx_name++) + if (xstats_names[idx_name].id == xstats[idx_xstat].id) { + printf("%s: %"PRIu64"\n", + xstats_names[idx_name].name, + xstats[idx_xstat].value); + break; + } + free(xstats_names); free(xstats); } diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c index dffa04f..b822992 100644 --- a/drivers/net/e1000/igb_ethdev.c +++ b/drivers/net/e1000/igb_ethdev.c @@ -99,7 +99,7 @@ static int eth_igb_link_update(struct rte_eth_dev *dev, 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); + struct rte_eth_xstat *xstats, unsigned n); static int eth_igb_xstats_get_names(struct rte_eth_dev *dev, struct rte_eth_xstat_name *xstats_names, unsigned limit); @@ -167,7 +167,7 @@ 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 int eth_igbvf_xstats_get(struct rte_eth_dev *dev, - struct rte_eth_xstats *xstats, unsigned n); + struct rte_eth_xstat *xstats, unsigned n); static int eth_igbvf_xstats_get_names(struct rte_eth_dev *dev, struct rte_eth_xstat_name *xstats_names, unsigned limit); @@ -1720,7 +1720,7 @@ 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_xstats *xstats, +eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, unsigned n) { struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); @@ -1741,7 +1741,6 @@ eth_igb_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* Extended stats */ for (i = 0; i < IGB_NB_XSTATS; i++) { - xstats[i].name[0] = '\0'; xstats[i].id = i; xstats[i].value = *(uint64_t *)(((char *)hw_stats) + rte_igb_stats_strings[i].offset); @@ -1807,7 +1806,7 @@ static int eth_igbvf_xstats_get_names(__rte_unused struct rte_eth_dev *dev, } static int -eth_igbvf_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, +eth_igbvf_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, unsigned n) { struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); @@ -1824,7 +1823,6 @@ eth_igbvf_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, return 0; for (i = 0; i < IGBVF_NB_XSTATS; i++) { - xstats[i].name[0] = '\0'; xstats[i].id = i; xstats[i].value = *(uint64_t *)(((char *)hw_stats) + rte_igbvf_stats_strings[i].offset); diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c index e07c1ec..ce053b0 100644 --- a/drivers/net/fm10k/fm10k_ethdev.c +++ b/drivers/net/fm10k/fm10k_ethdev.c @@ -1298,7 +1298,7 @@ static int fm10k_xstats_get_names(__rte_unused struct rte_eth_dev *dev, } static int -fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, +fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, unsigned n) { struct fm10k_hw_stats *hw_stats = @@ -1310,7 +1310,6 @@ fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* Global stats */ for (i = 0; i < FM10K_NB_HW_XSTATS; i++) { - xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + fm10k_hw_stats_strings[count].offset); count++; @@ -1319,14 +1318,12 @@ fm10k_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* PF queue stats */ for (q = 0; q < FM10K_MAX_QUEUES_PF; q++) { for (i = 0; i < FM10K_NB_RX_Q_XSTATS; i++) { - xstats[count].name[0] = '\0'; 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++) { - xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)&hw_stats->q[q]) + fm10k_hw_stats_tx_q_strings[i].offset); diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index d712bbe..f94ad87 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -305,7 +305,7 @@ 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); + struct rte_eth_xstat *xstats, unsigned n); static int i40e_dev_xstats_get_names(struct rte_eth_dev *dev, struct rte_eth_xstat_name *xstats_names, unsigned limit); @@ -2264,7 +2264,7 @@ static int i40e_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, } static int -i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, +i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, unsigned n) { struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); @@ -2285,7 +2285,6 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* Get stats from i40e_eth_stats struct */ for (i = 0; i < I40E_NB_ETH_XSTATS; i++) { - xstats[count].name[0] = '\0'; xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)&hw_stats->eth) + rte_i40e_stats_strings[i].offset); @@ -2294,7 +2293,6 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, /* Get individiual stats from i40e_hw_port struct */ for (i = 0; i < I40E_NB_HW_PORT_XSTATS; i++) { - xstats[count].name[0] = '\0'; xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_i40e_hw_port_strings[i].offset); @@ -2303,7 +2301,6 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, for (i = 0; i < I40E_NB_RXQ_PRIO_XSTATS; i++) { for (prio = 0; prio < 8; prio++) { - xstats[count].name[0] = '\0'; xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + @@ -2315,7 +2312,6 @@ i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, for (i = 0; i < I40E_NB_TXQ_PRIO_XSTATS; i++) { for (prio = 0; prio < 8; prio++) { - xstats[count].name[0] = '\0'; xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c index 4c5e45e..37af399 100644 --- a/drivers/net/i40e/i40e_ethdev_vf.c +++ b/drivers/net/i40e/i40e_ethdev_vf.c @@ -111,7 +111,7 @@ static int i40evf_dev_link_update(struct rte_eth_dev *dev, 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); + struct rte_eth_xstat *xstats, unsigned n); static int i40evf_dev_xstats_get_names(struct rte_eth_dev *dev, struct rte_eth_xstat_name *xstats_names, unsigned limit); @@ -1005,7 +1005,7 @@ static int i40evf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, } static int i40evf_dev_xstats_get(struct rte_eth_dev *dev, - struct rte_eth_xstats *xstats, unsigned n) + struct rte_eth_xstat *xstats, unsigned n) { int ret; unsigned i; @@ -1023,7 +1023,6 @@ static int i40evf_dev_xstats_get(struct rte_eth_dev *dev, /* loop over xstats array and values from pstats */ for (i = 0; i < I40EVF_NB_XSTATS; i++) { - xstats[i].name[0] = '\0'; xstats[i].id = i; xstats[i].value = *(uint64_t *)(((char *)pstats) + rte_i40evf_stats_strings[i].offset); diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c index 9e73492..125c257 100644 --- a/drivers/net/ixgbe/ixgbe_ethdev.c +++ b/drivers/net/ixgbe/ixgbe_ethdev.c @@ -174,9 +174,9 @@ static int ixgbe_dev_link_update(struct rte_eth_dev *dev, 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); + struct rte_eth_xstat *xstats, unsigned n); static int ixgbevf_dev_xstats_get(struct rte_eth_dev *dev, - struct rte_eth_xstats *xstats, unsigned n); + 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_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, @@ -2775,7 +2775,7 @@ static int ixgbevf_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, } static int -ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, +ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, unsigned n) { struct ixgbe_hw *hw = @@ -2808,7 +2808,6 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, count = 0; for (i = 0; i < IXGBE_NB_HW_STATS; i++) { xstats[count].id = count; - xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_stats_strings[i].offset); count++; @@ -2818,7 +2817,6 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, for (stat = 0; stat < IXGBE_NB_RXQ_PRIO_STATS; stat++) { for (i = 0; i < IXGBE_NB_RXQ_PRIO_VALUES; i++) { xstats[count].id = count; - xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_rxq_strings[stat].offset + (sizeof(uint64_t) * i)); @@ -2830,7 +2828,6 @@ ixgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, for (stat = 0; stat < IXGBE_NB_TXQ_PRIO_STATS; stat++) { for (i = 0; i < IXGBE_NB_TXQ_PRIO_VALUES; i++) { xstats[count].id = count; - xstats[count].name[0] = '\0'; xstats[count].value = *(uint64_t *)(((char *)hw_stats) + rte_ixgbe_txq_strings[stat].offset + (sizeof(uint64_t) * i)); @@ -2884,7 +2881,7 @@ ixgbevf_update_stats(struct rte_eth_dev *dev) } static int -ixgbevf_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, +ixgbevf_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, unsigned n) { struct ixgbevf_hw_stats *hw_stats = (struct ixgbevf_hw_stats *) diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c index 83df025..a833740 100644 --- a/drivers/net/virtio/virtio_ethdev.c +++ b/drivers/net/virtio/virtio_ethdev.c @@ -79,7 +79,7 @@ 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 int virtio_dev_xstats_get(struct rte_eth_dev *dev, - struct rte_eth_xstats *xstats, unsigned n); + struct rte_eth_xstat *xstats, unsigned n); static int virtio_dev_xstats_get_names(struct rte_eth_dev *dev, struct rte_eth_xstat_name *xstats_names, unsigned limit); @@ -759,7 +759,7 @@ static int virtio_dev_xstats_get_names(struct rte_eth_dev *dev, } static int -virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, +virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, unsigned n) { unsigned i; @@ -780,7 +780,6 @@ virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned t; for (t = 0; t < VIRTIO_NB_Q_XSTATS; t++) { - xstats[count].name[0] = '\0'; xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)rxvq) + rte_virtio_q_stat_strings[t].offset); @@ -797,7 +796,6 @@ virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, unsigned t; for (t = 0; t < VIRTIO_NB_Q_XSTATS; t++) { - xstats[count].name[0] = '\0'; xstats[count].id = count; xstats[count].value = *(uint64_t *)(((char *)txvq) + rte_virtio_q_stat_strings[t].offset); diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index 98e5efb..63320cc 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -1583,7 +1583,7 @@ rte_eth_xstats_get_names(uint8_t port_id, /* retrieve ethdev extended statistics */ int -rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, +rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstat *xstats, unsigned n) { struct rte_eth_stats eth_stats; @@ -1625,7 +1625,6 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, stats_ptr = RTE_PTR_ADD(ð_stats, rte_stats_strings[i].offset); val = *stats_ptr; - xstats[count].name[0] = '\0'; xstats[count].id = count + xcount; xstats[count++].value = val; } @@ -1637,7 +1636,6 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, rte_rxq_stats_strings[i].offset + q * sizeof(uint64_t)); val = *stats_ptr; - xstats[count].name[0] = '\0'; xstats[count].id = count + xcount; xstats[count++].value = val; } @@ -1650,7 +1648,6 @@ rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, rte_txq_stats_strings[i].offset + q * sizeof(uint64_t)); val = *stats_ptr; - xstats[count].name[0] = '\0'; xstats[count].id = count + xcount; xstats[count++].value = val; } diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index 5de86b8..440641e 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -914,8 +914,7 @@ struct rte_eth_txq_info { * statistics that are not provided in the generic rte_eth_stats * structure. */ -struct rte_eth_xstats { - char name[RTE_ETH_XSTATS_NAME_SIZE]; +struct rte_eth_xstat { uint64_t id; uint64_t value; }; @@ -1060,7 +1059,7 @@ typedef void (*eth_stats_reset_t)(struct rte_eth_dev *dev); /**< @internal Reset global I/O statistics of an Ethernet device to 0. */ typedef int (*eth_xstats_get_t)(struct rte_eth_dev *dev, - struct rte_eth_xstats *stats, unsigned n); + struct rte_eth_xstat *stats, unsigned n); /**< @internal Get extended stats of an Ethernet device. */ typedef void (*eth_xstats_reset_t)(struct rte_eth_dev *dev); @@ -2314,7 +2313,7 @@ int rte_eth_xstats_get_names(uint8_t port_id, * shall not be used by the caller. * - negative value on error (invalid port id) */ -int rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstats *xstats, +int rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstat *xstats, unsigned n); /** -- 2.5.5 ^ permalink raw reply [flat|nested] 71+ messages in thread
* Re: [dpdk-dev] [PATCH v5 0/7] Remove string operations from xstats 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 0/7] Remove string operations from xstats Remy Horton ` (6 preceding siblings ...) 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 7/7] rte: change xstats usage to new API Remy Horton @ 2016-06-16 16:02 ` Thomas Monjalon 7 siblings, 0 replies; 71+ messages in thread From: Thomas Monjalon @ 2016-06-16 16:02 UTC (permalink / raw) To: Remy Horton; +Cc: dev, John McNamara > Remy Horton (7): > rte: change xstats to use integer ids > drivers/net/ixgbe: change xstats to use integer ids > drivers/net/e1000: change xstats to use integer ids > drivers/net/fm10k: change xstats to use integer ids > drivers/net/i40e: change xstats to use integer ids > drivers/net/virtio: change xstats to use integer ids > rte: change xstats usage to new API Applied, thanks ^ permalink raw reply [flat|nested] 71+ messages in thread
end of thread, other threads:[~2016-06-20 10:43 UTC | newest] Thread overview: 71+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-04-15 14:44 [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats Remy Horton 2016-04-15 14:44 ` [dpdk-dev] [RFC PATCH v1 1/3] rte: change xstats to use integer keys Remy Horton 2016-04-29 13:17 ` David Harton (dharton) 2016-04-15 14:44 ` [dpdk-dev] [RFC PATCH v1 2/3] drivers/net/ixgbe: change xstats to use integers Remy Horton 2016-04-29 13:43 ` David Harton (dharton) 2016-05-03 12:22 ` Remy Horton 2016-05-03 13:40 ` David Harton (dharton) 2016-04-15 14:44 ` [dpdk-dev] [RFC PATCH v1 3/3] examples/ethtool: add xstats display command Remy Horton 2016-04-20 16:03 ` [dpdk-dev] [RFC PATCH v1 0/3] Remove string operations from xstats David Harton (dharton) 2016-04-20 16:49 ` Mcnamara, John 2016-04-22 15:04 ` David Harton (dharton) 2016-04-28 14:56 ` Tahhan, Maryam 2016-04-28 15:58 ` David Harton (dharton) 2016-04-29 10:21 ` Remy Horton 2016-04-29 12:15 ` David Harton (dharton) 2016-04-29 12:52 ` David Harton (dharton) 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 " Remy Horton 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 1/3] rte: change xstats to use integer keys Remy Horton 2016-05-09 13:59 ` David Harton (dharton) 2016-05-10 8:58 ` Remy Horton 2016-05-12 16:17 ` Thomas Monjalon 2016-05-16 10:47 ` Tahhan, Maryam 2016-05-18 8:31 ` Tahhan, Maryam 2016-05-18 8:45 ` Remy Horton 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 2/3] drivers/net/ixgbe: change xstats to use integer id Remy Horton 2016-05-09 14:06 ` David Harton (dharton) 2016-05-18 8:41 ` Tahhan, Maryam 2016-05-06 11:11 ` [dpdk-dev] [RFC PATCH v2 3/3] examples/ethtool: add xstats display command Remy Horton 2016-05-09 14:08 ` David Harton (dharton) 2016-05-18 8:42 ` Tahhan, Maryam 2016-05-16 10:42 ` [dpdk-dev] [RFC PATCH v2 0/3] Remove string operations from xstats Tahhan, Maryam 2016-05-18 10:12 ` Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 00/10] " Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 01/10] rte: change xstats to use integer ids Remy Horton 2016-06-08 9:37 ` Thomas Monjalon 2016-06-08 11:16 ` Remy Horton 2016-06-08 12:22 ` Thomas Monjalon 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 02/10] drivers/net/ixgbe: " Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 03/10] drivers/net/e1000: " Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 04/10] drivers/net/fm10k: " Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 05/10] drivers/net/i40e: " Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 06/10] drivers/net/virtio: " Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 07/10] app/test-pmd: " Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 08/10] app/proc_info: " Remy Horton 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 09/10] remove name field from struct rte_eth_xstats Remy Horton 2016-06-08 12:23 ` Thomas Monjalon 2016-05-30 10:48 ` [dpdk-dev] [PATCH v3 10/10] doc: update xstats documentation Remy Horton 2016-06-09 8:48 ` Mcnamara, John 2016-06-06 12:45 ` [dpdk-dev] [PATCH v3 00/10] Remove string operations from xstats David Harton (dharton) 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 0/8] " Remy Horton 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 1/8] rte: change xstats to use integer ids Remy Horton 2016-06-15 9:19 ` Thomas Monjalon 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 2/8] drivers/net/ixgbe: " Remy Horton 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 3/8] drivers/net/e1000: " Remy Horton 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 4/8] drivers/net/fm10k: " Remy Horton 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 5/8] drivers/net/i40e: " Remy Horton 2016-06-13 15:51 ` [dpdk-dev] [PATCH v4 6/8] drivers/net/virtio: " Remy Horton 2016-06-13 15:52 ` [dpdk-dev] [PATCH v4 7/8] rte: change xstats usage to new API Remy Horton 2016-06-15 9:13 ` Thomas Monjalon 2016-06-13 15:52 ` [dpdk-dev] [PATCH v4 8/8] doc: update xstats documentation Remy Horton 2016-06-14 14:06 ` Mcnamara, John 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 0/7] Remove string operations from xstats Remy Horton 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 1/7] rte: change xstats to use integer ids Remy Horton 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 2/7] drivers/net/ixgbe: " Remy Horton 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 3/7] drivers/net/e1000: " Remy Horton 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 4/7] drivers/net/fm10k: " Remy Horton 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 5/7] drivers/net/i40e: " Remy Horton 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 6/7] drivers/net/virtio: " Remy Horton 2016-06-20 10:43 ` Yuanhan Liu 2016-06-15 15:25 ` [dpdk-dev] [PATCH v5 7/7] rte: change xstats usage to new API Remy Horton 2016-06-16 16:02 ` [dpdk-dev] [PATCH v5 0/7] Remove string operations from xstats Thomas Monjalon
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).