diff --git a/devicemodel/core/iothread.c b/devicemodel/core/iothread.c index 238ecb375..c572f04e1 100644 --- a/devicemodel/core/iothread.c +++ b/devicemodel/core/iothread.c @@ -21,6 +21,7 @@ #define MEVENT_MAX 64 +#define MAX_EVENT_NUM 64 struct iothread_ctx { pthread_t tid; int epfd; @@ -34,7 +35,8 @@ io_thread(void *arg) { struct epoll_event eventlist[MEVENT_MAX]; struct iothread_mevent *aevp; - int i, n; + int i, n, status; + char buf[MAX_EVENT_NUM]; while(ioctx.started) { n = epoll_wait(ioctx.epfd, eventlist, MEVENT_MAX, -1); @@ -47,8 +49,13 @@ io_thread(void *arg) } for (i = 0; i < n; i++) { aevp = eventlist[i].data.ptr; - if (aevp && aevp->run) + if (aevp && aevp->run) { + /* Mitigate the epoll_wait repeat cycles by reading out the events as more as possile.*/ + do { + status = read(aevp->fd, buf, sizeof(buf)); + } while (status == MAX_EVENT_NUM); (*aevp->run)(aevp->arg); + } } } diff --git a/devicemodel/hw/pci/virtio/virtio.c b/devicemodel/hw/pci/virtio/virtio.c index 6b5646269..546ec6f31 100644 --- a/devicemodel/hw/pci/virtio/virtio.c +++ b/devicemodel/hw/pci/virtio/virtio.c @@ -104,6 +104,7 @@ virtio_set_iothread(struct virtio_base *base, vq->viothrd.idx = idx; vq->viothrd.iomvt.arg = &vq->viothrd; vq->viothrd.iomvt.run = iothread_handler; + vq->viothrd.iomvt.fd = vq->viothrd.kick_fd; if (!iothread_add(vq->viothrd.kick_fd, &vq->viothrd.iomvt)) if (!virtio_register_ioeventfd(base, idx, true)) diff --git a/devicemodel/include/iothread.h b/devicemodel/include/iothread.h index 6a3cc7167..fb76e9baa 100644 --- a/devicemodel/include/iothread.h +++ b/devicemodel/include/iothread.h @@ -10,6 +10,7 @@ struct iothread_mevent { void (*run)(void *); void *arg; + int fd; }; int iothread_add(int fd, struct iothread_mevent *aevt); int iothread_del(int fd);