From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id 893BD2C02 for ; Sat, 1 Apr 2017 09:25:55 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=intel.com; i=@intel.com; q=dns/txt; s=intel; t=1491031555; x=1522567555; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=GnFjSC3pS+uKTz2ulZF5bgO1so16xqIkvxxYblx1eAA=; b=PbsF8Wt8wapcmLlCV5PUVd3Eo17SK/ADyqkn7vf7ysW4YxXFTWLjXnIv O24iKZZZUGUq6gnjPIocXb1Zwg6VvQ==; Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Apr 2017 00:25:51 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,256,1486454400"; d="scan'208";a="67700696" Received: from yliu-dev.sh.intel.com ([10.239.67.162]) by orsmga002.jf.intel.com with ESMTP; 01 Apr 2017 00:25:45 -0700 From: Yuanhan Liu To: dev@dpdk.org Cc: Maxime Coquelin , Harris James R , Liu Changpeng , Yuanhan Liu Date: Sat, 1 Apr 2017 15:22:55 +0800 Message-Id: <1491031380-1499-18-git-send-email-yuanhan.liu@linux.intel.com> X-Mailer: git-send-email 1.9.0 In-Reply-To: <1491031380-1499-1-git-send-email-yuanhan.liu@linux.intel.com> References: <1490705142-893-1-git-send-email-yuanhan.liu@linux.intel.com> <1491031380-1499-1-git-send-email-yuanhan.liu@linux.intel.com> Subject: [dpdk-dev] [PATCH v4 17/22] vhost: export APIs for live migration support 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: Sat, 01 Apr 2017 07:25:56 -0000 Export few APIs for the vhost-user driver to log the guest memory writes, which is a must for live migration support. This patch basically moves vhost_log_write() and vhost_log_used_vring() into vhost.h and then add an wrapper (the public API) to them. Signed-off-by: Yuanhan Liu Reviewed-by: Maxime Coquelin --- lib/librte_vhost/rte_vhost_version.map | 2 ++ lib/librte_vhost/rte_virtio_net.h | 43 ++++++++++++++++++++++++++++++++++ lib/librte_vhost/vhost.c | 31 ++++++++++++++++++++++++ lib/librte_vhost/vhost.h | 38 ++++++++++++++++++++++++++++++ lib/librte_vhost/virtio_net.c | 36 ---------------------------- 5 files changed, 114 insertions(+), 36 deletions(-) diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map index 8df14dc..f4b74da 100644 --- a/lib/librte_vhost/rte_vhost_version.map +++ b/lib/librte_vhost/rte_vhost_version.map @@ -41,5 +41,7 @@ DPDK_17.05 { rte_vhost_get_vhost_vring; rte_vhost_get_vring_num; rte_vhost_gpa_to_vva; + rte_vhost_log_used_vring; + rte_vhost_log_write; } DPDK_16.07; diff --git a/lib/librte_vhost/rte_virtio_net.h b/lib/librte_vhost/rte_virtio_net.h index ec52a9b..7a08bbf 100644 --- a/lib/librte_vhost/rte_virtio_net.h +++ b/lib/librte_vhost/rte_virtio_net.h @@ -132,6 +132,49 @@ static inline uint64_t __attribute__((always_inline)) return 0; } +#define RTE_VHOST_NEED_LOG(features) ((features) & (1ULL << VHOST_F_LOG_ALL)) + +/** + * Log the memory write start with given address. + * + * This function only need be invoked when the live migration starts. + * Therefore, we won't need call it at all in the most of time. For + * making the performance impact be minimum, it's suggested to do a + * check before calling it: + * + * if (unlikely(RTE_VHOST_NEED_LOG(features))) + * rte_vhost_log_write(vid, addr, len); + * + * @param vid + * vhost device ID + * @param addr + * the starting address for write + * @param len + * the length to write + */ +void rte_vhost_log_write(int vid, uint64_t addr, uint64_t len); + +/** + * Log the used ring update start at given offset. + * + * Same as rte_vhost_log_write, it's suggested to do a check before + * calling it: + * + * if (unlikely(RTE_VHOST_NEED_LOG(features))) + * rte_vhost_log_used_vring(vid, vring_idx, offset, len); + * + * @param vid + * vhost device ID + * @param vring_idx + * the vring index + * @param offset + * the offset inside the used ring + * @param len + * the length to write + */ +void rte_vhost_log_used_vring(int vid, uint16_t vring_idx, + uint64_t offset, uint64_t len); + int rte_vhost_enable_guest_notification(int vid, uint16_t queue_id, int enable); /** diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c index d57d4b2..59de2ea 100644 --- a/lib/librte_vhost/vhost.c +++ b/lib/librte_vhost/vhost.c @@ -444,3 +444,34 @@ struct virtio_net * dev->virtqueue[queue_id]->used->flags = VRING_USED_F_NO_NOTIFY; return 0; } + +void +rte_vhost_log_write(int vid, uint64_t addr, uint64_t len) +{ + struct virtio_net *dev = get_device(vid); + + if (dev == NULL) + return; + + vhost_log_write(dev, addr, len); +} + +void +rte_vhost_log_used_vring(int vid, uint16_t vring_idx, + uint64_t offset, uint64_t len) +{ + struct virtio_net *dev; + struct vhost_virtqueue *vq; + + dev = get_device(vid); + if (dev == NULL) + return; + + if (vring_idx >= VHOST_MAX_VRING) + return; + vq = dev->virtqueue[vring_idx]; + if (!vq) + return; + + vhost_log_used_vring(dev, vq, offset, len); +} diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h index 225ff2e..a199ee6 100644 --- a/lib/librte_vhost/vhost.h +++ b/lib/librte_vhost/vhost.h @@ -198,6 +198,44 @@ struct virtio_net { struct guest_page *guest_pages; } __rte_cache_aligned; + +#define VHOST_LOG_PAGE 4096 + +static inline void __attribute__((always_inline)) +vhost_log_page(uint8_t *log_base, uint64_t page) +{ + log_base[page / 8] |= 1 << (page % 8); +} + +static inline void __attribute__((always_inline)) +vhost_log_write(struct virtio_net *dev, uint64_t addr, uint64_t len) +{ + uint64_t page; + + if (likely(((dev->features & (1ULL << VHOST_F_LOG_ALL)) == 0) || + !dev->log_base || !len)) + return; + + if (unlikely(dev->log_size <= ((addr + len - 1) / VHOST_LOG_PAGE / 8))) + return; + + /* To make sure guest memory updates are committed before logging */ + rte_smp_wmb(); + + page = addr / VHOST_LOG_PAGE; + while (page * VHOST_LOG_PAGE < addr + len) { + vhost_log_page((uint8_t *)(uintptr_t)dev->log_base, page); + page += 1; + } +} + +static inline void __attribute__((always_inline)) +vhost_log_used_vring(struct virtio_net *dev, struct vhost_virtqueue *vq, + uint64_t offset, uint64_t len) +{ + vhost_log_write(dev, vq->log_guest_addr + offset, len); +} + /* Macros for printing using RTE_LOG */ #define RTE_LOGTYPE_VHOST_CONFIG RTE_LOGTYPE_USER1 #define RTE_LOGTYPE_VHOST_DATA RTE_LOGTYPE_USER1 diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c index 28542cf..fc336d9 100644 --- a/lib/librte_vhost/virtio_net.c +++ b/lib/librte_vhost/virtio_net.c @@ -48,42 +48,6 @@ #include "vhost.h" #define MAX_PKT_BURST 32 -#define VHOST_LOG_PAGE 4096 - -static inline void __attribute__((always_inline)) -vhost_log_page(uint8_t *log_base, uint64_t page) -{ - log_base[page / 8] |= 1 << (page % 8); -} - -static inline void __attribute__((always_inline)) -vhost_log_write(struct virtio_net *dev, uint64_t addr, uint64_t len) -{ - uint64_t page; - - if (likely(((dev->features & (1ULL << VHOST_F_LOG_ALL)) == 0) || - !dev->log_base || !len)) - return; - - if (unlikely(dev->log_size <= ((addr + len - 1) / VHOST_LOG_PAGE / 8))) - return; - - /* To make sure guest memory updates are committed before logging */ - rte_smp_wmb(); - - page = addr / VHOST_LOG_PAGE; - while (page * VHOST_LOG_PAGE < addr + len) { - vhost_log_page((uint8_t *)(uintptr_t)dev->log_base, page); - page += 1; - } -} - -static inline void __attribute__((always_inline)) -vhost_log_used_vring(struct virtio_net *dev, struct vhost_virtqueue *vq, - uint64_t offset, uint64_t len) -{ - vhost_log_write(dev, vq->log_guest_addr + offset, len); -} static bool is_valid_virt_queue_idx(uint32_t idx, int is_tx, uint32_t nr_vring) -- 1.9.0