From patchwork Mon Jan 26 03:20:31 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Huawei Xie X-Patchwork-Id: 2505 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id E86E65A7D; Mon, 26 Jan 2015 04:21:31 +0100 (CET) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id E17F05A9E for ; Mon, 26 Jan 2015 04:21:08 +0100 (CET) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga103.fm.intel.com with ESMTP; 25 Jan 2015 19:15:06 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.09,466,1418112000"; d="scan'208";a="667415709" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by fmsmga002.fm.intel.com with ESMTP; 25 Jan 2015 19:21:06 -0800 Received: from shecgisg003.sh.intel.com (shecgisg003.sh.intel.com [10.239.29.90]) by shvmail01.sh.intel.com with ESMTP id t0Q3L3cF013359; Mon, 26 Jan 2015 11:21:03 +0800 Received: from shecgisg003.sh.intel.com (localhost [127.0.0.1]) by shecgisg003.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id t0Q3L1Oe029018; Mon, 26 Jan 2015 11:21:03 +0800 Received: (from hxie5@localhost) by shecgisg003.sh.intel.com (8.13.6/8.13.6/Submit) id t0Q3L1Aq029014; Mon, 26 Jan 2015 11:21:01 +0800 From: Huawei Xie To: dev@dpdk.org Date: Mon, 26 Jan 2015 11:20:31 +0800 Message-Id: <1422242440-28948-6-git-send-email-huawei.xie@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1422242440-28948-1-git-send-email-huawei.xie@intel.com> References: <1422242440-28948-1-git-send-email-huawei.xie@intel.com> Subject: [dpdk-dev] [RFC PATCH v2 05/14] implement eventfd copying(from fd in qemu process to fd in vhost process) in vhost-net-cdev.c X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Signed-off-by: Huawei Xie --- lib/librte_vhost/vhost_cuse/vhost-net-cdev.c | 85 ++++++++++++++++++++++++---- lib/librte_vhost/virtio-net.c | 57 +------------------ 2 files changed, 77 insertions(+), 65 deletions(-) diff --git a/lib/librte_vhost/vhost_cuse/vhost-net-cdev.c b/lib/librte_vhost/vhost_cuse/vhost-net-cdev.c index 2bb07af..802c7dc 100644 --- a/lib/librte_vhost/vhost_cuse/vhost-net-cdev.c +++ b/lib/librte_vhost/vhost_cuse/vhost-net-cdev.c @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include #include @@ -45,6 +47,7 @@ #include #include "vhost-net.h" +#include "eventfd_link/eventfd_link.h" #define FUSE_OPT_DUMMY "\0\0" #define FUSE_OPT_FORE "-f\0\0" @@ -54,6 +57,7 @@ static const uint32_t default_major = 231; static const uint32_t default_minor = 1; static const char cuse_device_name[] = "/dev/cuse"; static const char default_cdev[] = "vhost-net"; +static const char eventfd_cdev[] = "/dev/eventfd-link"; static struct fuse_session *session; static struct vhost_net_device_ops const *ops; @@ -173,6 +177,47 @@ vhost_net_release(fuse_req_t req, struct fuse_file_info *fi) } while (0) /* + * This function uses the eventfd_link kernel module to copy an eventfd file + * descriptor provided by QEMU in to our process space. + */ +static int +eventfd_copy(int target_fd, int target_pid) +{ + int eventfd_link, ret; + struct eventfd_copy eventfd_copy; + int fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); + + if (fd == -1) + return -1; + + /* Open the character device to the kernel module. */ + /* TODO: check this earlier rather than fail until VM boots! */ + eventfd_link = open(eventfd_cdev, O_RDWR); + if (eventfd_link < 0) { + RTE_LOG(ERR, VHOST_CONFIG, + "eventfd_link module is not loaded\n"); + close(fd); + return -1; + } + + eventfd_copy.source_fd = fd; + eventfd_copy.target_fd = target_fd; + eventfd_copy.target_pid = target_pid; + /* Call the IOCTL to copy the eventfd. */ + ret = ioctl(eventfd_link, EVENTFD_COPY, &eventfd_copy); + close(eventfd_link); + + if (ret < 0) { + RTE_LOG(ERR, VHOST_CONFIG, + "EVENTFD_COPY ioctl failed\n"); + close(fd); + return -1; + } + + return fd; +} + +/* * The IOCTLs are handled using CUSE/FUSE in userspace. Depending on the type * of IOCTL a buffer is requested to read or to write. This request is handled * by FUSE and the buffer is then given to CUSE. @@ -284,17 +329,37 @@ vhost_net_ioctl(fuse_req_t req, int cmd, void *arg, break; case VHOST_SET_VRING_KICK: - LOG_DEBUG(VHOST_CONFIG, - "(%"PRIu64") IOCTL: VHOST_SET_VRING_KICK\n", ctx.fh); - VHOST_IOCTL_R(struct vhost_vring_file, file, - ops->set_vring_kick); - break; - case VHOST_SET_VRING_CALL: - LOG_DEBUG(VHOST_CONFIG, - "(%"PRIu64") IOCTL: VHOST_SET_VRING_CALL\n", ctx.fh); - VHOST_IOCTL_R(struct vhost_vring_file, file, - ops->set_vring_call); + if (cmd == VHOST_SET_VRING_KICK) + LOG_DEBUG(VHOST_CONFIG, + "(%"PRIu64") IOCTL: VHOST_SET_VRING_KICK\n", + ctx.fh); + else + LOG_DEBUG(VHOST_CONFIG, + "(%"PRIu64") IOCTL: VHOST_SET_VRING_CALL\n", + ctx.fh); + if (!in_buf) + VHOST_IOCTL_RETRY(sizeof(struct vhost_vring_file), 0); + else { + int fd; + file = *(const struct vhost_vring_file *)in_buf; + LOG_DEBUG(VHOST_CONFIG, + "idx:%d fd:%d\n", file.index, file.fd); + fd = eventfd_copy(file.fd, ctx.pid); + if (fd < 0) { + fuse_reply_ioctl(req, -1, NULL, 0); + result = -1; + break; + } + file.fd = fd; + if (cmd == VHOST_SET_VRING_KICK) { + result = ops->set_vring_kick(ctx, &file); + fuse_reply_ioctl(req, result, NULL, 0); + } else { + result = ops->set_vring_call(ctx, &file); + fuse_reply_ioctl(req, result, NULL, 0); + } + } break; default: diff --git a/lib/librte_vhost/virtio-net.c b/lib/librte_vhost/virtio-net.c index 6bc9d51..da9e3a6 100644 --- a/lib/librte_vhost/virtio-net.c +++ b/lib/librte_vhost/virtio-net.c @@ -38,8 +38,6 @@ #include #include #include -#include -#include #include #include @@ -54,7 +52,6 @@ #include #include "vhost-net.h" -#include "eventfd_link/eventfd_link.h" /* * Device linked list structure for configuration. @@ -64,8 +61,6 @@ struct virtio_net_config_ll { struct virtio_net_config_ll *next; /* Next dev on linked list.*/ }; -const char eventfd_cdev[] = "/dev/eventfd-link"; - /* device ops to add/remove device to/from data core. */ static struct virtio_net_device_ops const *notify_ops; /* root address of the linked list of managed virtio devices */ @@ -904,37 +899,6 @@ get_vring_base(struct vhost_device_ctx ctx, uint32_t index, return 0; } -/* - * This function uses the eventfd_link kernel module to copy an eventfd file - * descriptor provided by QEMU in to our process space. - */ -static int -eventfd_copy(struct virtio_net *dev, struct eventfd_copy *eventfd_copy) -{ - int eventfd_link, ret; - - /* Open the character device to the kernel module. */ - eventfd_link = open(eventfd_cdev, O_RDWR); - if (eventfd_link < 0) { - RTE_LOG(ERR, VHOST_CONFIG, - "(%"PRIu64") eventfd_link module is not loaded\n", - dev->device_fh); - return -1; - } - - /* Call the IOCTL to copy the eventfd. */ - ret = ioctl(eventfd_link, EVENTFD_COPY, eventfd_copy); - close(eventfd_link); - - if (ret < 0) { - RTE_LOG(ERR, VHOST_CONFIG, - "(%"PRIu64") EVENTFD_COPY ioctl failed\n", - dev->device_fh); - return -1; - } - - return 0; -} /* * Called from CUSE IOCTL: VHOST_SET_VRING_CALL @@ -945,7 +909,6 @@ static int set_vring_call(struct vhost_device_ctx ctx, struct vhost_vring_file *file) { struct virtio_net *dev; - struct eventfd_copy eventfd_kick; struct vhost_virtqueue *vq; dev = get_device(ctx); @@ -958,14 +921,7 @@ set_vring_call(struct vhost_device_ctx ctx, struct vhost_vring_file *file) if (vq->kickfd) close((int)vq->kickfd); - /* Populate the eventfd_copy structure and call eventfd_copy. */ - vq->kickfd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); - eventfd_kick.source_fd = vq->kickfd; - eventfd_kick.target_fd = file->fd; - eventfd_kick.target_pid = ctx.pid; - - if (eventfd_copy(dev, &eventfd_kick)) - return -1; + vq->kickfd = file->fd; return 0; } @@ -979,7 +935,6 @@ static int set_vring_kick(struct vhost_device_ctx ctx, struct vhost_vring_file *file) { struct virtio_net *dev; - struct eventfd_copy eventfd_call; struct vhost_virtqueue *vq; dev = get_device(ctx); @@ -991,15 +946,7 @@ set_vring_kick(struct vhost_device_ctx ctx, struct vhost_vring_file *file) if (vq->callfd) close((int)vq->callfd); - - /* Populate the eventfd_copy structure and call eventfd_copy. */ - vq->callfd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); - eventfd_call.source_fd = vq->callfd; - eventfd_call.target_fd = file->fd; - eventfd_call.target_pid = ctx.pid; - - if (eventfd_copy(dev, &eventfd_call)) - return -1; + vq->callfd = file->fd; return 0; }