Commit 57b22906 authored by Ross Lagerwall's avatar Ross Lagerwall Committed by David S. Miller

xen/netback: Wake dealloc thread after completing zerocopy work

Waking the dealloc thread before decrementing inflight_packets is racy
because it means the thread may go to sleep before inflight_packets is
decremented. If kthread_stop() has already been called, the dealloc
thread may wait forever with nothing to wake it. Instead, wake the
thread only after decrementing inflight_packets.
Signed-off-by: default avatarRoss Lagerwall <ross.lagerwall@citrix.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a0a2a660
...@@ -61,6 +61,12 @@ void xenvif_skb_zerocopy_prepare(struct xenvif_queue *queue, ...@@ -61,6 +61,12 @@ void xenvif_skb_zerocopy_prepare(struct xenvif_queue *queue,
void xenvif_skb_zerocopy_complete(struct xenvif_queue *queue) void xenvif_skb_zerocopy_complete(struct xenvif_queue *queue)
{ {
atomic_dec(&queue->inflight_packets); atomic_dec(&queue->inflight_packets);
/* Wake the dealloc thread _after_ decrementing inflight_packets so
* that if kthread_stop() has already been called, the dealloc thread
* does not wait forever with nothing to wake it.
*/
wake_up(&queue->dealloc_wq);
} }
int xenvif_schedulable(struct xenvif *vif) int xenvif_schedulable(struct xenvif *vif)
......
...@@ -1541,7 +1541,6 @@ void xenvif_zerocopy_callback(struct ubuf_info *ubuf, bool zerocopy_success) ...@@ -1541,7 +1541,6 @@ void xenvif_zerocopy_callback(struct ubuf_info *ubuf, bool zerocopy_success)
smp_wmb(); smp_wmb();
queue->dealloc_prod++; queue->dealloc_prod++;
} while (ubuf); } while (ubuf);
wake_up(&queue->dealloc_wq);
spin_unlock_irqrestore(&queue->callback_lock, flags); spin_unlock_irqrestore(&queue->callback_lock, flags);
if (likely(zerocopy_success)) if (likely(zerocopy_success))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment