Skip to content

Commit 265a0ad

Browse files
Zhu Lingshanmstsirkin
authored andcommitted
vhost: introduce vhost_vring_call
This commit introduces struct vhost_vring_call which replaced raw struct eventfd_ctx *call_ctx in struct vhost_virtqueue. Besides eventfd_ctx, it contains a spin lock and an irq_bypass_producer in its structure. Signed-off-by: Zhu Lingshan <[email protected]> Suggested-by: Jason Wang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Michael S. Tsirkin <[email protected]>
1 parent bf11d71 commit 265a0ad

File tree

3 files changed

+26
-9
lines changed

3 files changed

+26
-9
lines changed

drivers/vhost/vdpa.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ static void handle_vq_kick(struct vhost_work *work)
6363
static irqreturn_t vhost_vdpa_virtqueue_cb(void *private)
6464
{
6565
struct vhost_virtqueue *vq = private;
66-
struct eventfd_ctx *call_ctx = vq->call_ctx;
66+
struct eventfd_ctx *call_ctx = vq->call_ctx.ctx;
6767

6868
if (call_ctx)
6969
eventfd_signal(call_ctx, 1);
@@ -343,7 +343,7 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
343343
break;
344344

345345
case VHOST_SET_VRING_CALL:
346-
if (vq->call_ctx) {
346+
if (vq->call_ctx.ctx) {
347347
cb.callback = vhost_vdpa_virtqueue_cb;
348348
cb.private = vq;
349349
} else {

drivers/vhost/vhost.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,13 @@ static void vhost_vq_meta_reset(struct vhost_dev *d)
298298
__vhost_vq_meta_reset(d->vqs[i]);
299299
}
300300

301+
static void vhost_vring_call_reset(struct vhost_vring_call *call_ctx)
302+
{
303+
call_ctx->ctx = NULL;
304+
memset(&call_ctx->producer, 0x0, sizeof(struct irq_bypass_producer));
305+
spin_lock_init(&call_ctx->ctx_lock);
306+
}
307+
301308
static void vhost_vq_reset(struct vhost_dev *dev,
302309
struct vhost_virtqueue *vq)
303310
{
@@ -319,13 +326,13 @@ static void vhost_vq_reset(struct vhost_dev *dev,
319326
vq->log_base = NULL;
320327
vq->error_ctx = NULL;
321328
vq->kick = NULL;
322-
vq->call_ctx = NULL;
323329
vq->log_ctx = NULL;
324330
vhost_reset_is_le(vq);
325331
vhost_disable_cross_endian(vq);
326332
vq->busyloop_timeout = 0;
327333
vq->umem = NULL;
328334
vq->iotlb = NULL;
335+
vhost_vring_call_reset(&vq->call_ctx);
329336
__vhost_vq_meta_reset(vq);
330337
}
331338

@@ -685,8 +692,8 @@ void vhost_dev_cleanup(struct vhost_dev *dev)
685692
eventfd_ctx_put(dev->vqs[i]->error_ctx);
686693
if (dev->vqs[i]->kick)
687694
fput(dev->vqs[i]->kick);
688-
if (dev->vqs[i]->call_ctx)
689-
eventfd_ctx_put(dev->vqs[i]->call_ctx);
695+
if (dev->vqs[i]->call_ctx.ctx)
696+
eventfd_ctx_put(dev->vqs[i]->call_ctx.ctx);
690697
vhost_vq_reset(dev, dev->vqs[i]);
691698
}
692699
vhost_dev_free_iovecs(dev);
@@ -1629,7 +1636,10 @@ long vhost_vring_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *arg
16291636
r = PTR_ERR(ctx);
16301637
break;
16311638
}
1632-
swap(ctx, vq->call_ctx);
1639+
1640+
spin_lock(&vq->call_ctx.ctx_lock);
1641+
swap(ctx, vq->call_ctx.ctx);
1642+
spin_unlock(&vq->call_ctx.ctx_lock);
16331643
break;
16341644
case VHOST_SET_VRING_ERR:
16351645
if (copy_from_user(&f, argp, sizeof f)) {
@@ -2440,8 +2450,8 @@ static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq)
24402450
void vhost_signal(struct vhost_dev *dev, struct vhost_virtqueue *vq)
24412451
{
24422452
/* Signal the Guest tell them we used something up. */
2443-
if (vq->call_ctx && vhost_notify(dev, vq))
2444-
eventfd_signal(vq->call_ctx, 1);
2453+
if (vq->call_ctx.ctx && vhost_notify(dev, vq))
2454+
eventfd_signal(vq->call_ctx.ctx, 1);
24452455
}
24462456
EXPORT_SYMBOL_GPL(vhost_signal);
24472457

drivers/vhost/vhost.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/virtio_ring.h>
1414
#include <linux/atomic.h>
1515
#include <linux/vhost_iotlb.h>
16+
#include <linux/irqbypass.h>
1617

1718
struct vhost_work;
1819
typedef void (*vhost_work_fn_t)(struct vhost_work *work);
@@ -60,6 +61,12 @@ enum vhost_uaddr_type {
6061
VHOST_NUM_ADDRS = 3,
6162
};
6263

64+
struct vhost_vring_call {
65+
struct eventfd_ctx *ctx;
66+
struct irq_bypass_producer producer;
67+
spinlock_t ctx_lock;
68+
};
69+
6370
/* The virtqueue structure describes a queue attached to a device. */
6471
struct vhost_virtqueue {
6572
struct vhost_dev *dev;
@@ -72,7 +79,7 @@ struct vhost_virtqueue {
7279
vring_used_t __user *used;
7380
const struct vhost_iotlb_map *meta_iotlb[VHOST_NUM_ADDRS];
7481
struct file *kick;
75-
struct eventfd_ctx *call_ctx;
82+
struct vhost_vring_call call_ctx;
7683
struct eventfd_ctx *error_ctx;
7784
struct eventfd_ctx *log_ctx;
7885

0 commit comments

Comments
 (0)