From patchwork Tue Sep 29 14:32:48 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Van Haaren, Harry" X-Patchwork-Id: 7267 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id C10D88DAC; Tue, 29 Sep 2015 16:33:25 +0200 (CEST) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id 8425E5960 for ; Tue, 29 Sep 2015 16:33:24 +0200 (CEST) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP; 29 Sep 2015 07:33:25 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,608,1437462000"; d="scan'208";a="570542963" Received: from sie-lab-212-222.ir.intel.com (HELO silpixa00366884.ir.intel.com) ([10.237.212.222]) by FMSMGA003.fm.intel.com with ESMTP; 29 Sep 2015 07:33:23 -0700 From: Harry van Haaren To: dev@dpdk.org Date: Tue, 29 Sep 2015 15:32:48 +0100 Message-Id: <1443537175-13809-5-git-send-email-harry.van.haaren@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1443537175-13809-1-git-send-email-harry.van.haaren@intel.com> References: <1443537175-13809-1-git-send-email-harry.van.haaren@intel.com> Subject: [dpdk-dev] [PATCH 04/11] virtio: add xstats() implementation X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add xstats() functions and statistic strings to virtio PMD. Signed-off-by: Harry van Haaren --- drivers/net/virtio/virtio_ethdev.c | 86 +++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c index 465d3cd..165ad97 100644 --- a/drivers/net/virtio/virtio_ethdev.c +++ b/drivers/net/virtio/virtio_ethdev.c @@ -80,7 +80,10 @@ static int virtio_dev_link_update(struct rte_eth_dev *dev, static void virtio_set_hwaddr(struct virtio_hw *hw); static void virtio_get_hwaddr(struct virtio_hw *hw); -static void virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats); +static void virtio_dev_stats_get(struct rte_eth_dev *dev, + struct rte_eth_stats *stats); +static int virtio_dev_xstats_get(struct rte_eth_dev *dev, + struct rte_eth_xstats *xstats, unsigned n); static void virtio_dev_stats_reset(struct rte_eth_dev *dev); static void virtio_dev_free_mbufs(struct rte_eth_dev *dev); static int virtio_vlan_filter_set(struct rte_eth_dev *dev, @@ -109,6 +112,21 @@ static const struct rte_pci_id pci_id_virtio_map[] = { { .vendor_id = 0, /* sentinel */ }, }; +struct rte_virtio_xstats_name_off { + char name[RTE_ETH_XSTATS_NAME_SIZE]; + unsigned offset; +}; + +/* [rt]x_qX_ is prepended to the name string here */ +static const struct rte_virtio_xstats_name_off rte_virtio_q_stat_strings[] = { + {"packets", offsetof(struct virtqueue, packets)}, + {"bytes", offsetof(struct virtqueue, bytes)}, + {"errors", offsetof(struct virtqueue, errors)}, +}; + +#define VIRTIO_NB_Q_XSTATS (sizeof(rte_virtio_q_stat_strings) / \ + sizeof(rte_virtio_q_stat_strings[0])) + static int virtio_send_command(struct virtqueue *vq, struct virtio_pmd_ctrl *ctrl, int *dlen, int pkt_num) @@ -568,7 +586,9 @@ static const struct eth_dev_ops virtio_eth_dev_ops = { .dev_infos_get = virtio_dev_info_get, .stats_get = virtio_dev_stats_get, + .xstats_get = virtio_dev_xstats_get, .stats_reset = virtio_dev_stats_reset, + .xstats_reset = virtio_dev_stats_reset, .link_update = virtio_dev_link_update, .rx_queue_setup = virtio_dev_rx_queue_setup, .rx_queue_release = virtio_dev_rx_queue_release, @@ -623,7 +643,7 @@ virtio_dev_atomic_write_link_status(struct rte_eth_dev *dev, } static void -virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) +virtio_update_stats(struct rte_eth_dev *dev, struct rte_eth_stats *stats) { unsigned i; @@ -660,6 +680,68 @@ virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed; } +static int +virtio_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstats *xstats, + unsigned n) +{ + unsigned i; + unsigned count = 0; + + // TODO: what about global stats? mbuf_alloc_failed? + unsigned nstats = dev->data->nb_tx_queues * VIRTIO_NB_Q_XSTATS + + dev->data->nb_rx_queues * VIRTIO_NB_Q_XSTATS; + + if(n < nstats) + return nstats; + + + for (i = 0; i < dev->data->nb_rx_queues; i++) { + struct virtqueue *rxvq = dev->data->rx_queues[i]; + + if(rxvq == NULL) + continue; + + unsigned t; + + for(t = 0; t < VIRTIO_NB_Q_XSTATS; t++) { + snprintf(xstats[count].name, sizeof(xstats[count].name), + "rx_q%u_%s", i, + rte_virtio_q_stat_strings[t].name); + xstats[count].value = *(uint64_t *)(((char *)rxvq) + + rte_virtio_q_stat_strings[t].offset); + count++; + } + } + + for (i = 0; i < dev->data->nb_tx_queues; i++) { + struct virtqueue *txvq = dev->data->tx_queues[i]; + + // TODO: Concider returning 0 value instead of skipping? + // TODO: Is it possible to have NULL queues? ie check necessary? + if(txvq == NULL) + continue; + + unsigned t; + + for(t = 0; t < VIRTIO_NB_Q_XSTATS; t++) { + snprintf(xstats[count].name, sizeof(xstats[count].name), + "tx_q%u_%s", i, + rte_virtio_q_stat_strings[t].name); + xstats[count].value = *(uint64_t *)(((char *)txvq) + + rte_virtio_q_stat_strings[t].offset); + count++; + } + } + + return count; +} + +static void +virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) +{ + virtio_update_stats(dev, stats); +} + static void virtio_dev_stats_reset(struct rte_eth_dev *dev) {