All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gregory Haskins <ghaskins@novell.com>
To: alacrityvm-devel@lists.sourceforge.net
Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org
Subject: [NET PATCH 7/9] venet: use an skblist for outstanding descriptors
Date: Wed, 14 Oct 2009 11:59:22 -0400	[thread overview]
Message-ID: <20091014155922.18864.84913.stgit@dev.haskins.net> (raw)
In-Reply-To: <20091014154457.18864.28382.stgit@dev.haskins.net>

This will be useful later in the series so that we can switch to
an asynchronous model.

Signed-off-by: Gregory Haskins <ghaskins@novell.com>
---

 drivers/net/vbus-enet.c |   59 +++++++++++++++++++++++++++--------------------
 1 files changed, 34 insertions(+), 25 deletions(-)

diff --git a/drivers/net/vbus-enet.c b/drivers/net/vbus-enet.c
index 5fccfd1..3032169 100644
--- a/drivers/net/vbus-enet.c
+++ b/drivers/net/vbus-enet.c
@@ -59,8 +59,11 @@ struct vbus_enet_priv {
 	struct vbus_device_proxy  *vdev;
 	struct napi_struct         napi;
 	struct vbus_enet_queue     rxq;
-	struct vbus_enet_queue     txq;
-	struct tasklet_struct      txtask;
+	struct {
+		struct vbus_enet_queue veq;
+		struct tasklet_struct  task;
+		struct sk_buff_head    outstanding;
+	} tx;
 	bool                       sg;
 	struct {
 		bool               enabled;
@@ -76,7 +79,7 @@ struct vbus_enet_priv {
 	} evq;
 };
 
-static void vbus_enet_tx_reap(struct vbus_enet_priv *priv, int force);
+static void vbus_enet_tx_reap(struct vbus_enet_priv *priv);
 
 static struct vbus_enet_priv *
 napi_to_priv(struct napi_struct *napi)
@@ -216,7 +219,7 @@ rx_teardown(struct vbus_enet_priv *priv)
 static int
 tx_setup(struct vbus_enet_priv *priv)
 {
-	struct ioq *ioq    = priv->txq.queue;
+	struct ioq *ioq    = priv->tx.veq.queue;
 	size_t      iovlen = sizeof(struct venet_iov) * (MAX_SKB_FRAGS-1);
 	size_t      len    = sizeof(struct venet_sg) + iovlen;
 	struct ioq_iterator iter;
@@ -233,7 +236,7 @@ tx_setup(struct vbus_enet_priv *priv)
 	/* pre-allocate our descriptor pool if pmtd is enabled */
 	if (priv->pmtd.enabled) {
 		struct vbus_device_proxy *dev = priv->vdev;
-		size_t poollen = len * priv->txq.count;
+		size_t poollen = len * priv->tx.veq.count;
 		char *pool;
 		int shmid;
 
@@ -262,7 +265,7 @@ tx_setup(struct vbus_enet_priv *priv)
 	/*
 	 * Now populate each descriptor with an empty SG descriptor
 	 */
-	for (i = 0; i < priv->txq.count; i++) {
+	for (i = 0; i < priv->tx.veq.count; i++) {
 		struct venet_sg *vsg;
 
 		if (priv->pmtd.enabled) {
@@ -291,12 +294,14 @@ tx_setup(struct vbus_enet_priv *priv)
 static void
 tx_teardown(struct vbus_enet_priv *priv)
 {
-	struct ioq *ioq = priv->txq.queue;
+	struct ioq *ioq = priv->tx.veq.queue;
 	struct ioq_iterator iter;
+	struct sk_buff *skb;
 	int ret;
 
 	/* forcefully free all outstanding transmissions */
-	vbus_enet_tx_reap(priv, 1);
+	while ((skb = __skb_dequeue(&priv->tx.outstanding)))
+		dev_kfree_skb(skb);
 
 	if (!priv->sg)
 		/*
@@ -529,7 +534,7 @@ vbus_enet_tx_start(struct sk_buff *skb, struct net_device *dev)
 
 	spin_lock_irqsave(&priv->lock, flags);
 
-	if (ioq_full(priv->txq.queue, ioq_idxtype_valid)) {
+	if (ioq_full(priv->tx.veq.queue, ioq_idxtype_valid)) {
 		/*
 		 * We must flow-control the kernel by disabling the
 		 * queue
@@ -544,7 +549,7 @@ vbus_enet_tx_start(struct sk_buff *skb, struct net_device *dev)
 	 * We want to iterate on the tail of both the "inuse" and "valid" index
 	 * so we specify the "both" index
 	 */
-	ret = ioq_iter_init(priv->txq.queue, &iter, ioq_idxtype_both,
+	ret = ioq_iter_init(priv->tx.veq.queue, &iter, ioq_idxtype_both,
 			    IOQ_ITER_AUTOUPDATE);
 	BUG_ON(ret < 0);
 
@@ -620,6 +625,8 @@ vbus_enet_tx_start(struct sk_buff *skb, struct net_device *dev)
 	priv->dev->stats.tx_packets++;
 	priv->dev->stats.tx_bytes += skb->len;
 
+	__skb_queue_tail(&priv->tx.outstanding, skb);
+
 	/*
 	 * This advances both indexes together implicitly, and then
 	 * signals the south side to consume the packet
@@ -629,7 +636,7 @@ vbus_enet_tx_start(struct sk_buff *skb, struct net_device *dev)
 
 	dev->trans_start = jiffies; /* save the timestamp */
 
-	if (ioq_full(priv->txq.queue, ioq_idxtype_valid)) {
+	if (ioq_full(priv->tx.veq.queue, ioq_idxtype_valid)) {
 		/*
 		 * If the queue is congested, we must flow-control the kernel
 		 */
@@ -648,7 +655,7 @@ vbus_enet_tx_start(struct sk_buff *skb, struct net_device *dev)
  * assumes priv->lock held
  */
 static void
-vbus_enet_tx_reap(struct vbus_enet_priv *priv, int force)
+vbus_enet_tx_reap(struct vbus_enet_priv *priv)
 {
 	struct ioq_iterator iter;
 	int ret;
@@ -658,7 +665,7 @@ vbus_enet_tx_reap(struct vbus_enet_priv *priv, int force)
 	 * do not want the iter_pop (below) to flip the ownership, so
 	 * we set the NOFLIPOWNER option
 	 */
-	ret = ioq_iter_init(priv->txq.queue, &iter, ioq_idxtype_valid,
+	ret = ioq_iter_init(priv->tx.veq.queue, &iter, ioq_idxtype_valid,
 			    IOQ_ITER_NOFLIPOWNER);
 	BUG_ON(ret < 0);
 
@@ -669,7 +676,7 @@ vbus_enet_tx_reap(struct vbus_enet_priv *priv, int force)
 	 * We are done once we find the first packet either invalid or still
 	 * owned by the south-side
 	 */
-	while (iter.desc->valid && (!iter.desc->sown || force)) {
+	while (iter.desc->valid && !iter.desc->sown) {
 		struct sk_buff *skb;
 
 		if (priv->sg) {
@@ -687,6 +694,7 @@ vbus_enet_tx_reap(struct vbus_enet_priv *priv, int force)
 		/* Reset the descriptor */
 		iter.desc->valid  = 0;
 
+		__skb_unlink(skb, &priv->tx.outstanding);
 		dev_kfree_skb(skb);
 
 		/* Advance the valid-index head */
@@ -699,7 +707,7 @@ vbus_enet_tx_reap(struct vbus_enet_priv *priv, int force)
 	 * processing
 	 */
 	if (netif_queue_stopped(priv->dev)
-	    && !ioq_full(priv->txq.queue, ioq_idxtype_valid)) {
+	    && !ioq_full(priv->tx.veq.queue, ioq_idxtype_valid)) {
 		PDEBUG(priv->dev, "re-enabling tx queue\n");
 		netif_wake_queue(priv->dev);
 	}
@@ -714,7 +722,7 @@ vbus_enet_timeout(struct net_device *dev)
 	dev_dbg(&dev->dev, "Transmit timeout\n");
 
 	spin_lock_irqsave(&priv->lock, flags);
-	vbus_enet_tx_reap(priv, 0);
+	vbus_enet_tx_reap(priv);
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
@@ -740,10 +748,10 @@ deferred_tx_isr(unsigned long data)
 	PDEBUG(priv->dev, "deferred_tx_isr\n");
 
 	spin_lock_irqsave(&priv->lock, flags);
-	vbus_enet_tx_reap(priv, 0);
+	vbus_enet_tx_reap(priv);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	ioq_notify_enable(priv->txq.queue, 0);
+	ioq_notify_enable(priv->tx.veq.queue, 0);
 }
 
 static void
@@ -751,12 +759,12 @@ tx_isr(struct ioq_notifier *notifier)
 {
        struct vbus_enet_priv *priv;
 
-       priv = container_of(notifier, struct vbus_enet_priv, txq.notifier);
+       priv = container_of(notifier, struct vbus_enet_priv, tx.veq.notifier);
 
        PDEBUG(priv->dev, "tx_isr\n");
 
-       ioq_notify_disable(priv->txq.queue, 0);
-       tasklet_schedule(&priv->txtask);
+       ioq_notify_disable(priv->tx.veq.queue, 0);
+       tasklet_schedule(&priv->tx.task);
 }
 
 static void
@@ -1043,16 +1051,17 @@ vbus_enet_probe(struct vbus_device_proxy *vdev)
 		goto out_free;
 	}
 
-	tasklet_init(&priv->txtask, deferred_tx_isr, (unsigned long)priv);
+	tasklet_init(&priv->tx.task, deferred_tx_isr, (unsigned long)priv);
+	skb_queue_head_init(&priv->tx.outstanding);
 
 	queue_init(priv, &priv->rxq, VENET_QUEUE_RX, rx_ringlen, rx_isr);
-	queue_init(priv, &priv->txq, VENET_QUEUE_TX, tx_ringlen, tx_isr);
+	queue_init(priv, &priv->tx.veq, VENET_QUEUE_TX, tx_ringlen, tx_isr);
 
 	rx_setup(priv);
 	tx_setup(priv);
 
 	ioq_notify_enable(priv->rxq.queue, 0);  /* enable interrupts */
-	ioq_notify_enable(priv->txq.queue, 0);
+	ioq_notify_enable(priv->tx.veq.queue, 0);
 
 	dev->netdev_ops     = &vbus_enet_netdev_ops;
 	dev->watchdog_timeo = 5 * HZ;
@@ -1101,7 +1110,7 @@ vbus_enet_remove(struct vbus_device_proxy *vdev)
 	ioq_put(priv->rxq.queue);
 
 	tx_teardown(priv);
-	ioq_put(priv->txq.queue);
+	ioq_put(priv->tx.veq.queue);
 
 	if (priv->evq.enabled)
 		evq_teardown(priv);


  parent reply	other threads:[~2009-10-14 16:09 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-10-14 15:58 [NET PATCH 0/9] ZC/L4RO enhancements to alacrityvm::vbus-enet driver Gregory Haskins
2009-10-14 15:58 ` [NET PATCH 1/9] venet: Update maintainer Gregory Haskins
2009-10-14 15:58 ` [NET PATCH 2/9] venet: fix gso.hdr_len to report correct length Gregory Haskins
2009-10-14 15:59 ` [NET PATCH 3/9] venet: add pre-mapped tx descriptor feature Gregory Haskins
2009-10-14 15:59 ` [NET PATCH 4/9] venet: report actual used descriptor size Gregory Haskins
2009-10-14 15:59 ` [NET PATCH 5/9] venet: cache the ringlen values at init Gregory Haskins
2009-10-14 15:59 ` [NET PATCH 6/9] venet: add eventq protocol Gregory Haskins
2009-10-14 15:59 ` Gregory Haskins [this message]
2009-10-14 15:59 ` [NET PATCH 8/9] venet: add a tx-complete event for out-of-order support Gregory Haskins
2009-10-14 15:59 ` [NET PATCH 9/9] venet: add Layer-4 Reassembler Offload (L4RO) support Gregory Haskins

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20091014155922.18864.84913.stgit@dev.haskins.net \
    --to=ghaskins@novell.com \
    --cc=alacrityvm-devel@lists.sourceforge.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.