Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934822AbZJNQJw (ORCPT ); Wed, 14 Oct 2009 12:09:52 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1761977AbZJNQJt (ORCPT ); Wed, 14 Oct 2009 12:09:49 -0400 Received: from victor.provo.novell.com ([137.65.250.26]:36174 "EHLO victor.provo.novell.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1761920AbZJNQJq (ORCPT ); Wed, 14 Oct 2009 12:09:46 -0400 From: Gregory Haskins Subject: [NET PATCH 7/9] venet: use an skblist for outstanding descriptors To: alacrityvm-devel@lists.sourceforge.net Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org Date: Wed, 14 Oct 2009 11:59:22 -0400 Message-ID: <20091014155922.18864.84913.stgit@dev.haskins.net> In-Reply-To: <20091014154457.18864.28382.stgit@dev.haskins.net> References: <20091014154457.18864.28382.stgit@dev.haskins.net> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 7766 Lines: 234 This will be useful later in the series so that we can switch to an asynchronous model. Signed-off-by: Gregory Haskins --- 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); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/