Skip to content

Commit

Permalink
contrib/libvhost-user: Protect slave fd with mutex
Browse files Browse the repository at this point in the history
In future patches we'll be performing commands on the slave-fd driven
by commands on queues, since those queues will be driven by individual
threads we need to make sure they don't attempt to use the slave-fd
for multiple commands in parallel.

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
  • Loading branch information
dagrh committed Jan 23, 2020
1 parent 0fdc465 commit c25c02b
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 4 deletions.
24 changes: 20 additions & 4 deletions contrib/libvhost-user/libvhost-user.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,26 +392,37 @@ vu_send_reply(VuDev *dev, int conn_fd, VhostUserMsg *vmsg)
return vu_message_write(dev, conn_fd, vmsg);
}

/*
* Processes a reply on the slave channel.
* Entered with slave_mutex held and releases it before exit.
* Returns true on success.
*/
static bool
vu_process_message_reply(VuDev *dev, const VhostUserMsg *vmsg)
{
VhostUserMsg msg_reply;
bool result = false;

if ((vmsg->flags & VHOST_USER_NEED_REPLY_MASK) == 0) {
return true;
result = true;
goto out;
}

if (!vu_message_read(dev, dev->slave_fd, &msg_reply)) {
return false;
goto out;
}

if (msg_reply.request != vmsg->request) {
DPRINT("Received unexpected msg type. Expected %d received %d",
vmsg->request, msg_reply.request);
return false;
goto out;
}

return msg_reply.payload.u64 == 0;
result = msg_reply.payload.u64 == 0;

out:
pthread_mutex_unlock(&dev->slave_mutex);
return result;
}

/* Kick the log_call_fd if required. */
Expand Down Expand Up @@ -1105,10 +1116,13 @@ bool vu_set_queue_host_notifier(VuDev *dev, VuVirtq *vq, int fd,
return false;
}

pthread_mutex_lock(&dev->slave_mutex);
if (!vu_message_write(dev, dev->slave_fd, &vmsg)) {
pthread_mutex_unlock(&dev->slave_mutex);
return false;
}

/* Also unlocks the slave_mutex */
return vu_process_message_reply(dev, &vmsg);
}

Expand Down Expand Up @@ -1628,6 +1642,7 @@ vu_deinit(VuDev *dev)
close(dev->slave_fd);
dev->slave_fd = -1;
}
pthread_mutex_destroy(&dev->slave_mutex);

if (dev->sock != -1) {
close(dev->sock);
Expand Down Expand Up @@ -1663,6 +1678,7 @@ vu_init(VuDev *dev,
dev->remove_watch = remove_watch;
dev->iface = iface;
dev->log_call_fd = -1;
pthread_mutex_init(&dev->slave_mutex, NULL);
dev->slave_fd = -1;
dev->max_queues = max_queues;

Expand Down
3 changes: 3 additions & 0 deletions contrib/libvhost-user/libvhost-user.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <stddef.h>
#include <sys/poll.h>
#include <linux/vhost.h>
#include <pthread.h>
#include "standard-headers/linux/virtio_ring.h"

/* Based on qemu/hw/virtio/vhost-user.c */
Expand Down Expand Up @@ -355,6 +356,8 @@ struct VuDev {
VuVirtq *vq;
VuDevInflightInfo inflight_info;
int log_call_fd;
/* Must be held while using slave_fd */
pthread_mutex_t slave_mutex;
int slave_fd;
uint64_t log_size;
uint8_t *log_table;
Expand Down

0 comments on commit c25c02b

Please sign in to comment.