aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/xen-netback/interface.c
diff options
context:
space:
mode:
authorWei Liu <wei.liu2@citrix.com>2014-08-12 06:48:07 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-13 23:07:44 -0400
commita64bd934528e26e8956112e43a279fba2ee0634e (patch)
tree304e4fca43ec1c2907bb0db71f50445ef5fcae32 /drivers/net/xen-netback/interface.c
parentea2c5e134237eadc9924ce821ded678750024549 (diff)
xen-netback: don't stop dealloc kthread too early
Reference count the number of packets in host stack, so that we don't stop the deallocation thread too early. If not, we can end up with xenvif_free permanently waiting for deallocation thread to unmap grefs. Reported-by: Thomas Leonard <talex5@gmail.com> Signed-off-by: Wei Liu <wei.liu2@citrix.com> Cc: Ian Campbell <ian.campbell@citrix.com> Cc: Zoltan Kiss <zoltan.kiss@citrix.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/xen-netback/interface.c')
-rw-r--r--drivers/net/xen-netback/interface.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index 5f3d6c06fcf7..0aaca902699a 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -43,6 +43,23 @@
43#define XENVIF_QUEUE_LENGTH 32 43#define XENVIF_QUEUE_LENGTH 32
44#define XENVIF_NAPI_WEIGHT 64 44#define XENVIF_NAPI_WEIGHT 64
45 45
46/* This function is used to set SKBTX_DEV_ZEROCOPY as well as
47 * increasing the inflight counter. We need to increase the inflight
48 * counter because core driver calls into xenvif_zerocopy_callback
49 * which calls xenvif_skb_zerocopy_complete.
50 */
51void xenvif_skb_zerocopy_prepare(struct xenvif_queue *queue,
52 struct sk_buff *skb)
53{
54 skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY;
55 atomic_inc(&queue->inflight_packets);
56}
57
58void xenvif_skb_zerocopy_complete(struct xenvif_queue *queue)
59{
60 atomic_dec(&queue->inflight_packets);
61}
62
46static inline void xenvif_stop_queue(struct xenvif_queue *queue) 63static inline void xenvif_stop_queue(struct xenvif_queue *queue)
47{ 64{
48 struct net_device *dev = queue->vif->dev; 65 struct net_device *dev = queue->vif->dev;
@@ -557,6 +574,7 @@ int xenvif_connect(struct xenvif_queue *queue, unsigned long tx_ring_ref,
557 574
558 init_waitqueue_head(&queue->wq); 575 init_waitqueue_head(&queue->wq);
559 init_waitqueue_head(&queue->dealloc_wq); 576 init_waitqueue_head(&queue->dealloc_wq);
577 atomic_set(&queue->inflight_packets, 0);
560 578
561 if (tx_evtchn == rx_evtchn) { 579 if (tx_evtchn == rx_evtchn) {
562 /* feature-split-event-channels == 0 */ 580 /* feature-split-event-channels == 0 */