From patchwork Tue Nov 24 09:00:01 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tetsuya Mukawa X-Patchwork-Id: 9083 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 7EFA88E9F; Tue, 24 Nov 2015 10:00:32 +0100 (CET) Received: from mail-pa0-f42.google.com (mail-pa0-f42.google.com [209.85.220.42]) by dpdk.org (Postfix) with ESMTP id 41B538E9D for ; Tue, 24 Nov 2015 10:00:28 +0100 (CET) Received: by pabfh17 with SMTP id fh17so16609713pab.0 for ; Tue, 24 Nov 2015 01:00:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=igel-co-jp.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=EZhAKg6+4LUzZ8jKhPrzlSoGgUdPJxuLxc1c5wr+VB0=; b=uAAp//3/SFtJn3KsNPVwXjPoZb6EAVsjEtSLea/1dO2OTT6lMUEkRHKlpFpIYWoAHz kQBKGobHxjsBQy6NRvdpdXEdSs0l3hrjkJZL5yqhB/YJbDf7dFyyifGo2ctvzMfiQbdI afWusJYN+YWsV6fP+YAjkITLjNCvCyDT1uQAjzwh9aBXg1dSNVkWAl3mBkwfAbBnOmeG R52eeL2iQzgqOGXjlRVLp4xdD9CAHscVfUIBCrPgw3g4dKNiAYH64FjJ2Uo0qzri4UUD uFPw32Uf76qM9XCYTQ44/5/Js/zTwYKkqoaxIndWwOo1yL/gjepL/G/jV9StHMDksll0 hTRw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=EZhAKg6+4LUzZ8jKhPrzlSoGgUdPJxuLxc1c5wr+VB0=; b=N8tFQ5svAXvmXow5UTzk8i3lp/4YseSkrO2irWOAjKJrkDtrvEbK7IHYC6k9v8lI35 QJxAhVqTMjV4K2QB8zTSOSR3VaqSb35XjCPIDDaKjH7DUvasJYxUVJQM2nM09dVktsXC EAfqK4aHvcy0eSJq2kR/aMFJyCuhiwaYL9vy591WvwMts9Ug6aYdicGhel7yAIbRiTn2 ujrwj2AEuqHA12j28LC8D35YEpe4HL91Tvo8tzhPxSiZl6BgR/tDpIfDUMDK8mtJRxZI L+yrQlSKEIuslYDHuMDYekXscxQMCdUbBEQhgD2qOHNYPdW3KoidmjaKaeacOVXFzx0i 04TA== X-Gm-Message-State: ALoCoQlvdQevBxIKRaMFMicnIWapsdqoNbeXSr6kbwnzUH3qOdob6UmRCafI24QmR449VkC8DNgq X-Received: by 10.98.80.20 with SMTP id e20mr20915614pfb.23.1448355627445; Tue, 24 Nov 2015 01:00:27 -0800 (PST) Received: from localhost.localdomain (napt.igel.co.jp. [219.106.231.132]) by smtp.gmail.com with ESMTPSA id py5sm13430738pbc.8.2015.11.24.01.00.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 24 Nov 2015 01:00:26 -0800 (PST) From: Tetsuya Mukawa To: dev@dpdk.org Date: Tue, 24 Nov 2015 18:00:01 +0900 Message-Id: <1448355603-21275-2-git-send-email-mukawa@igel.co.jp> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1448355603-21275-1-git-send-email-mukawa@igel.co.jp> References: <1447392031-24970-3-git-send-email-mukawa@igel.co.jp> <1448355603-21275-1-git-send-email-mukawa@igel.co.jp> Cc: yuanhan.liu@intel.com, ann.zhuangyanying@huawei.com Subject: [dpdk-dev] [PATCH v5 1/3] vhost: Add callback and private data for vhost PMD 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" The vhost PMD will be a wrapper of vhost library, but some of vhost library APIs cannot be mapped to ethdev library APIs. Becasue of this, in some cases, we still need to use vhost library APIs for a port created by the vhost PMD. Currently, when virtio device is created and destroyed, vhost library will call one of callback handlers. The vhost PMD need to use this pair of callback handlers to know which virtio devices are connected actually. Because we can register only one pair of callbacks to vhost library, if the PMD use it, DPDK applications cannot have a way to know the events. This may break legacy DPDK applications that uses vhost library. To prevent it, this patch adds one more pair of callbacks to vhost library especially for the vhost PMD. With the patch, legacy applications can use the vhost PMD even if they need additional specific handling for virtio device creation and destruction. For example, legacy application can call rte_vhost_enable_guest_notification() in callbacks to change setting. Signed-off-by: Tetsuya Mukawa Reviewed-by: Rich Lane Tested-by: Rich Lane --- lib/librte_vhost/rte_vhost_version.map | 6 +++ lib/librte_vhost/rte_virtio_net.h | 3 ++ lib/librte_vhost/vhost_user/virtio-net-user.c | 13 +++--- lib/librte_vhost/virtio-net.c | 60 +++++++++++++++++++++++++-- lib/librte_vhost/virtio-net.h | 4 +- 5 files changed, 73 insertions(+), 13 deletions(-) diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map index 3d8709e..00a9ce5 100644 --- a/lib/librte_vhost/rte_vhost_version.map +++ b/lib/librte_vhost/rte_vhost_version.map @@ -20,3 +20,9 @@ DPDK_2.1 { rte_vhost_driver_unregister; } DPDK_2.0; + +DPDK_2.2 { + global: + + rte_vhost_driver_pmd_callback_register; +} DPDK_2.1; diff --git a/lib/librte_vhost/rte_virtio_net.h b/lib/librte_vhost/rte_virtio_net.h index 5687452..3ef6e58 100644 --- a/lib/librte_vhost/rte_virtio_net.h +++ b/lib/librte_vhost/rte_virtio_net.h @@ -128,6 +128,7 @@ struct virtio_net { char ifname[IF_NAME_SZ]; /**< Name of the tap device or socket path. */ uint32_t virt_qp_nb; /**< number of queue pair we have allocated */ void *priv; /**< private context */ + void *pmd_priv; /**< private context for vhost PMD */ struct vhost_virtqueue *virtqueue[VHOST_MAX_QUEUE_PAIRS * 2]; /**< Contains all virtqueue information. */ } __rte_cache_aligned; @@ -224,6 +225,8 @@ int rte_vhost_driver_unregister(const char *dev_name); /* Register callbacks. */ int rte_vhost_driver_callback_register(struct virtio_net_device_ops const * const); +/* Register callbacks for vhost PMD (Only for internal). */ +int rte_vhost_driver_pmd_callback_register(struct virtio_net_device_ops const * const); /* Start vhost driver session blocking loop. */ int rte_vhost_driver_session_start(void); diff --git a/lib/librte_vhost/vhost_user/virtio-net-user.c b/lib/librte_vhost/vhost_user/virtio-net-user.c index d07452a..d8ae2fc 100644 --- a/lib/librte_vhost/vhost_user/virtio-net-user.c +++ b/lib/librte_vhost/vhost_user/virtio-net-user.c @@ -111,7 +111,7 @@ user_set_mem_table(struct vhost_device_ctx ctx, struct VhostUserMsg *pmsg) /* Remove from the data plane. */ if (dev->flags & VIRTIO_DEV_RUNNING) - notify_ops->destroy_device(dev); + notify_destroy_device(dev); if (dev->mem) { free_mem_region(dev); @@ -272,7 +272,7 @@ user_set_vring_kick(struct vhost_device_ctx ctx, struct VhostUserMsg *pmsg) if (virtio_is_ready(dev) && !(dev->flags & VIRTIO_DEV_RUNNING)) - notify_ops->new_device(dev); + notify_new_device(dev); } /* @@ -288,7 +288,7 @@ user_get_vring_base(struct vhost_device_ctx ctx, return -1; /* We have to stop the queue (virtio) if it is running. */ if (dev->flags & VIRTIO_DEV_RUNNING) - notify_ops->destroy_device(dev); + notify_destroy_device(dev); /* Here we are safe to get the last used index */ ops->get_vring_base(ctx, state->index, state); @@ -324,10 +324,7 @@ user_set_vring_enable(struct vhost_device_ctx ctx, "set queue enable: %d to qp idx: %d\n", enable, state->index); - if (notify_ops->vring_state_changed) { - notify_ops->vring_state_changed(dev, base_idx / VIRTIO_QNUM, - enable); - } + notify_vring_state_changed(dev, base_idx / VIRTIO_QNUM, enable); dev->virtqueue[base_idx + VIRTIO_RXQ]->enabled = enable; dev->virtqueue[base_idx + VIRTIO_TXQ]->enabled = enable; @@ -341,7 +338,7 @@ user_destroy_device(struct vhost_device_ctx ctx) struct virtio_net *dev = get_device(ctx); if (dev && (dev->flags & VIRTIO_DEV_RUNNING)) - notify_ops->destroy_device(dev); + notify_destroy_device(dev); if (dev && dev->mem) { free_mem_region(dev); diff --git a/lib/librte_vhost/virtio-net.c b/lib/librte_vhost/virtio-net.c index 8364938..dc977b7 100644 --- a/lib/librte_vhost/virtio-net.c +++ b/lib/librte_vhost/virtio-net.c @@ -65,6 +65,8 @@ struct virtio_net_config_ll { /* device ops to add/remove device to/from data core. */ struct virtio_net_device_ops const *notify_ops; +/* device ops for vhost PMD to add/remove device to/from data core. */ +struct virtio_net_device_ops const *pmd_notify_ops; /* root address of the linked list of managed virtio devices */ static struct virtio_net_config_ll *ll_root; @@ -81,6 +83,45 @@ static struct virtio_net_config_ll *ll_root; static uint64_t VHOST_FEATURES = VHOST_SUPPORTED_FEATURES; +int +notify_new_device(struct virtio_net *dev) +{ + if ((pmd_notify_ops != NULL) && (pmd_notify_ops->new_device != NULL)) { + int ret = pmd_notify_ops->new_device(dev); + + if (ret != 0) + return ret; + } + if ((notify_ops != NULL) && (notify_ops->new_device != NULL)) + return notify_ops->new_device(dev); + + return 0; +} + +void +notify_destroy_device(volatile struct virtio_net *dev) +{ + if ((pmd_notify_ops != NULL) && (pmd_notify_ops->destroy_device != NULL)) + pmd_notify_ops->destroy_device(dev); + if ((notify_ops != NULL) && (notify_ops->destroy_device != NULL)) + notify_ops->destroy_device(dev); +} + +int +notify_vring_state_changed(struct virtio_net *dev, uint16_t queue_id, int enable) +{ + if ((pmd_notify_ops != NULL) && (pmd_notify_ops->vring_state_changed != NULL)) { + int ret = pmd_notify_ops->vring_state_changed(dev, queue_id, enable); + + if (ret != 0) + return ret; + } + if ((notify_ops != NULL) && (notify_ops->vring_state_changed != NULL)) + return notify_ops->vring_state_changed(dev, queue_id, enable); + + return 0; +} + /* * Converts QEMU virtual address to Vhost virtual address. This function is * used to convert the ring addresses to our address space. @@ -393,7 +434,7 @@ destroy_device(struct vhost_device_ctx ctx) * the function to remove it from the data core. */ if ((ll_dev_cur->dev.flags & VIRTIO_DEV_RUNNING)) - notify_ops->destroy_device(&(ll_dev_cur->dev)); + notify_destroy_device(&(ll_dev_cur->dev)); ll_dev_cur = rm_config_ll_entry(ll_dev_cur, ll_dev_last); } else { @@ -451,7 +492,7 @@ reset_owner(struct vhost_device_ctx ctx) return -1; if (dev->flags & VIRTIO_DEV_RUNNING) - notify_ops->destroy_device(dev); + notify_destroy_device(dev); cleanup_device(dev, 0); reset_device(dev); @@ -809,12 +850,12 @@ set_backend(struct vhost_device_ctx ctx, struct vhost_vring_file *file) if (!(dev->flags & VIRTIO_DEV_RUNNING)) { if (((int)dev->virtqueue[VIRTIO_TXQ]->backend != VIRTIO_DEV_STOPPED) && ((int)dev->virtqueue[VIRTIO_RXQ]->backend != VIRTIO_DEV_STOPPED)) { - return notify_ops->new_device(dev); + return notify_new_device(dev); } /* Otherwise we remove it. */ } else if (file->fd == VIRTIO_DEV_STOPPED) - notify_ops->destroy_device(dev); + notify_destroy_device(dev); return 0; } @@ -898,3 +939,14 @@ rte_vhost_driver_callback_register(struct virtio_net_device_ops const * const op return 0; } + +/* + * Register ops so that we can add/remove device to data core. + */ +int +rte_vhost_driver_pmd_callback_register(struct virtio_net_device_ops const * const ops) +{ + pmd_notify_ops = ops; + + return 0; +} diff --git a/lib/librte_vhost/virtio-net.h b/lib/librte_vhost/virtio-net.h index 75fb57e..0816e71 100644 --- a/lib/librte_vhost/virtio-net.h +++ b/lib/librte_vhost/virtio-net.h @@ -37,7 +37,9 @@ #include "vhost-net.h" #include "rte_virtio_net.h" -struct virtio_net_device_ops const *notify_ops; struct virtio_net *get_device(struct vhost_device_ctx ctx); +int notify_new_device(struct virtio_net *dev); +void notify_destroy_device(volatile struct virtio_net *dev); +int notify_vring_state_changed(struct virtio_net *dev, uint16_t queue_id, int enable); #endif