From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by dpdk.space (Postfix) with ESMTP id 392CDA0471 for ; Wed, 19 Jun 2019 17:18:42 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 3EF601C3D3; Wed, 19 Jun 2019 17:16:05 +0200 (CEST) Received: from mx0.arrikto.com (mx0.arrikto.com [212.71.252.59]) by dpdk.org (Postfix) with ESMTP id 112FD1C38F for ; Wed, 19 Jun 2019 17:15:40 +0200 (CEST) Received: from troi.prod.arr (mail.arr [10.99.0.5]) by mx0.arrikto.com (Postfix) with ESMTP id D694618200F; Wed, 19 Jun 2019 18:15:39 +0300 (EEST) Received: from localhost.localdomain (unknown [10.89.50.133]) by troi.prod.arr (Postfix) with ESMTPSA id 3B12C394; Wed, 19 Jun 2019 18:15:39 +0300 (EEST) From: Nikos Dragazis To: dev@dpdk.org Cc: Maxime Coquelin , Tiwei Bie , Zhihong Wang , Stefan Hajnoczi , Wei Wang , Stojaczyk Dariusz , Vangelis Koukis Date: Wed, 19 Jun 2019 18:14:35 +0300 Message-Id: <1560957293-17294-11-git-send-email-ndragazis@arrikto.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1560957293-17294-1-git-send-email-ndragazis@arrikto.com> References: <1560957293-17294-1-git-send-email-ndragazis@arrikto.com> Subject: [dpdk-dev] [PATCH 10/28] vhost: use a single structure for the device state 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: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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: Nikos Dragazis Signed-off-by: Stefan Hajnoczi --- lib/librte_vhost/trans_af_unix.c | 60 +++++++++++++++------------------------- lib/librte_vhost/vhost.c | 12 ++++---- lib/librte_vhost/vhost.h | 11 +++++++- 3 files changed, 40 insertions(+), 43 deletions(-) diff --git a/lib/librte_vhost/trans_af_unix.c b/lib/librte_vhost/trans_af_unix.c index 865d862..7e119b4 100644 --- a/lib/librte_vhost/trans_af_unix.c +++ b/lib/librte_vhost/trans_af_unix.c @@ -26,9 +26,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; }; @@ -153,7 +153,7 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket) { struct af_unix_socket *af_vsocket = container_of(vsocket, struct af_unix_socket, socket); - int vid; + struct virtio_net *dev; size_t size; struct vhost_user_connection *conn; int ret; @@ -161,42 +161,37 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket) if (vsocket == NULL) return; - 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); - vhost_set_builtin_virtio_net(vid, vsocket->use_builtin_virtio_net); + vhost_set_builtin_virtio_net(dev->vid, vsocket->use_builtin_virtio_net); - vhost_attach_vdpa_device(vid, vsocket->vdpa_dev_id); + vhost_attach_vdpa_device(dev->vid, vsocket->vdpa_dev_id); 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", fd); - goto err_cleanup; + goto err; } } - 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) { @@ -205,9 +200,9 @@ 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_cleanup; + goto err; } pthread_mutex_lock(&af_vsocket->conn_mutex); @@ -217,11 +212,9 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket) fdset_pipe_notify(&af_unix_fdset); return; -err_cleanup: - vhost_destroy_device(vid); err: - free(conn); - close(fd); + close(conn->connfd); + vhost_destroy_device(dev->vid); } /* call back when there is new vhost-user connection from client */ @@ -247,26 +240,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) { - struct virtio_net *dev = get_device(conn->vid); - close(connfd); *remove = 1; - if (dev) - vhost_destroy_device_notify(dev); - if (vsocket->notify_ops->destroy_connection) - vsocket->notify_ops->destroy_connection(conn->vid); - - vhost_destroy_device(conn->vid); + vsocket->notify_ops->destroy_connection(conn->device.vid); pthread_mutex_lock(&af_vsocket->conn_mutex); TAILQ_REMOVE(&af_vsocket->conn_list, conn, next); pthread_mutex_unlock(&af_vsocket->conn_mutex); - free(conn); + vhost_destroy_device(conn->device.vid); if (vsocket->reconnect) { create_unix_socket(vsocket); @@ -594,9 +580,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(&af_vsocket->conn_list, conn, next); - free(conn); + vhost_destroy_device(conn->device.vid); } pthread_mutex_unlock(&af_vsocket->conn_mutex); @@ -648,6 +633,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 a72edf3..0fdc54f 100644 --- a/lib/librte_vhost/vhost.c +++ b/lib/librte_vhost/vhost.c @@ -7,6 +7,7 @@ #include #include #include +#include #ifdef RTE_LIBRTE_VHOST_NUMA #include #include @@ -479,7 +480,7 @@ 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; @@ -493,14 +494,15 @@ vhost_new_device(const struct vhost_transport_ops *trans_ops) if (i == MAX_VHOST_DEVICE) { RTE_LOG(ERR, VHOST_CONFIG, "Failed to find a free slot for new device.\n"); - return -1; + return NULL; } - dev = rte_zmalloc(NULL, sizeof(struct virtio_net), 0); + assert(trans_ops->device_size >= sizeof(struct virtio_net)); + 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; } vhost_devices[i] = dev; @@ -512,7 +514,7 @@ vhost_new_device(const struct vhost_transport_ops *trans_ops) dev->postcopy_ufd = -1; rte_spinlock_init(&dev->slave_req_lock); - return i; + return dev; } void diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h index 0831b27..b9e4df1 100644 --- a/lib/librte_vhost/vhost.h +++ b/lib/librte_vhost/vhost.h @@ -298,6 +298,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 @@ -356,6 +359,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 */ @@ -568,7 +576,8 @@ get_device(int vid) return dev; } -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); -- 2.7.4