static void notify_guest_bh(void *opaque) { VirtIOBlockDataPlane *s = opaque; unsigned nvqs = s->conf->num_queues; unsigned long bitmap[BITS_TO_LONGS(nvqs)]; unsigned j; memcpy(bitmap, s->batch_notify_vqs, sizeof(bitmap)); memset(s->batch_notify_vqs, 0, sizeof(bitmap)); for (j = 0; j < nvqs; j += BITS_PER_LONG) { unsigned long bits = bitmap[j]; while (bits != 0) { unsigned i = j + ctzl(bits); VirtQueue *vq = virtio_get_queue(s->vdev, i); if (virtio_should_notify(s->vdev, vq)) { event_notifier_set(virtio_queue_get_guest_notifier(vq)); } bits &= bits - 1; /* clear right-most bit */ } } }
/* Raise an interrupt to signal guest, if necessary */ static void notify_guest(VirtIOBlockDataPlane *s) { if (!vring_should_notify(s->vdev, &s->vring)) { return; } event_notifier_set(s->guest_notifier); }
void aio_notify(AioContext *ctx) { /* Write e.g. bh->scheduled before reading ctx->dispatching. */ smp_mb(); if (!ctx->dispatching) { event_notifier_set(&ctx->notifier); } }
static void notify_guest_bh(void *opaque) { VirtIOBlockDataPlane *s = opaque; if (!virtio_should_notify(s->vdev, s->vq)) { return; } event_notifier_set(s->guest_notifier); }
static void v9fs_thread_routine(gpointer data, gpointer user_data) { Coroutine *co = data; qemu_coroutine_enter(co, NULL); g_async_queue_push(v9fs_pool.completed, co); event_notifier_set(&v9fs_pool.e); }
static void event_ready_cb(EventNotifier *e) { EventNotifierTestData *data = container_of(e, EventNotifierTestData, e); g_assert(event_notifier_test_and_clear(e)); data->n++; if (data->active > 0) { data->active--; } if (data->auto_set && data->active) { event_notifier_set(e); } }
/* Context: QEMU global mutex held */ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s) { BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s->vdev))); VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); VirtIOBlock *vblk = VIRTIO_BLK(s->vdev); int r; if (vblk->dataplane_started || s->starting) { return; } s->starting = true; s->vq = virtio_get_queue(s->vdev, 0); /* Set up guest notifier (irq) */ r = k->set_guest_notifiers(qbus->parent, 1, true); if (r != 0) { fprintf(stderr, "virtio-blk failed to set guest notifier (%d), " "ensure -enable-kvm is set\n", r); goto fail_guest_notifiers; } s->guest_notifier = virtio_queue_get_guest_notifier(s->vq); /* Set up virtqueue notify */ r = k->set_host_notifier(qbus->parent, 0, true); if (r != 0) { fprintf(stderr, "virtio-blk failed to set host notifier (%d)\n", r); goto fail_host_notifier; } s->starting = false; vblk->dataplane_started = true; trace_virtio_blk_data_plane_start(s); blk_set_aio_context(s->conf->conf.blk, s->ctx); /* Kick right away to begin processing requests already in vring */ event_notifier_set(virtio_queue_get_host_notifier(s->vq)); /* Get this show started by hooking up our callbacks */ aio_context_acquire(s->ctx); virtio_queue_aio_set_host_notifier_handler(s->vq, s->ctx, virtio_blk_data_plane_handle_output); aio_context_release(s->ctx); return; fail_host_notifier: k->set_guest_notifiers(qbus->parent, 1, false); fail_guest_notifiers: vblk->dataplane_disabled = true; s->starting = false; vblk->dataplane_started = true; }
int event_notifier_init(EventNotifier *e, int active) { int fds[2]; int ret; #ifdef CONFIG_EVENTFD ret = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); #else ret = -1; errno = ENOSYS; #endif if (ret >= 0) { e->rfd = e->wfd = ret; } else { if (errno != ENOSYS) { return -errno; } if (qemu_pipe(fds) < 0) { return -errno; } ret = fcntl_setfl(fds[0], O_NONBLOCK); if (ret < 0) { ret = -errno; goto fail; } ret = fcntl_setfl(fds[1], O_NONBLOCK); if (ret < 0) { ret = -errno; goto fail; } e->rfd = fds[0]; e->wfd = fds[1]; } if (active) { event_notifier_set(e); } return 0; fail: close(fds[0]); close(fds[1]); return ret; }
static void *test_acquire_thread(void *opaque) { AcquireTestData *data = opaque; /* Wait for other thread to let us start */ qemu_mutex_lock(&data->start_lock); qemu_mutex_unlock(&data->start_lock); /* event_notifier_set might be called either before or after * the main thread's call to poll(). The test case's outcome * should be the same in either case. */ event_notifier_set(&data->notifier); aio_context_acquire(ctx); aio_context_release(ctx); data->thread_acquired = true; /* success, we got here */ return NULL; }
static void ivshmem_io_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { IVShmemState *s = opaque; uint16_t dest = val >> 16; uint16_t vector = val & 0xff; addr &= 0xfc; IVSHMEM_DPRINTF("writing to addr " TARGET_FMT_plx "\n", addr); switch (addr) { case INTRMASK: ivshmem_IntrMask_write(s, val); break; case INTRSTATUS: ivshmem_IntrStatus_write(s, val); break; case DOORBELL: /* check that dest VM ID is reasonable */ if (dest >= s->nb_peers) { IVSHMEM_DPRINTF("Invalid destination VM ID (%d)\n", dest); break; } /* check doorbell range */ if (vector < s->peers[dest].nb_eventfds) { IVSHMEM_DPRINTF("Notifying VM %d on vector %d\n", dest, vector); event_notifier_set(&s->peers[dest].eventfds[vector]); } else { IVSHMEM_DPRINTF("Invalid destination vector %d on VM %d\n", vector, dest); } break; default: IVSHMEM_DPRINTF("Unhandled write " TARGET_FMT_plx "\n", addr); } }
static int virtio_ccw_set_guest_notifier(VirtioCcwDevice *dev, int n, bool assign, bool with_irqfd) { VirtQueue *vq = virtio_get_queue(dev->vdev, n); EventNotifier *notifier = virtio_queue_get_guest_notifier(vq); VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(dev->vdev); if (assign) { int r = event_notifier_init(notifier, 0); if (r < 0) { return r; } virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd); /* We do not support irqfd for classic I/O interrupts, because the * classic interrupts are intermixed with the subchannel status, that * is queried with test subchannel. We want to use vhost, though. * Lets make sure to have vhost running and wire up the irq fd to * land in qemu (and only the irq fd) in this code. */ if (k->guest_notifier_mask) { k->guest_notifier_mask(dev->vdev, n, false); } /* get lost events and re-inject */ if (k->guest_notifier_pending && k->guest_notifier_pending(dev->vdev, n)) { event_notifier_set(notifier); } } else { if (k->guest_notifier_mask) { k->guest_notifier_mask(dev->vdev, n, true); } virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd); event_notifier_cleanup(notifier); } return 0; }
int kvm_hv_sint_route_set_sint(HvSintRoute *sint_route) { return event_notifier_set(&sint_route->sint_set_notifier); }
void aio_notify(AioContext *ctx) { event_notifier_set(&ctx->notifier); }
void virtio_scsi_dataplane_notify(VirtIODevice *vdev, VirtIOSCSIReq *req) { if (virtio_should_notify(vdev, req->vq)) { event_notifier_set(virtio_queue_get_guest_notifier(req->vq)); } }