From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by dpdk.org (Postfix) with ESMTP id 415141B2E6 for ; Fri, 19 Jan 2018 14:46:22 +0100 (CET) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A2B7F2DACE5; Fri, 19 Jan 2018 13:46:21 +0000 (UTC) Received: from localhost (ovpn-116-254.ams2.redhat.com [10.36.116.254]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8207F5D6B2; Fri, 19 Jan 2018 13:46:10 +0000 (UTC) From: Stefan Hajnoczi To: dev@dpdk.org Cc: maxime.coquelin@redhat.com, Yuanhan Liu , wei.w.wang@intel.com, mst@redhat.com, zhiyong.yang@intel.com, jasowang@redhat.com, Stefan Hajnoczi Date: Fri, 19 Jan 2018 13:44:30 +0000 Message-Id: <20180119134444.24927-11-stefanha@redhat.com> In-Reply-To: <20180119134444.24927-1-stefanha@redhat.com> References: <20180119134444.24927-1-stefanha@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Fri, 19 Jan 2018 13:46:21 +0000 (UTC) Subject: [dpdk-dev] [RFC 10/24] vhost: embed struct virtio_net inside struct vhost_user_connection X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 19 Jan 2018 13:46:22 -0000 There is a 1:1 relationship between struct virtio_net and struct vhost_user_connection. They share the same lifetime. struct virtio_net is the per-device state that is part of the vhost.h API. struct vhost_user_connection is the AF_UNIX-specific per-device state and is private to trans_af_unix.c. It will be necessary to go between these two structs. This patch embeds struct virtio_net within struct vhost_user_connection so that AF_UNIX transport code can convert a struct virtio_net pointer into a struct vhost_user_connection pointer. There is now just a single malloc/free for both of these structs together. Signed-off-by: Stefan Hajnoczi --- lib/librte_vhost/vhost.h | 11 +++++++++- lib/librte_vhost/trans_af_unix.c | 44 +++++++++++++++++----------------------- lib/librte_vhost/vhost.c | 10 ++++----- 3 files changed, 34 insertions(+), 31 deletions(-) diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h index ca7507284..757e18391 100644 --- a/lib/librte_vhost/vhost.h +++ b/lib/librte_vhost/vhost.h @@ -211,6 +211,9 @@ struct vhost_transport_ops { /** Size of struct vhost_user_socket-derived per-socket state */ size_t socket_size; + /** Size of struct virtio_net-derived per-device state */ + size_t device_size; + /** * Initialize a vhost-user socket that is being created by * rte_vhost_driver_register(). This function checks that the flags @@ -269,6 +272,11 @@ extern const struct vhost_transport_ops af_unix_trans_ops; /** * Device structure contains all configuration information relating * to the device. + * + * Transport-specific per-device state can be kept by embedding this struct at + * the beginning of a transport-specific struct. Set + * vhost_transport_ops->device_size to the size of the transport-specific + * struct. */ struct virtio_net { /* Frontend (QEMU) memory and memory region information */ @@ -434,7 +442,8 @@ gpa_to_hpa(struct virtio_net *dev, uint64_t gpa, uint64_t size) struct virtio_net *get_device(int vid); -int vhost_new_device(const struct vhost_transport_ops *trans_ops); +struct virtio_net * +vhost_new_device(const struct vhost_transport_ops *trans_ops); void cleanup_device(struct virtio_net *dev, int destroy); void reset_device(struct virtio_net *dev); void vhost_destroy_device(int); diff --git a/lib/librte_vhost/trans_af_unix.c b/lib/librte_vhost/trans_af_unix.c index c85a162e8..dde3e76cd 100644 --- a/lib/librte_vhost/trans_af_unix.c +++ b/lib/librte_vhost/trans_af_unix.c @@ -54,9 +54,9 @@ static struct fdset af_unix_fdset = { TAILQ_HEAD(vhost_user_connection_list, vhost_user_connection); struct vhost_user_connection { + struct virtio_net device; /* must be the first field! */ struct vhost_user_socket *vsocket; int connfd; - int vid; TAILQ_ENTRY(vhost_user_connection) next; }; @@ -165,32 +165,30 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket) { struct af_unix_socket *s = container_of(vsocket, struct af_unix_socket, socket); - int vid; size_t size; + struct virtio_net *dev; struct vhost_user_connection *conn; int ret; - conn = malloc(sizeof(*conn)); - if (conn == NULL) { - close(fd); + dev = vhost_new_device(vsocket->trans_ops); + if (!dev) { return; } - vid = vhost_new_device(vsocket->trans_ops); - if (vid == -1) { - goto err; - } + conn = container_of(dev, struct vhost_user_connection, device); + conn->connfd = fd; + conn->vsocket = vsocket; size = strnlen(vsocket->path, PATH_MAX); - vhost_set_ifname(vid, vsocket->path, size); + vhost_set_ifname(dev->vid, vsocket->path, size); if (vsocket->dequeue_zero_copy) - vhost_enable_dequeue_zero_copy(vid); + vhost_enable_dequeue_zero_copy(dev->vid); - RTE_LOG(INFO, VHOST_CONFIG, "new device, handle is %d\n", vid); + RTE_LOG(INFO, VHOST_CONFIG, "new device, handle is %d\n", dev->vid); if (vsocket->notify_ops->new_connection) { - ret = vsocket->notify_ops->new_connection(vid); + ret = vsocket->notify_ops->new_connection(dev->vid); if (ret < 0) { RTE_LOG(ERR, VHOST_CONFIG, "failed to add vhost user connection with fd %d\n", @@ -199,9 +197,6 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket) } } - conn->connfd = fd; - conn->vsocket = vsocket; - conn->vid = vid; ret = fdset_add(&af_unix_fdset, fd, vhost_user_read_cb, NULL, conn); if (ret < 0) { @@ -210,7 +205,7 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket) fd); if (vsocket->notify_ops->destroy_connection) - vsocket->notify_ops->destroy_connection(conn->vid); + vsocket->notify_ops->destroy_connection(dev->vid); goto err; } @@ -221,8 +216,8 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket) return; err: - free(conn); - close(fd); + close(conn->connfd); + vhost_destroy_device(dev->vid); } /* call back when there is new vhost-user connection from client */ @@ -248,20 +243,19 @@ vhost_user_read_cb(int connfd, void *dat, int *remove) container_of(vsocket, struct af_unix_socket, socket); int ret; - ret = vhost_user_msg_handler(conn->vid, connfd); + ret = vhost_user_msg_handler(conn->device.vid, connfd); if (ret < 0) { close(connfd); *remove = 1; - vhost_destroy_device(conn->vid); if (vsocket->notify_ops->destroy_connection) - vsocket->notify_ops->destroy_connection(conn->vid); + vsocket->notify_ops->destroy_connection(conn->device.vid); pthread_mutex_lock(&s->conn_mutex); TAILQ_REMOVE(&s->conn_list, conn, next); pthread_mutex_unlock(&s->conn_mutex); - free(conn); + vhost_destroy_device(conn->device.vid); if (vsocket->reconnect) { create_unix_socket(vsocket); @@ -576,9 +570,8 @@ af_unix_socket_cleanup(struct vhost_user_socket *vsocket) "free connfd = %d for device '%s'\n", conn->connfd, vsocket->path); close(conn->connfd); - vhost_destroy_device(conn->vid); TAILQ_REMOVE(&s->conn_list, conn, next); - free(conn); + vhost_destroy_device(conn->device.vid); } pthread_mutex_unlock(&s->conn_mutex); @@ -615,6 +608,7 @@ af_unix_vring_call(struct virtio_net *dev __rte_unused, const struct vhost_transport_ops af_unix_trans_ops = { .socket_size = sizeof(struct af_unix_socket), + .device_size = sizeof(struct vhost_user_connection), .socket_init = af_unix_socket_init, .socket_cleanup = af_unix_socket_cleanup, .socket_start = af_unix_socket_start, diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c index f8754e261..1168e137e 100644 --- a/lib/librte_vhost/vhost.c +++ b/lib/librte_vhost/vhost.c @@ -260,17 +260,17 @@ reset_device(struct virtio_net *dev) * Invoked when there is a new vhost-user connection established (when * there is a new virtio device being attached). */ -int +struct virtio_net * vhost_new_device(const struct vhost_transport_ops *trans_ops) { struct virtio_net *dev; int i; - dev = rte_zmalloc(NULL, sizeof(struct virtio_net), 0); + dev = rte_zmalloc(NULL, trans_ops->device_size, 0); if (dev == NULL) { RTE_LOG(ERR, VHOST_CONFIG, "Failed to allocate memory for new dev.\n"); - return -1; + return NULL; } for (i = 0; i < MAX_VHOST_DEVICE; i++) { @@ -281,7 +281,7 @@ vhost_new_device(const struct vhost_transport_ops *trans_ops) RTE_LOG(ERR, VHOST_CONFIG, "Failed to find a free slot for new device.\n"); rte_free(dev); - return -1; + return NULL; } vhost_devices[i] = dev; @@ -289,7 +289,7 @@ vhost_new_device(const struct vhost_transport_ops *trans_ops) dev->slave_req_fd = -1; dev->trans_ops = trans_ops; - return i; + return dev; } /* -- 2.14.3