]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
xen-netback: wake up xenvif_dealloc_kthread when it should stop
authorDongli Zhang <dongli.zhang@oracle.com>
Mon, 21 Jan 2019 01:56:55 +0000 (09:56 +0800)
committerBrian Maly <brian.maly@oracle.com>
Wed, 30 Jan 2019 04:03:12 +0000 (23:03 -0500)
The feature 'staging grant' changed the behaviour of
xenvif_zerocopy_callback() that queue->dealloc_prod may not increase during
the do-while loop because of 'staging grant'. As a result,
xenvif_skb_zerocopy_complete() would not wake up xenvif_dealloc_kthread
because (prod == queue->dealloc_prod).

This makes trouble when the xenvif_dealloc_kthread is requested to stop by
xenvif_disconnect(). When xenvif_dealloc_kthread is stopped while
inflight_packets is not 0, xenvif_dealloc_kthread would not exit until
inflight_packets becomes 0.

However, because of 'staging grant', xenvif_skb_zerocopy_complete() would
not wake up xenvif_dealloc_kthread() although inflight_packets is
decremented and already becomes 0. As a result, xenvif_dealloc_kthread will
never wakes up.

xenvif_skb_zerocopy_complete() should wake up xenvif_dealloc_kthread when
the latter is in the progress to stop.

Orabug: 29217927

Fixes: fdbb2e3659b3 ("xen-netback: use gref mappings for Tx requests")
Reported-by: Ajaykumar Hotchandani <ajaykumar.hotchandani@oracle.com>
Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
Reviewed-by: Joao Martins <joao.m.martins@oracle.com>
Reviewed-by: Joe Jin <joe.jin@oracle.com>
Signed-off-by: Brian Maly <brian.maly@oracle.com>
drivers/net/xen-netback/interface.c

index 461b764f0567c6e133f5c0c3fdb7b7bd47da7217..432a965242da34e4f750f7a5b463f006c80a4483 100644 (file)
@@ -66,9 +66,12 @@ void xenvif_skb_zerocopy_complete(struct xenvif_queue *queue,
        /* 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. But only wake up when
-        * there are grants to unmap.
+        * there are grants to unmap, or when we disconnect/teardown the
+        * interface.
         */
-       if (prod != queue->dealloc_prod)
+       if (prod != queue->dealloc_prod ||
+           (unlikely(!test_bit(VIF_STATUS_CONNECTED, &queue->vif->status) &&
+                     !atomic_read(&queue->inflight_packets))))
                wake_up(&queue->dealloc_wq);
 }