diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2009-09-24 11:59:18 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2009-09-23 20:29:19 -0400 |
commit | 8958f574dbe7e41cc54df0df1accc861bb9f6be8 (patch) | |
tree | d1d88beb865bef3ce0547998151b0ef98d12cb81 | |
parent | 2b5bbe3b8bee8b38bdc27dd9c0270829b6eb7eeb (diff) |
virtio_net: return NETDEV_TX_BUSY instead of queueing an extra skb.
This effectively reverts 99ffc696d10b28580fe93441d627cf290ac4484c
"virtio: wean net driver off NETDEV_TX_BUSY".
The complexity of queuing an skb (setting a tasklet to re-xmit) is
questionable, especially once we get rid of the other reason for the
tasklet in the next patch.
If the skb won't fit in the tx queue, just return NETDEV_TX_BUSY.
This is frowned upon, so a followup patch uses a more complex solution.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | drivers/net/virtio_net.c | 46 |
1 files changed, 10 insertions, 36 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index dc4c68718976..222f3d098ae4 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -48,9 +48,6 @@ struct virtnet_info | |||
48 | struct napi_struct napi; | 48 | struct napi_struct napi; |
49 | unsigned int status; | 49 | unsigned int status; |
50 | 50 | ||
51 | /* The skb we couldn't send because buffers were full. */ | ||
52 | struct sk_buff *last_xmit_skb; | ||
53 | |||
54 | /* If we need to free in a timer, this is it. */ | 51 | /* If we need to free in a timer, this is it. */ |
55 | struct timer_list xmit_free_timer; | 52 | struct timer_list xmit_free_timer; |
56 | 53 | ||
@@ -120,9 +117,8 @@ static void skb_xmit_done(struct virtqueue *svq) | |||
120 | /* We were probably waiting for more output buffers. */ | 117 | /* We were probably waiting for more output buffers. */ |
121 | netif_wake_queue(vi->dev); | 118 | netif_wake_queue(vi->dev); |
122 | 119 | ||
123 | /* Make sure we re-xmit last_xmit_skb: if there are no more packets | 120 | if (vi->free_in_tasklet) |
124 | * queued, start_xmit won't be called. */ | 121 | tasklet_schedule(&vi->tasklet); |
125 | tasklet_schedule(&vi->tasklet); | ||
126 | } | 122 | } |
127 | 123 | ||
128 | static void receive_skb(struct net_device *dev, struct sk_buff *skb, | 124 | static void receive_skb(struct net_device *dev, struct sk_buff *skb, |
@@ -543,12 +539,7 @@ static void xmit_tasklet(unsigned long data) | |||
543 | struct virtnet_info *vi = (void *)data; | 539 | struct virtnet_info *vi = (void *)data; |
544 | 540 | ||
545 | netif_tx_lock_bh(vi->dev); | 541 | netif_tx_lock_bh(vi->dev); |
546 | if (vi->last_xmit_skb && xmit_skb(vi, vi->last_xmit_skb) >= 0) { | 542 | free_old_xmit_skbs(vi); |
547 | vi->svq->vq_ops->kick(vi->svq); | ||
548 | vi->last_xmit_skb = NULL; | ||
549 | } | ||
550 | if (vi->free_in_tasklet) | ||
551 | free_old_xmit_skbs(vi); | ||
552 | netif_tx_unlock_bh(vi->dev); | 543 | netif_tx_unlock_bh(vi->dev); |
553 | } | 544 | } |
554 | 545 | ||
@@ -560,28 +551,16 @@ again: | |||
560 | /* Free up any pending old buffers before queueing new ones. */ | 551 | /* Free up any pending old buffers before queueing new ones. */ |
561 | free_old_xmit_skbs(vi); | 552 | free_old_xmit_skbs(vi); |
562 | 553 | ||
563 | /* If we has a buffer left over from last time, send it now. */ | ||
564 | if (unlikely(vi->last_xmit_skb) && | ||
565 | xmit_skb(vi, vi->last_xmit_skb) < 0) | ||
566 | goto stop_queue; | ||
567 | |||
568 | vi->last_xmit_skb = NULL; | ||
569 | |||
570 | /* Put new one in send queue and do transmit */ | 554 | /* Put new one in send queue and do transmit */ |
571 | if (likely(skb)) { | 555 | __skb_queue_head(&vi->send, skb); |
572 | __skb_queue_head(&vi->send, skb); | 556 | if (likely(xmit_skb(vi, skb) >= 0)) { |
573 | if (xmit_skb(vi, skb) < 0) { | 557 | vi->svq->vq_ops->kick(vi->svq); |
574 | vi->last_xmit_skb = skb; | 558 | return NETDEV_TX_OK; |
575 | skb = NULL; | ||
576 | goto stop_queue; | ||
577 | } | ||
578 | } | 559 | } |
579 | done: | ||
580 | vi->svq->vq_ops->kick(vi->svq); | ||
581 | return NETDEV_TX_OK; | ||
582 | 560 | ||
583 | stop_queue: | 561 | /* Ring too full for this packet, remove it from queue again. */ |
584 | pr_debug("%s: virtio not prepared to send\n", dev->name); | 562 | pr_debug("%s: virtio not prepared to send\n", dev->name); |
563 | __skb_unlink(skb, &vi->send); | ||
585 | netif_stop_queue(dev); | 564 | netif_stop_queue(dev); |
586 | 565 | ||
587 | /* Activate callback for using skbs: if this returns false it | 566 | /* Activate callback for using skbs: if this returns false it |
@@ -591,12 +570,7 @@ stop_queue: | |||
591 | netif_start_queue(dev); | 570 | netif_start_queue(dev); |
592 | goto again; | 571 | goto again; |
593 | } | 572 | } |
594 | if (skb) { | 573 | return NETDEV_TX_BUSY; |
595 | /* Drop this skb: we only queue one. */ | ||
596 | vi->dev->stats.tx_dropped++; | ||
597 | kfree_skb(skb); | ||
598 | } | ||
599 | goto done; | ||
600 | } | 574 | } |
601 | 575 | ||
602 | static int virtnet_set_mac_address(struct net_device *dev, void *p) | 576 | static int virtnet_set_mac_address(struct net_device *dev, void *p) |