@@ -105,6 +105,9 @@ struct vring_virtqueue {
/* Host publishes avail event idx */
bool event;
+ /* Suppress warning in interrupt handler */
+ bool no_interrupt_check;
+
/* Head of free buffer list. */
unsigned int free_head;
/* Number we've added since last sync. */
@@ -1604,6 +1607,7 @@ static struct virtqueue *vring_create_virtqueue_packed(
vq->notify = notify;
vq->weak_barriers = weak_barriers;
vq->broken = false;
+ vq->no_interrupt_check = false;
vq->last_used_idx = 0;
vq->num_added = 0;
vq->packed_ring = true;
@@ -2037,6 +2041,9 @@ irqreturn_t vring_interrupt(int irq, void *_vq)
struct vring_virtqueue *vq = to_vvq(_vq);
if (!more_used(vq)) {
+ if (vq->no_interrupt_check)
+ return IRQ_HANDLED;
+
pr_debug("virtqueue interrupt with no work for %p\n", vq);
return IRQ_NONE;
}
@@ -2082,6 +2089,7 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index,
vq->notify = notify;
vq->weak_barriers = weak_barriers;
vq->broken = false;
+ vq->no_interrupt_check = false;
vq->last_used_idx = 0;
vq->num_added = 0;
vq->use_dma_api = vring_use_dma_api(vdev);
@@ -2266,6 +2274,14 @@ bool virtqueue_is_broken(struct virtqueue *_vq)
}
EXPORT_SYMBOL_GPL(virtqueue_is_broken);
+void virtqueue_set_no_interrupt_check(struct virtqueue *_vq, bool val)
+{
+ struct vring_virtqueue *vq = to_vvq(_vq);
+
+ vq->no_interrupt_check = val;
+}
+EXPORT_SYMBOL_GPL(virtqueue_set_no_interrupt_check);
+
/*
* This should prevent the device from being used, allowing drivers to
* recover. You may need to grab appropriate locks to flush.
@@ -84,6 +84,8 @@ unsigned int virtqueue_get_vring_size(struct virtqueue *vq);
bool virtqueue_is_broken(struct virtqueue *vq);
+void virtqueue_set_no_interrupt_check(struct virtqueue *vq, bool val);
+
const struct vring *virtqueue_get_vring(struct virtqueue *vq);
dma_addr_t virtqueue_get_desc_addr(struct virtqueue *vq);
dma_addr_t virtqueue_get_avail_addr(struct virtqueue *vq);