From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <stephen@networkplumber.org>
Received: from mail-pd0-f180.google.com (mail-pd0-f180.google.com
 [209.85.192.180]) by dpdk.org (Postfix) with ESMTP id C7CF56AB7
 for <dev@dpdk.org>; Sat, 14 Jun 2014 03:08:15 +0200 (CEST)
Received: by mail-pd0-f180.google.com with SMTP id ft15so2621277pdb.11
 for <dev@dpdk.org>; Fri, 13 Jun 2014 18:08:30 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20130820;
 h=x-gm-message-state:message-id:user-agent:date:from:to:cc:subject
 :references:mime-version:content-type:content-disposition;
 bh=LyUqq5eSNk4qmZoYg00d7TOJmRf9JHsrT9q0iAHxLQI=;
 b=bYjuo4e+2T4L+1+ERlorF61Q00XMvh0p/zsptSOZHgWk+A5/YVeVSnLylagy7X04og
 gap8W1FoX5D/o0pVy01n862J1icaFLAE7Xg5Ge+x9BA0x+qgDnVbh5wzmyp59pt6vQXc
 WOCC/0f3WCzL/v+uxw/9MUJSByf7c1DKUKxu0GXGVYy1Ob8FikwJ0z8R8uxQE0tCKKqG
 g+ERy8GV638aD0Bh6ouM/C8AoeEJDaN4bIYGRoRLFLAMBll7PmsScQLHJhycsNBNgooO
 vxh8KBTglm+S7ODgZ4I+uChUoLNV2VWAOLjxWh9F63u4KUWj+vGQHATkdqJYmM3cCy7X
 ZvTQ==
X-Gm-Message-State: ALoCoQknYhsp0Dd7BmXwEE91YmZfHoswmBivQMdHnuFX3vb6uzhwJxS33NFxQpdkY4tNaOfn+Uyo
X-Received: by 10.66.243.225 with SMTP id xb1mr7331247pac.49.1402708110872;
 Fri, 13 Jun 2014 18:08:30 -0700 (PDT)
Received: from localhost (static-50-53-83-51.bvtn.or.frontiernet.net.
 [50.53.83.51])
 by mx.google.com with ESMTPSA id sv10sm28890331pab.32.2014.06.13.18.08.29
 for <multiple recipients>
 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
 Fri, 13 Jun 2014 18:08:29 -0700 (PDT)
Message-Id: <20140614010820.971150445@networkplumber.org>
User-Agent: quilt/0.63-1
Date: Fri, 13 Jun 2014 18:06:18 -0700
From: Stephen Hemminger <stephen@networkplumber.org>
To: dev@dpdk.org
References: <20140614010617.902738763@networkplumber.org>
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-15
Content-Disposition: inline; filename=virtio-per-queue-stats.patch
Cc: Stephen Hemminger <shemming@brocade.com>
Subject: [dpdk-dev] [PATCH 1/8] virtio: maintain stats per queue
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: patches and discussions about DPDK <dev.dpdk.org>
List-Unsubscribe: <http://dpdk.org/ml/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://dpdk.org/ml/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <http://dpdk.org/ml/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
X-List-Received-Date: Sat, 14 Jun 2014 01:08:16 -0000

Avoid cache collision and thrashing of the software statistics
by keeping them per-queue in the driver.

Signed-off-by: Stephen Hemminger <shemming@brocade.com>

--- a/lib/librte_pmd_virtio/virtio_ethdev.c	2014-06-13 17:41:11.634778400 -0700
+++ b/lib/librte_pmd_virtio/virtio_ethdev.c	2014-06-13 17:48:08.235480894 -0700
@@ -474,19 +474,67 @@ virtio_dev_atomic_write_link_status(stru
 static void
 virtio_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 {
-	struct virtio_hw *hw =
-		VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	if (stats)
-		memcpy(stats, &hw->eth_stats, sizeof(*stats));
+	unsigned i;
+
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
+		const struct virtqueue *txvq = dev->data->tx_queues[i];
+		if (txvq == NULL)
+			continue;
+
+		stats->opackets += txvq->packets;
+		stats->obytes += txvq->bytes;
+		stats->oerrors += txvq->errors;
+
+		if (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
+			stats->q_opackets[i] = txvq->packets;
+			stats->q_obytes[i] = txvq->bytes;
+		}
+	}
+
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		const struct virtqueue *rxvq = dev->data->rx_queues[i];
+		if (rxvq == NULL)
+			continue;
+
+		stats->ipackets += rxvq->packets;
+		stats->ibytes += rxvq->bytes;
+		stats->ierrors += rxvq->errors;
+
+		if (i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
+			stats->q_ipackets[i] = rxvq->packets;
+			stats->q_ibytes[i] = rxvq->bytes;
+		}
+	}
+
+	stats->rx_nombuf = dev->data->rx_mbuf_alloc_failed;
 }
 
 static void
 virtio_dev_stats_reset(struct rte_eth_dev *dev)
 {
-	struct virtio_hw *hw =
-		VIRTIO_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	/* Reset software totals */
-	memset(&hw->eth_stats, 0, sizeof(hw->eth_stats));
+	unsigned int i;
+
+	for (i = 0; i < dev->data->nb_tx_queues; i++) {
+		struct virtqueue *txvq = dev->data->tx_queues[i];
+		if (txvq == NULL)
+			continue;
+
+		txvq->packets = 0;
+		txvq->bytes = 0;
+		txvq->errors = 0;
+	}
+
+	for (i = 0; i < dev->data->nb_rx_queues; i++) {
+		struct virtqueue *rxvq = dev->data->rx_queues[i];
+		if (rxvq == NULL)
+			continue;
+
+		rxvq->packets = 0;
+		rxvq->bytes = 0;
+		rxvq->errors = 0;
+	}
+
+	dev->data->rx_mbuf_alloc_failed = 0;
 }
 
 static void
--- a/lib/librte_pmd_virtio/virtio_pci.h	2014-06-13 17:41:11.634778400 -0700
+++ b/lib/librte_pmd_virtio/virtio_pci.h	2014-06-13 17:41:11.626778388 -0700
@@ -179,7 +179,6 @@ struct virtio_hw {
 	uint8_t     revision_id;
 	uint8_t     mac_addr[ETHER_ADDR_LEN];
 	int         adapter_stopped;
-	struct      rte_eth_stats eth_stats;
 };
 
 /*
--- a/lib/librte_pmd_virtio/virtio_rxtx.c	2014-06-13 17:41:11.634778400 -0700
+++ b/lib/librte_pmd_virtio/virtio_rxtx.c	2014-06-13 17:42:07.946869260 -0700
@@ -301,7 +301,7 @@ virtio_recv_pkts(void *rx_queue, struct
 			PMD_RX_LOG(ERR, "Packet drop\n");
 			nb_enqueued++;
 			virtio_discard_rxbuf(rxvq, rxm);
-			hw->eth_stats.ierrors++;
+			rxvq->errors++;
 			continue;
 		}
 
@@ -317,20 +317,19 @@ virtio_recv_pkts(void *rx_queue, struct
 		VIRTIO_DUMP_PACKET(rxm, rxm->pkt.data_len);
 
 		rx_pkts[nb_rx++] = rxm;
-		hw->eth_stats.ibytes += len[i] - sizeof(struct virtio_net_hdr);
-		hw->eth_stats.q_ibytes[rxvq->queue_id] += len[i]
-			- sizeof(struct virtio_net_hdr);
+		rxvq->bytes += len[i] - sizeof(struct virtio_net_hdr);
 	}
 
-	hw->eth_stats.ipackets += nb_rx;
-	hw->eth_stats.q_ipackets[rxvq->queue_id] += nb_rx;
+	rxvq->packets += nb_rx;
 
 	/* Allocate new mbuf for the used descriptor */
 	error = ENOSPC;
 	while (likely(!virtqueue_full(rxvq))) {
 		new_mbuf = rte_rxmbuf_alloc(rxvq->mpool);
 		if (unlikely(new_mbuf == NULL)) {
-			hw->eth_stats.rx_nombuf++;
+			struct rte_eth_dev *dev
+				= &rte_eth_devices[rxvq->port_id];
+			dev->data->rx_mbuf_alloc_failed++;
 			break;
 		}
 		error = virtqueue_enqueue_recv_refill(rxvq, new_mbuf);
@@ -359,7 +358,6 @@ virtio_xmit_pkts(void *tx_queue, struct
 	struct rte_mbuf *txm;
 	uint16_t nb_used, nb_tx, num;
 	int error;
-	struct virtio_hw *hw;
 
 	nb_tx = 0;
 
@@ -371,7 +369,6 @@ virtio_xmit_pkts(void *tx_queue, struct
 
 	rmb();
 
-	hw = txvq->hw;
 	num = (uint16_t)(likely(nb_used < VIRTIO_MBUF_BURST_SZ) ? nb_used : VIRTIO_MBUF_BURST_SZ);
 
 	while (nb_tx < nb_pkts) {
@@ -394,9 +391,7 @@ virtio_xmit_pkts(void *tx_queue, struct
 				break;
 			}
 			nb_tx++;
-			hw->eth_stats.obytes += txm->pkt.data_len;
-			hw->eth_stats.q_obytes[txvq->queue_id]
-				+= txm->pkt.data_len;
+			txvq->bytes += txm->pkt.data_len;
 		} else {
 			PMD_TX_LOG(ERR, "No free tx descriptors to transmit\n");
 			break;
@@ -404,8 +399,7 @@ virtio_xmit_pkts(void *tx_queue, struct
 	}
 	vq_update_avail_idx(txvq);
 
-	hw->eth_stats.opackets += nb_tx;
-	hw->eth_stats.q_opackets[txvq->queue_id] += nb_tx;
+	txvq->packets += nb_tx;
 
 	if (unlikely(virtqueue_kick_prepare(txvq))) {
 		virtqueue_notify(txvq);
--- a/lib/librte_pmd_virtio/virtqueue.h	2014-06-13 17:41:11.634778400 -0700
+++ b/lib/librte_pmd_virtio/virtqueue.h	2014-06-13 17:41:11.630778394 -0700
@@ -154,6 +154,11 @@ struct virtqueue {
 	uint16_t vq_avail_idx;
 	void     *virtio_net_hdr_mem; /**< hdr for each xmit packet */
 
+	/* Statistics */
+	uint64_t	packets;
+	uint64_t	bytes;
+	uint64_t	errors;
+
 	struct vq_desc_extra {
 		void              *cookie;
 		uint16_t          ndescs;