From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 60F87C433EF for ; Sun, 26 Jun 2022 09:04:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234100AbiFZJEY (ORCPT ); Sun, 26 Jun 2022 05:04:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43358 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229550AbiFZJEW (ORCPT ); Sun, 26 Jun 2022 05:04:22 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id CD8A1EE04 for ; Sun, 26 Jun 2022 02:04:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1656234260; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=S9HmucARGH4U51xZGz2NUlyf6+GRMYlD6t9LRB32Dik=; b=WnJhyS/r9i8FZ1mTHmwT9CDd4guvbDRHp7FwEzmBIXDlZOwEtH8iHsNoUB3zTRMPQ1JKyL +JkXFmkQDu0AhvSK1K4wWhF3lETPAmTswRKwCh4LjmivbmcQhPY6RdJ6pMh7z1JtpXds0L GAhl041V3iK1foOzfNg/W3ciHgjjFmE= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-306-lyOwNRFaN5e0Zdk0w4EVVw-1; Sun, 26 Jun 2022 05:04:17 -0400 X-MC-Unique: lyOwNRFaN5e0Zdk0w4EVVw-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 736221C05EB0; Sun, 26 Jun 2022 09:04:17 +0000 (UTC) Received: from server.redhat.com (ovpn-12-26.pek2.redhat.com [10.72.12.26]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2A9DD1131D; Sun, 26 Jun 2022 09:04:14 +0000 (UTC) From: Cindy Lu To: mst@redhat.com, jasowang@redhat.com, lulu@redhat.com, virtualization@lists.linux-foundation.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 1/2] vhost: Add rbtree vdpa_mem_tree to saved the counted mem Date: Sun, 26 Jun 2022 17:04:08 +0800 Message-Id: <20220626090409.1011144-1-lulu@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org We count pinned_vm as follow in vhost-vDPA lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; if (npages + atomic64_read(&dev->mm->pinned_vm) > lock_limit) { ret = -ENOMEM; goto unlock; } This means if we have two vDPA devices for the same VM the pages would be counted twice. So we add a tree to save the page that counted and we will not count it again. Add vdpa_mem_tree to saved the mem that already counted. use a hlist to saved the root for vdpa_mem_tree. Signed-off-by: Cindy Lu --- drivers/vhost/vhost.c | 63 +++++++++++++++++++++++++++++++++++++++++++ drivers/vhost/vhost.h | 1 + 2 files changed, 64 insertions(+) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 40097826cff0..4ca8b1ed944b 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -32,6 +32,8 @@ #include #include "vhost.h" +#include +#include static ushort max_mem_regions = 64; module_param(max_mem_regions, ushort, 0444); @@ -49,6 +51,14 @@ enum { #define vhost_used_event(vq) ((__virtio16 __user *)&vq->avail->ring[vq->num]) #define vhost_avail_event(vq) ((__virtio16 __user *)&vq->used->ring[vq->num]) +struct vhost_vdpa_rbtree_node { + struct hlist_node node; + struct rb_root_cached vdpa_mem_tree; + struct mm_struct *mm_using; +}; +static DECLARE_HASHTABLE(vhost_vdpa_rbtree_hlist, 8); +int vhost_vdpa_rbtree_hlist_status; + #ifdef CONFIG_VHOST_CROSS_ENDIAN_LEGACY static void vhost_disable_cross_endian(struct vhost_virtqueue *vq) { @@ -571,6 +581,51 @@ static void vhost_detach_mm(struct vhost_dev *dev) dev->mm = NULL; } +struct rb_root_cached *vhost_vdpa_get_mem_tree(struct mm_struct *mm) +{ + struct vhost_vdpa_rbtree_node *rbtree_root = NULL; + struct rb_root_cached *vdpa_tree; + u32 key; + + /* No hased table, init one */ + if (vhost_vdpa_rbtree_hlist_status == 0) { + hash_init(vhost_vdpa_rbtree_hlist); + vhost_vdpa_rbtree_hlist_status = 1; + } + + key = jhash_1word((u64)mm, JHASH_INITVAL); + hash_for_each_possible(vhost_vdpa_rbtree_hlist, rbtree_root, node, + key) { + if (rbtree_root->mm_using == mm) + return &(rbtree_root->vdpa_mem_tree); + } + rbtree_root = kmalloc(sizeof(*rbtree_root), GFP_KERNEL); + if (!rbtree_root) + return NULL; + rbtree_root->mm_using = mm; + rbtree_root->vdpa_mem_tree = RB_ROOT_CACHED; + hash_add(vhost_vdpa_rbtree_hlist, &rbtree_root->node, key); + vdpa_tree = &(rbtree_root->vdpa_mem_tree); + return vdpa_tree; +} + +void vhost_vdpa_relase_mem_tree(struct mm_struct *mm) +{ + struct vhost_vdpa_rbtree_node *rbtree_root = NULL; + u32 key; + + key = jhash_1word((u64)mm, JHASH_INITVAL); + + /* No hased table, init one */ + hash_for_each_possible(vhost_vdpa_rbtree_hlist, rbtree_root, node, + key) { + if (rbtree_root->mm_using == mm) { + hash_del(&rbtree_root->node); + kfree(rbtree_root); + } + } +} + /* Caller should have device mutex */ long vhost_dev_set_owner(struct vhost_dev *dev) { @@ -605,6 +660,11 @@ long vhost_dev_set_owner(struct vhost_dev *dev) err = vhost_dev_alloc_iovecs(dev); if (err) goto err_cgroup; + dev->vdpa_mem_tree = vhost_vdpa_get_mem_tree(dev->mm); + if (dev->vdpa_mem_tree == NULL) { + err = -ENOMEM; + goto err_cgroup; + } return 0; err_cgroup: @@ -613,6 +673,7 @@ long vhost_dev_set_owner(struct vhost_dev *dev) dev->worker = NULL; } err_worker: + vhost_vdpa_relase_mem_tree(dev->mm); vhost_detach_mm(dev); dev->kcov_handle = 0; err_mm: @@ -710,6 +771,8 @@ void vhost_dev_cleanup(struct vhost_dev *dev) dev->worker = NULL; dev->kcov_handle = 0; } + + vhost_vdpa_relase_mem_tree(dev->mm); vhost_detach_mm(dev); } EXPORT_SYMBOL_GPL(vhost_dev_cleanup); diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index d9109107af08..84de33de3abf 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -160,6 +160,7 @@ struct vhost_dev { int byte_weight; u64 kcov_handle; bool use_worker; + struct rb_root_cached *vdpa_mem_tree; int (*msg_handler)(struct vhost_dev *dev, u32 asid, struct vhost_iotlb_msg *msg); }; -- 2.34.3