Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5b1bf7cb authored by Heinz Graalfs's avatar Heinz Graalfs Committed by Rusty Russell
Browse files

virtio_ring: let virtqueue_{kick()/notify()} return a bool



virtqueue_{kick()/notify()} should exploit the new host notification API.
If the notify call returned with a negative value the host kick failed
(e.g. a kick triggered after a device was hot-unplugged). In this case
the virtqueue is set to 'broken' and false is returned, otherwise true.

Signed-off-by: default avatarHeinz Graalfs <graalfs@linux.vnet.ibm.com>
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent 46f9c2b9
Loading
Loading
Loading
Loading
+16 −4
Original line number Diff line number Diff line
@@ -430,13 +430,22 @@ EXPORT_SYMBOL_GPL(virtqueue_kick_prepare);
 * @vq: the struct virtqueue
 *
 * This does not need to be serialized.
 *
 * Returns false if host notify failed or queue is broken, otherwise true.
 */
void virtqueue_notify(struct virtqueue *_vq)
bool virtqueue_notify(struct virtqueue *_vq)
{
	struct vring_virtqueue *vq = to_vvq(_vq);

	if (unlikely(vq->broken))
		return false;

	/* Prod other side to tell it about changes. */
	vq->notify(_vq);
	if (vq->notify(_vq) < 0) {
		vq->broken = true;
		return false;
	}
	return true;
}
EXPORT_SYMBOL_GPL(virtqueue_notify);

@@ -449,11 +458,14 @@ EXPORT_SYMBOL_GPL(virtqueue_notify);
 *
 * Caller must ensure we don't call this with other virtqueue
 * operations at the same time (except where noted).
 *
 * Returns false if kick failed, otherwise true.
 */
void virtqueue_kick(struct virtqueue *vq)
bool virtqueue_kick(struct virtqueue *vq)
{
	if (virtqueue_kick_prepare(vq))
		virtqueue_notify(vq);
		return virtqueue_notify(vq);
	return true;
}
EXPORT_SYMBOL_GPL(virtqueue_kick);

+2 −2
Original line number Diff line number Diff line
@@ -51,11 +51,11 @@ int virtqueue_add_sgs(struct virtqueue *vq,
		      void *data,
		      gfp_t gfp);

void virtqueue_kick(struct virtqueue *vq);
bool virtqueue_kick(struct virtqueue *vq);

bool virtqueue_kick_prepare(struct virtqueue *vq);

void virtqueue_notify(struct virtqueue *vq);
bool virtqueue_notify(struct virtqueue *vq);

void *virtqueue_get_buf(struct virtqueue *vq, unsigned int *len);