From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id E067AA0C3F; Tue, 29 Jun 2021 18:12:32 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 0444041207; Tue, 29 Jun 2021 18:12:02 +0200 (CEST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by mails.dpdk.org (Postfix) with ESMTP id 0289E411F2 for ; Tue, 29 Jun 2021 18:11:57 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1624983117; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Z9QtokOZEakyrBN2qXtE6pOpzvmAV/32F6/KtWt2VaE=; b=MpYxtyatTQ6KaaKp7zQGpmQOM16EjlscPj91htESUUqg65la9liapgdncH0KJr3QFxTCD+ YTJY++7FVQjwfOB2LvqlKIUcqRDCVntPnHQnwnduUIVaDy321GHNEVJq8qtwb74PnbNRaO 93MEX7xB+I82p2eSpWAxdnTbm/g/4b0= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-573--4OLgPXbOnyuYwkobd1sIw-1; Tue, 29 Jun 2021 12:11:53 -0400 X-MC-Unique: -4OLgPXbOnyuYwkobd1sIw-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 5FD3C1835AC3; Tue, 29 Jun 2021 16:11:52 +0000 (UTC) Received: from max-t490s.redhat.com (unknown [10.36.110.32]) by smtp.corp.redhat.com (Postfix) with ESMTP id 487A65C1D1; Tue, 29 Jun 2021 16:11:51 +0000 (UTC) From: Maxime Coquelin To: dev@dpdk.org, chenbo.xia@intel.com, david.marchand@redhat.com Cc: Maxime Coquelin Date: Tue, 29 Jun 2021 18:11:32 +0200 Message-Id: <20210629161133.79472-7-maxime.coquelin@redhat.com> In-Reply-To: <20210629161133.79472-1-maxime.coquelin@redhat.com> References: <20210629161133.79472-1-maxime.coquelin@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=maxime.coquelin@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII" Subject: [dpdk-dev] [PATCH v7 6/7] vhost: allocate all data on same node as virtqueue X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" This patch saves the NUMA node the virtqueue is allocated on at init time, in order to allocate all other data on the same node. While most of the data are allocated before numa_realloc() is called and so the data will be reallocated properly, some data like the log cache are most likely allocated after. For the virtio device metadata, we decide to allocate them on the same node as the VQ 0. Signed-off-by: Maxime Coquelin Reviewed-by: Chenbo Xia --- lib/vhost/vhost.c | 34 ++++++++++++++++------------------ lib/vhost/vhost.h | 1 + lib/vhost/vhost_user.c | 41 ++++++++++++++++++++++++++++------------- 3 files changed, 45 insertions(+), 31 deletions(-) diff --git a/lib/vhost/vhost.c b/lib/vhost/vhost.c index c96f6335c8..0000cd3297 100644 --- a/lib/vhost/vhost.c +++ b/lib/vhost/vhost.c @@ -261,7 +261,7 @@ vhost_alloc_copy_ind_table(struct virtio_net *dev, struct vhost_virtqueue *vq, uint64_t src, dst; uint64_t len, remain = desc_len; - idesc = rte_malloc(__func__, desc_len, 0); + idesc = rte_malloc_socket(__func__, desc_len, 0, vq->numa_node); if (unlikely(!idesc)) return NULL; @@ -549,6 +549,7 @@ static void init_vring_queue(struct virtio_net *dev, uint32_t vring_idx) { struct vhost_virtqueue *vq; + int numa_node = SOCKET_ID_ANY; if (vring_idx >= VHOST_MAX_VRING) { VHOST_LOG_CONFIG(ERR, @@ -570,6 +571,15 @@ init_vring_queue(struct virtio_net *dev, uint32_t vring_idx) vq->callfd = VIRTIO_UNINITIALIZED_EVENTFD; vq->notif_enable = VIRTIO_UNINITIALIZED_NOTIF; +#ifdef RTE_LIBRTE_VHOST_NUMA + if (get_mempolicy(&numa_node, NULL, 0, vq, MPOL_F_NODE | MPOL_F_ADDR)) { + VHOST_LOG_CONFIG(ERR, "(%d) failed to query numa node: %s\n", + dev->vid, rte_strerror(errno)); + numa_node = SOCKET_ID_ANY; + } +#endif + vq->numa_node = numa_node; + vhost_user_iotlb_init(dev, vring_idx); } @@ -1616,7 +1626,6 @@ int rte_vhost_async_channel_register(int vid, uint16_t queue_id, struct vhost_virtqueue *vq; struct virtio_net *dev = get_device(vid); struct rte_vhost_async_features f; - int node; if (dev == NULL || ops == NULL) return -1; @@ -1651,20 +1660,9 @@ int rte_vhost_async_channel_register(int vid, uint16_t queue_id, goto reg_out; } -#ifdef RTE_LIBRTE_VHOST_NUMA - if (get_mempolicy(&node, NULL, 0, vq, MPOL_F_NODE | MPOL_F_ADDR)) { - VHOST_LOG_CONFIG(ERR, - "unable to get numa information in async register. " - "allocating async buffer memory on the caller thread node\n"); - node = SOCKET_ID_ANY; - } -#else - node = SOCKET_ID_ANY; -#endif - vq->async_pkts_info = rte_malloc_socket(NULL, vq->size * sizeof(struct async_inflight_info), - RTE_CACHE_LINE_SIZE, node); + RTE_CACHE_LINE_SIZE, vq->numa_node); if (!vq->async_pkts_info) { vhost_free_async_mem(vq); VHOST_LOG_CONFIG(ERR, @@ -1675,7 +1673,7 @@ int rte_vhost_async_channel_register(int vid, uint16_t queue_id, vq->it_pool = rte_malloc_socket(NULL, VHOST_MAX_ASYNC_IT * sizeof(struct rte_vhost_iov_iter), - RTE_CACHE_LINE_SIZE, node); + RTE_CACHE_LINE_SIZE, vq->numa_node); if (!vq->it_pool) { vhost_free_async_mem(vq); VHOST_LOG_CONFIG(ERR, @@ -1686,7 +1684,7 @@ int rte_vhost_async_channel_register(int vid, uint16_t queue_id, vq->vec_pool = rte_malloc_socket(NULL, VHOST_MAX_ASYNC_VEC * sizeof(struct iovec), - RTE_CACHE_LINE_SIZE, node); + RTE_CACHE_LINE_SIZE, vq->numa_node); if (!vq->vec_pool) { vhost_free_async_mem(vq); VHOST_LOG_CONFIG(ERR, @@ -1698,7 +1696,7 @@ int rte_vhost_async_channel_register(int vid, uint16_t queue_id, if (vq_is_packed(dev)) { vq->async_buffers_packed = rte_malloc_socket(NULL, vq->size * sizeof(struct vring_used_elem_packed), - RTE_CACHE_LINE_SIZE, node); + RTE_CACHE_LINE_SIZE, vq->numa_node); if (!vq->async_buffers_packed) { vhost_free_async_mem(vq); VHOST_LOG_CONFIG(ERR, @@ -1709,7 +1707,7 @@ int rte_vhost_async_channel_register(int vid, uint16_t queue_id, } else { vq->async_descs_split = rte_malloc_socket(NULL, vq->size * sizeof(struct vring_used_elem), - RTE_CACHE_LINE_SIZE, node); + RTE_CACHE_LINE_SIZE, vq->numa_node); if (!vq->async_descs_split) { vhost_free_async_mem(vq); VHOST_LOG_CONFIG(ERR, diff --git a/lib/vhost/vhost.h b/lib/vhost/vhost.h index 8078ddff79..8ffe387556 100644 --- a/lib/vhost/vhost.h +++ b/lib/vhost/vhost.h @@ -164,6 +164,7 @@ struct vhost_virtqueue { uint16_t batch_copy_nb_elems; struct batch_copy_elem *batch_copy_elems; + int numa_node; bool used_wrap_counter; bool avail_wrap_counter; diff --git a/lib/vhost/vhost_user.c b/lib/vhost/vhost_user.c index d6ec4000c3..d8ec087dfc 100644 --- a/lib/vhost/vhost_user.c +++ b/lib/vhost/vhost_user.c @@ -433,10 +433,10 @@ vhost_user_set_vring_num(struct virtio_net **pdev, if (vq_is_packed(dev)) { if (vq->shadow_used_packed) rte_free(vq->shadow_used_packed); - vq->shadow_used_packed = rte_malloc(NULL, + vq->shadow_used_packed = rte_malloc_socket(NULL, vq->size * sizeof(struct vring_used_elem_packed), - RTE_CACHE_LINE_SIZE); + RTE_CACHE_LINE_SIZE, vq->numa_node); if (!vq->shadow_used_packed) { VHOST_LOG_CONFIG(ERR, "failed to allocate memory for shadow used ring.\n"); @@ -447,9 +447,9 @@ vhost_user_set_vring_num(struct virtio_net **pdev, if (vq->shadow_used_split) rte_free(vq->shadow_used_split); - vq->shadow_used_split = rte_malloc(NULL, + vq->shadow_used_split = rte_malloc_socket(NULL, vq->size * sizeof(struct vring_used_elem), - RTE_CACHE_LINE_SIZE); + RTE_CACHE_LINE_SIZE, vq->numa_node); if (!vq->shadow_used_split) { VHOST_LOG_CONFIG(ERR, @@ -460,9 +460,9 @@ vhost_user_set_vring_num(struct virtio_net **pdev, if (vq->batch_copy_elems) rte_free(vq->batch_copy_elems); - vq->batch_copy_elems = rte_malloc(NULL, + vq->batch_copy_elems = rte_malloc_socket(NULL, vq->size * sizeof(struct batch_copy_elem), - RTE_CACHE_LINE_SIZE); + RTE_CACHE_LINE_SIZE, vq->numa_node); if (!vq->batch_copy_elems) { VHOST_LOG_CONFIG(ERR, "failed to allocate memory for batching copy.\n"); @@ -505,6 +505,9 @@ numa_realloc(struct virtio_net *dev, int index) return dev; } + if (node == vq->numa_node) + goto out_dev_realloc; + vq = rte_realloc_socket(vq, sizeof(*vq), 0, node); if (!vq) { VHOST_LOG_CONFIG(ERR, "Failed to realloc virtqueue %d on node %d\n", @@ -559,6 +562,10 @@ numa_realloc(struct virtio_net *dev, int index) vq->log_cache = lc; } + vq->numa_node = node; + +out_dev_realloc: + if (dev->flags & VIRTIO_DEV_RUNNING) return dev; @@ -1213,7 +1220,7 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, struct virtio_net *dev = *pdev; struct VhostUserMemory *memory = &msg->payload.memory; struct rte_vhost_mem_region *reg; - + int numa_node = SOCKET_ID_ANY; uint64_t mmap_offset; uint32_t i; @@ -1253,13 +1260,21 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, for (i = 0; i < dev->nr_vring; i++) vhost_user_iotlb_flush_all(dev->virtqueue[i]); + /* + * If VQ 0 has already been allocated, try to allocate on the same + * NUMA node. It can be reallocated later in numa_realloc(). + */ + if (dev->nr_vring > 0) + numa_node = dev->virtqueue[0]->numa_node; + dev->nr_guest_pages = 0; if (dev->guest_pages == NULL) { dev->max_guest_pages = 8; - dev->guest_pages = rte_zmalloc(NULL, + dev->guest_pages = rte_zmalloc_socket(NULL, dev->max_guest_pages * sizeof(struct guest_page), - RTE_CACHE_LINE_SIZE); + RTE_CACHE_LINE_SIZE, + numa_node); if (dev->guest_pages == NULL) { VHOST_LOG_CONFIG(ERR, "(%d) failed to allocate memory " @@ -1269,8 +1284,8 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg, } } - dev->mem = rte_zmalloc("vhost-mem-table", sizeof(struct rte_vhost_memory) + - sizeof(struct rte_vhost_mem_region) * memory->nregions, 0); + dev->mem = rte_zmalloc_socket("vhost-mem-table", sizeof(struct rte_vhost_memory) + + sizeof(struct rte_vhost_mem_region) * memory->nregions, 0, numa_node); if (dev->mem == NULL) { VHOST_LOG_CONFIG(ERR, "(%d) failed to allocate memory for dev->mem\n", @@ -2193,9 +2208,9 @@ vhost_user_set_log_base(struct virtio_net **pdev, struct VhostUserMsg *msg, rte_free(vq->log_cache); vq->log_cache = NULL; vq->log_cache_nb_elem = 0; - vq->log_cache = rte_zmalloc("vq log cache", + vq->log_cache = rte_malloc_socket("vq log cache", sizeof(struct log_cache_entry) * VHOST_LOG_CACHE_NR, - 0); + 0, vq->numa_node); /* * If log cache alloc fail, don't fail migration, but no * caching will be done, which will impact performance -- 2.31.1