@@ -2,7 +2,9 @@
* Copyright(c) 2010-2014 Intel Corporation
*/
+#include <errno.h>
#include <stdio.h>
+#include <string.h>
#include <unistd.h>
#include <rte_common.h>
@@ -17,6 +19,87 @@ RTE_LOG_REGISTER_SUFFIX(vhost_fdset_logtype, fdset, INFO);
#define FDPOLLERR (POLLERR | POLLHUP | POLLNVAL)
+static void
+fdset_pipe_read_cb(int readfd, void *dat,
+ int *remove __rte_unused)
+{
+ char charbuf[16];
+ struct fdset *fdset = dat;
+ int r = read(readfd, charbuf, sizeof(charbuf));
+ /*
+ * Just an optimization, we don't care if read() failed
+ * so ignore explicitly its return value to make the
+ * compiler happy
+ */
+ RTE_SET_USED(r);
+
+ pthread_mutex_lock(&fdset->sync_mutex);
+ fdset->sync = true;
+ pthread_cond_broadcast(&fdset->sync_cond);
+ pthread_mutex_unlock(&fdset->sync_mutex);
+}
+
+static void
+fdset_pipe_uninit(struct fdset *fdset)
+{
+ fdset_del(fdset, fdset->u.readfd);
+ close(fdset->u.readfd);
+ fdset->u.readfd = -1;
+ close(fdset->u.writefd);
+ fdset->u.writefd = -1;
+}
+
+static int
+fdset_pipe_init(struct fdset *fdset)
+{
+ int ret;
+
+ pthread_mutex_init(&fdset->sync_mutex, NULL);
+ pthread_cond_init(&fdset->sync_cond, NULL);
+
+ if (pipe(fdset->u.pipefd) < 0) {
+ VHOST_FDMAN_LOG(ERR,
+ "failed to create pipe for vhost fdset");
+ return -1;
+ }
+
+ ret = fdset_add(fdset, fdset->u.readfd,
+ fdset_pipe_read_cb, NULL, fdset);
+ if (ret < 0) {
+ VHOST_FDMAN_LOG(ERR,
+ "failed to add pipe readfd %d into vhost server fdset",
+ fdset->u.readfd);
+
+ fdset_pipe_uninit(fdset);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void
+fdset_sync(struct fdset *fdset)
+{
+ int ret;
+
+ pthread_mutex_lock(&fdset->sync_mutex);
+
+ fdset->sync = false;
+ ret = write(fdset->u.writefd, "1", 1);
+ if (ret < 0) {
+ VHOST_FDMAN_LOG(ERR,
+ "Failed to write to notification pipe: %s",
+ strerror(errno));
+ goto out_unlock;
+ }
+
+ while (!fdset->sync)
+ pthread_cond_wait(&fdset->sync_cond, &fdset->sync_mutex);
+
+out_unlock:
+ pthread_mutex_unlock(&fdset->sync_mutex);
+}
+
static int
get_last_valid_idx(struct fdset *pfdset, int last_valid_idx)
{
@@ -96,6 +179,12 @@ fdset_add_fd(struct fdset *pfdset, int idx, int fd,
pfd->revents = 0;
}
+void
+fdset_uninit(struct fdset *pfdset)
+{
+ fdset_pipe_uninit(pfdset);
+}
+
int
fdset_init(struct fdset *pfdset)
{
@@ -103,8 +192,6 @@ fdset_init(struct fdset *pfdset)
pthread_mutex_init(&pfdset->fd_mutex, NULL);
pthread_mutex_init(&pfdset->fd_polling_mutex, NULL);
- pthread_mutex_init(&pfdset->sync_mutex, NULL);
- pthread_cond_init(&pfdset->sync_cond, NULL);
for (i = 0; i < MAX_FDS; i++) {
pfdset->fd[i].fd = -1;
@@ -112,7 +199,7 @@ fdset_init(struct fdset *pfdset)
}
pfdset->num = 0;
- return 0;
+ return fdset_pipe_init(pfdset);
}
/**
@@ -142,6 +229,8 @@ fdset_add(struct fdset *pfdset, int fd, fd_cb rcb, fd_cb wcb, void *dat)
fdset_add_fd(pfdset, i, fd, rcb, wcb, dat);
pthread_mutex_unlock(&pfdset->fd_mutex);
+ fdset_sync(pfdset);
+
return 0;
}
@@ -173,6 +262,8 @@ fdset_del(struct fdset *pfdset, int fd)
pthread_mutex_unlock(&pfdset->fd_mutex);
} while (i != -1);
+ fdset_sync(pfdset);
+
return dat;
}
@@ -206,6 +297,9 @@ fdset_try_del(struct fdset *pfdset, int fd)
}
pthread_mutex_unlock(&pfdset->fd_mutex);
+
+ fdset_sync(pfdset);
+
return 0;
}
@@ -311,83 +405,3 @@ fdset_event_dispatch(void *arg)
return 0;
}
-
-static void
-fdset_pipe_read_cb(int readfd, void *dat,
- int *remove __rte_unused)
-{
- char charbuf[16];
- struct fdset *fdset = dat;
- int r = read(readfd, charbuf, sizeof(charbuf));
- /*
- * Just an optimization, we don't care if read() failed
- * so ignore explicitly its return value to make the
- * compiler happy
- */
- RTE_SET_USED(r);
-
- pthread_mutex_lock(&fdset->sync_mutex);
- fdset->sync = true;
- pthread_cond_broadcast(&fdset->sync_cond);
- pthread_mutex_unlock(&fdset->sync_mutex);
-}
-
-void
-fdset_pipe_uninit(struct fdset *fdset)
-{
- fdset_del(fdset, fdset->u.readfd);
- close(fdset->u.readfd);
- close(fdset->u.writefd);
-}
-
-int
-fdset_pipe_init(struct fdset *fdset)
-{
- int ret;
-
- if (pipe(fdset->u.pipefd) < 0) {
- VHOST_FDMAN_LOG(ERR,
- "failed to create pipe for vhost fdset");
- return -1;
- }
-
- ret = fdset_add(fdset, fdset->u.readfd,
- fdset_pipe_read_cb, NULL, fdset);
-
- if (ret < 0) {
- VHOST_FDMAN_LOG(ERR,
- "failed to add pipe readfd %d into vhost server fdset",
- fdset->u.readfd);
-
- fdset_pipe_uninit(fdset);
- return -1;
- }
-
- return 0;
-}
-
-void
-fdset_pipe_notify(struct fdset *fdset)
-{
- int r = write(fdset->u.writefd, "1", 1);
- /*
- * Just an optimization, we don't care if write() failed
- * so ignore explicitly its return value to make the
- * compiler happy
- */
- RTE_SET_USED(r);
-}
-
-void
-fdset_pipe_notify_sync(struct fdset *fdset)
-{
- pthread_mutex_lock(&fdset->sync_mutex);
-
- fdset->sync = false;
- fdset_pipe_notify(fdset);
-
- while (!fdset->sync)
- pthread_cond_wait(&fdset->sync_cond, &fdset->sync_mutex);
-
- pthread_mutex_unlock(&fdset->sync_mutex);
-}
@@ -42,6 +42,7 @@ struct fdset {
bool sync;
};
+void fdset_uninit(struct fdset *pfdset);
int fdset_init(struct fdset *pfdset);
@@ -53,11 +54,4 @@ int fdset_try_del(struct fdset *pfdset, int fd);
uint32_t fdset_event_dispatch(void *arg);
-int fdset_pipe_init(struct fdset *fdset);
-
-void fdset_pipe_uninit(struct fdset *fdset);
-
-void fdset_pipe_notify(struct fdset *fdset);
-void fdset_pipe_notify_sync(struct fdset *fdset);
-
#endif
@@ -279,7 +279,6 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket)
TAILQ_INSERT_TAIL(&vsocket->conn_list, conn, next);
pthread_mutex_unlock(&vsocket->conn_mutex);
- fdset_pipe_notify(&vhost_user.fdset);
return;
err_cleanup:
@@ -1190,20 +1189,11 @@ rte_vhost_driver_start(const char *path)
return -1;
}
- /**
- * create a pipe which will be waited by poll and notified to
- * rebuild the wait list of poll.
- */
- if (fdset_pipe_init(&vhost_user.fdset) < 0) {
- VHOST_CONFIG_LOG(path, ERR, "failed to create pipe for vhost fdset");
- return -1;
- }
-
int ret = rte_thread_create_internal_control(&fdset_tid,
"vhost-evt", fdset_event_dispatch, &vhost_user.fdset);
if (ret != 0) {
VHOST_CONFIG_LOG(path, ERR, "failed to create fdset handling thread");
- fdset_pipe_uninit(&vhost_user.fdset);
+ fdset_uninit(&vhost_user.fdset);
return -1;
}
}
@@ -225,7 +225,6 @@ vduse_vring_setup(struct virtio_net *dev, unsigned int index)
close(vq->kickfd);
vq->kickfd = VIRTIO_UNINITIALIZED_EVENTFD;
}
- fdset_pipe_notify(&vduse.fdset);
vhost_enable_guest_notification(dev, vq, 1);
VHOST_CONFIG_LOG(dev->ifname, INFO, "Ctrl queue event handler installed");
}
@@ -238,10 +237,8 @@ vduse_vring_cleanup(struct virtio_net *dev, unsigned int index)
struct vduse_vq_eventfd vq_efd;
int ret;
- if (vq == dev->cvq && vq->kickfd >= 0) {
+ if (vq == dev->cvq && vq->kickfd >= 0)
fdset_del(&vduse.fdset, vq->kickfd);
- fdset_pipe_notify(&vduse.fdset);
- }
vq_efd.index = index;
vq_efd.fd = VDUSE_EVENTFD_DEASSIGN;
@@ -432,20 +429,11 @@ vduse_device_create(const char *path, bool compliant_ol_flags)
return -1;
}
- /**
- * create a pipe which will be waited by poll and notified to
- * rebuild the wait list of poll.
- */
- if (fdset_pipe_init(&vduse.fdset) < 0) {
- VHOST_CONFIG_LOG(path, ERR, "failed to create pipe for vduse fdset");
- return -1;
- }
-
ret = rte_thread_create_internal_control(&fdset_tid, "vduse-evt",
fdset_event_dispatch, &vduse.fdset);
if (ret != 0) {
VHOST_CONFIG_LOG(path, ERR, "failed to create vduse fdset handling thread");
- fdset_pipe_uninit(&vduse.fdset);
+ fdset_uninit(&vduse.fdset);
return -1;
}
@@ -573,7 +561,6 @@ vduse_device_create(const char *path, bool compliant_ol_flags)
dev->vduse_dev_fd);
goto out_dev_destroy;
}
- fdset_pipe_notify(&vduse.fdset);
free(dev_config);
@@ -616,7 +603,6 @@ vduse_device_destroy(const char *path)
vduse_device_stop(dev);
fdset_del(&vduse.fdset, dev->vduse_dev_fd);
- fdset_pipe_notify_sync(&vduse.fdset);
if (dev->vduse_dev_fd >= 0) {
close(dev->vduse_dev_fd);