Support the new event index feature. When acked,
utilize it to reduce the # of interrupts sent to the guest.
Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
drivers/vhost/net.c | 12 ++--
drivers/vhost/test.c |6 +-
drivers/vhost/vhost.c | 138 +
drivers/vhost/vhost.h | 21 +---
4 files changed, 127 insertions(+), 50 deletions(-)
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 2f7c76a..e224a92 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -144,7 +144,7 @@ static void handle_tx(struct vhost_net *net)
}
mutex_lock(vq-mutex);
- vhost_disable_notify(vq);
+ vhost_disable_notify(net-dev, vq);
if (wmem sock-sk-sk_sndbuf / 2)
tx_poll_stop(net);
@@ -166,8 +166,8 @@ static void handle_tx(struct vhost_net *net)
set_bit(SOCK_ASYNC_NOSPACE, sock-flags);
break;
}
- if (unlikely(vhost_enable_notify(vq))) {
- vhost_disable_notify(vq);
+ if (unlikely(vhost_enable_notify(net-dev, vq))) {
+ vhost_disable_notify(net-dev, vq);
continue;
}
break;
@@ -315,7 +315,7 @@ static void handle_rx(struct vhost_net *net)
return;
mutex_lock(vq-mutex);
- vhost_disable_notify(vq);
+ vhost_disable_notify(net-dev, vq);
vhost_hlen = vq-vhost_hlen;
sock_hlen = vq-sock_hlen;
@@ -334,10 +334,10 @@ static void handle_rx(struct vhost_net *net)
break;
/* OK, now we need to know about added descriptors. */
if (!headcount) {
- if (unlikely(vhost_enable_notify(vq))) {
+ if (unlikely(vhost_enable_notify(net-dev, vq))) {
/* They have slipped one in as we were
* doing that: check again. */
- vhost_disable_notify(vq);
+ vhost_disable_notify(net-dev, vq);
continue;
}
/* Nothing new? Wait for eventfd to tell us
diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c
index 099f302..734e1d7 100644
--- a/drivers/vhost/test.c
+++ b/drivers/vhost/test.c
@@ -49,7 +49,7 @@ static void handle_vq(struct vhost_test *n)
return;
mutex_lock(vq-mutex);
- vhost_disable_notify(vq);
+ vhost_disable_notify(n-dev, vq);
for (;;) {
head = vhost_get_vq_desc(n-dev, vq, vq-iov,
@@ -61,8 +61,8 @@ static void handle_vq(struct vhost_test *n)
break;
/* Nothing new? Wait for eventfd to tell us they refilled. */
if (head == vq-num) {
- if (unlikely(vhost_enable_notify(vq))) {
- vhost_disable_notify(vq);
+ if (unlikely(vhost_enable_notify(n-dev, vq))) {
+ vhost_disable_notify(n-dev, vq);
continue;
}
break;
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 2ab2912..2a10786 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -37,6 +37,9 @@ enum {
VHOST_MEMORY_F_LOG = 0x1,
};
+#define vhost_used_event(vq) ((u16 __user *)vq-avail-ring[vq-num])
+#define vhost_avail_event(vq) ((u16 __user *)vq-used-ring[vq-num])
+
static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh,
poll_table *pt)
{
@@ -161,6 +164,8 @@ static void vhost_vq_reset(struct vhost_dev *dev,
vq-last_avail_idx = 0;
vq-avail_idx = 0;
vq-last_used_idx = 0;
+ vq-signalled_used = 0;
+ vq-signalled_used_valid = false;
vq-used_flags = 0;
vq-log_used = false;
vq-log_addr = -1ull;
@@ -489,16 +494,17 @@ static int memory_access_ok(struct vhost_dev *d, struct
vhost_memory *mem,
return 1;
}
-static int vq_access_ok(unsigned int num,
+static int vq_access_ok(struct vhost_dev *d, unsigned int num,
struct vring_desc __user *desc,
struct vring_avail __user *avail,
struct vring_used __user *used)
{
+ size_t s = vhost_has_feature(d, VIRTIO_RING_F_EVENT_IDX) ? 2 : 0;
return access_ok(VERIFY_READ, desc, num * sizeof *desc)
access_ok(VERIFY_READ, avail,
-sizeof *avail + num * sizeof *avail-ring)
+sizeof *avail + num * sizeof *avail-ring + s)
access_ok(VERIFY_WRITE, used,
- sizeof *used + num * sizeof *used-ring);
+