On Fri, Sep 06, 2019 at 03:13:50PM +0300, Johannes Berg wrote: > From: Johannes Berg <johannes.b...@intel.com> > > Signed-off-by: Johannes Berg <johannes.b...@intel.com>
a bit more content here about the motivation for this? > --- > contrib/libvhost-user/libvhost-user.c | 61 +++++++++++++++++++++++---- > contrib/libvhost-user/libvhost-user.h | 3 ++ > 2 files changed, 56 insertions(+), 8 deletions(-) > > diff --git a/contrib/libvhost-user/libvhost-user.c > b/contrib/libvhost-user/libvhost-user.c > index fba291c13db4..550f6416a211 100644 > --- a/contrib/libvhost-user/libvhost-user.c > +++ b/contrib/libvhost-user/libvhost-user.c > @@ -136,6 +136,7 @@ vu_request_to_string(unsigned int req) > REQ(VHOST_USER_GET_INFLIGHT_FD), > REQ(VHOST_USER_SET_INFLIGHT_FD), > REQ(VHOST_USER_GPU_SET_SOCKET), > + REQ(VHOST_USER_VRING_KICK), > REQ(VHOST_USER_MAX), > }; > #undef REQ > @@ -920,6 +921,7 @@ static bool > vu_check_queue_msg_file(VuDev *dev, VhostUserMsg *vmsg) > { > int index = vmsg->payload.u64 & VHOST_USER_VRING_IDX_MASK; > + bool nofd = vmsg->payload.u64 & VHOST_USER_VRING_NOFD_MASK; > > if (index >= dev->max_queues) { > vmsg_close_fds(vmsg); > @@ -927,8 +929,12 @@ vu_check_queue_msg_file(VuDev *dev, VhostUserMsg *vmsg) > return false; > } > > - if (vmsg->payload.u64 & VHOST_USER_VRING_NOFD_MASK || > - vmsg->fd_num != 1) { > + if (nofd) { > + vmsg_close_fds(vmsg); > + return true; > + } > + > + if (vmsg->fd_num != 1) { > vmsg_close_fds(vmsg); > vu_panic(dev, "Invalid fds in request: %d", vmsg->request); > return false; > @@ -1025,6 +1031,7 @@ static bool > vu_set_vring_kick_exec(VuDev *dev, VhostUserMsg *vmsg) > { > int index = vmsg->payload.u64 & VHOST_USER_VRING_IDX_MASK; > + bool nofd = vmsg->payload.u64 & VHOST_USER_VRING_NOFD_MASK; > > DPRINT("u64: 0x%016"PRIx64"\n", vmsg->payload.u64); > > @@ -1038,8 +1045,8 @@ vu_set_vring_kick_exec(VuDev *dev, VhostUserMsg *vmsg) > dev->vq[index].kick_fd = -1; > } > > - dev->vq[index].kick_fd = vmsg->fds[0]; > - DPRINT("Got kick_fd: %d for vq: %d\n", vmsg->fds[0], index); > + dev->vq[index].kick_fd = nofd ? -1 : vmsg->fds[0]; > + DPRINT("Got kick_fd: %d for vq: %d\n", dev->vq[index].kick_fd, index); > > dev->vq[index].started = true; > if (dev->iface->queue_set_started) { > @@ -1116,6 +1123,7 @@ static bool > vu_set_vring_call_exec(VuDev *dev, VhostUserMsg *vmsg) > { > int index = vmsg->payload.u64 & VHOST_USER_VRING_IDX_MASK; > + bool nofd = VHOST_USER_VRING_NOFD_MASK; > > DPRINT("u64: 0x%016"PRIx64"\n", vmsg->payload.u64); > > @@ -1128,14 +1136,14 @@ vu_set_vring_call_exec(VuDev *dev, VhostUserMsg *vmsg) > dev->vq[index].call_fd = -1; > } > > - dev->vq[index].call_fd = vmsg->fds[0]; > + dev->vq[index].call_fd = nofd ? -1 : vmsg->fds[0]; > > /* in case of I/O hang after reconnecting */ > - if (eventfd_write(vmsg->fds[0], 1)) { > + if (dev->vq[index].call_fd != -1 && eventfd_write(vmsg->fds[0], 1)) { > return -1; > } > > - DPRINT("Got call_fd: %d for vq: %d\n", vmsg->fds[0], index); > + DPRINT("Got call_fd: %d for vq: %d\n", dev->vq[index].call_fd, index); > > return false; > } > @@ -1169,7 +1177,8 @@ vu_get_protocol_features_exec(VuDev *dev, VhostUserMsg > *vmsg) > 1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ | > 1ULL << VHOST_USER_PROTOCOL_F_HOST_NOTIFIER | > 1ULL << VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD | > - 1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK; > + 1ULL << VHOST_USER_PROTOCOL_F_REPLY_ACK | > + 1ULL << VHOST_USER_PROTOCOL_F_KICK_CALL_MSGS; > > if (have_userfault()) { > features |= 1ULL << VHOST_USER_PROTOCOL_F_PAGEFAULT; > @@ -1456,6 +1465,25 @@ vu_set_inflight_fd(VuDev *dev, VhostUserMsg *vmsg) > return false; > } > > +static bool > +vu_handle_vring_kick(VuDev *dev, VhostUserMsg *vmsg) > +{ > + unsigned int index = vmsg->payload.state.index; > + > + if (index >= dev->max_queues) { > + vu_panic(dev, "Invalid queue index: %u", index); > + return false; > + } > + > + DPRINT("Got kick message: handler:%p idx:%d\n", > + dev->vq[index].handler, index); > + if (dev->vq[index].handler) { > + dev->vq[index].handler(dev, index); > + } > + > + return false; > +} > + > static bool > vu_process_message(VuDev *dev, VhostUserMsg *vmsg) > { > @@ -1538,6 +1566,8 @@ vu_process_message(VuDev *dev, VhostUserMsg *vmsg) > return vu_get_inflight_fd(dev, vmsg); > case VHOST_USER_SET_INFLIGHT_FD: > return vu_set_inflight_fd(dev, vmsg); > + case VHOST_USER_VRING_KICK: > + return vu_handle_vring_kick(dev, vmsg); > default: > vmsg_close_fds(vmsg); > vu_panic(dev, "Unhandled request: %d", vmsg->request); > @@ -2010,6 +2040,21 @@ vu_queue_notify(VuDev *dev, VuVirtq *vq) > return; > } > > + if (vu_has_protocol_feature(dev, VHOST_USER_PROTOCOL_F_KICK_CALL_MSGS) && > + vu_has_protocol_feature(dev, VHOST_USER_PROTOCOL_F_SLAVE_REQ)) { > + VhostUserMsg vmsg = { > + .request = VHOST_USER_SLAVE_VRING_CALL, > + .flags = VHOST_USER_VERSION, > + .size = sizeof(vmsg.payload.state), > + .payload.state = { > + .index = dev->vq - vq, > + }, > + }; > + > + vu_message_write(dev, dev->slave_fd, &vmsg); > + return; > + } > + > if (eventfd_write(vq->call_fd, 1) < 0) { > vu_panic(dev, "Error writing eventfd: %s", strerror(errno)); > } > diff --git a/contrib/libvhost-user/libvhost-user.h > b/contrib/libvhost-user/libvhost-user.h > index 46b600799b2e..392dea306bb9 100644 > --- a/contrib/libvhost-user/libvhost-user.h > +++ b/contrib/libvhost-user/libvhost-user.h > @@ -53,6 +53,7 @@ enum VhostUserProtocolFeature { > VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD = 10, > VHOST_USER_PROTOCOL_F_HOST_NOTIFIER = 11, > VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD = 12, > + VHOST_USER_PROTOCOL_F_KICK_CALL_MSGS = 13, > > VHOST_USER_PROTOCOL_F_MAX > }; > @@ -94,6 +95,7 @@ typedef enum VhostUserRequest { > VHOST_USER_GET_INFLIGHT_FD = 31, > VHOST_USER_SET_INFLIGHT_FD = 32, > VHOST_USER_GPU_SET_SOCKET = 33, > + VHOST_USER_VRING_KICK = 34, > VHOST_USER_MAX > } VhostUserRequest; > > @@ -102,6 +104,7 @@ typedef enum VhostUserSlaveRequest { > VHOST_USER_SLAVE_IOTLB_MSG = 1, > VHOST_USER_SLAVE_CONFIG_CHANGE_MSG = 2, > VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG = 3, > + VHOST_USER_SLAVE_VRING_CALL = 4, > VHOST_USER_SLAVE_MAX > } VhostUserSlaveRequest; > > -- > 2.23.0 >