Received: by 2002:a25:6193:0:0:0:0:0 with SMTP id v141csp3381626ybb; Mon, 13 Apr 2020 06:56:53 -0700 (PDT) X-Google-Smtp-Source: APiQypJRQCejZsO2z3/rX2VT1BmBBwCtdx8uvt29kJZrHVHKrpWQb5PVMcEzsq4chNe4wi2zAgAW X-Received: by 2002:a17:906:d18e:: with SMTP id c14mr16485604ejz.120.1586786212796; Mon, 13 Apr 2020 06:56:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1586786212; cv=none; d=google.com; s=arc-20160816; b=VAKd31zd8hDqk0O9CNzrI9SuqBaoqDUeE/6x6DdPJQZyj+l9gox45ok9YGlXXiYh+x 32NRxPBFNhpDtoneZo5TERI3DSeG/FhThYFUiXpw61PHqSk/ynkKcjHkuMLuzEOuROJ4 Db2tp1PykBUW17cFcX8iSP3WkLPfhUb8uKxXImZoFzGx6ARWtHKXpCGpvMFNKbiENGz5 M5bk9pRtTrmOT19D6egMRl1tazu+a0bOZ/CxxTf1SdUYh5klTZECdt6gEIldVvgK7D/X exYUw6KTZscCe4fWuUXw9niLuWaLO5hIca/y7SXdGP9LKlYObw79i5HYlk1q5OfhJg9Q Z1GQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=FhMhc4GAm3mO9T/9cC8MV1cBefK/kZLPD3JeoHO3X5Y=; b=mpa9+DkM6UGVWlvTDVE0wKV2Ehd1l99qZJFBzfV7wtXa09Zbh6TrQcgIYMvwviBMmW 8D9cbDDPsmKBfVo+PJc4iJs6NreP9OuVZwLJ1r+reH23JGnsHSczYFqYc8a//4zJAKqo Sf2l2ZD91HKNa6kj9jb6bye9P3WAhxfvAkB+xWtiAbIilOFtrhcyv1C3PWjLgQ+Pk50q j186lTlCIIGb3CUTLfxNFbBWpBb0MyHFxzjuFfMUufppaJqH0QydpkCsd3+tbaTqcy/K oXFEL3qj6lMtqGp7VcfR0rC2wVymH6ejhJ3ay3JSGvYfFEeU6dHQEgbgUvO1aK7N3yjo GjxA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id s26si5988241edr.218.2020.04.13.06.56.27; Mon, 13 Apr 2020 06:56:52 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729474AbgDMMWz (ORCPT + 99 others); Mon, 13 Apr 2020 08:22:55 -0400 Received: from szxga07-in.huawei.com ([45.249.212.35]:55336 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728344AbgDMMWz (ORCPT ); Mon, 13 Apr 2020 08:22:55 -0400 Received: from DGGEMS409-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 6B73DF5F703402750F59; Mon, 13 Apr 2020 20:22:52 +0800 (CST) Received: from linux-kDCJWP.huawei.com (10.175.104.212) by DGGEMS409-HUB.china.huawei.com (10.3.19.209) with Microsoft SMTP Server id 14.3.487.0; Mon, 13 Apr 2020 20:22:45 +0800 From: Keqian Zhu To: , , , CC: Marc Zyngier , Paolo Bonzini , "James Morse" , Julien Thierry , Will Deacon , Suzuki K Poulose , Sean Christopherson , Jay Zhou , , Keqian Zhu Subject: [PATCH v2] KVM/arm64: Support enabling dirty log gradually in small chunks Date: Mon, 13 Apr 2020 20:20:23 +0800 Message-ID: <20200413122023.52583-1-zhukeqian1@huawei.com> X-Mailer: git-send-email 2.19.1 MIME-Version: 1.0 Content-Transfer-Encoding: 7BIT Content-Type: text/plain; charset=US-ASCII X-Originating-IP: [10.175.104.212] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org There is already support of enabling dirty log graually in small chunks for x86 in commit 3c9bd4006bfc ("KVM: x86: enable dirty log gradually in small chunks"). This adds support for arm64. x86 still writes protect all huge pages when DIRTY_LOG_INITIALLY_ALL_SET is eanbled. However, for arm64, both huge pages and normal pages can be write protected gradually by userspace. Under the Huawei Kunpeng 920 2.6GHz platform, I did some tests on 128G Linux VMs with different page size. The memory pressure is 127G in each case. The time taken of memory_global_dirty_log_start in QEMU is listed below: Page Size Before After Optimization 4K 650ms 1.8ms 2M 4ms 1.8ms 1G 2ms 1.8ms Besides the time reduction, the biggest income is that we will minimize the performance side effect (because of dissloving huge pages and marking memslots dirty) on guest after enabling dirty log. Signed-off-by: Keqian Zhu --- Documentation/virt/kvm/api.rst | 2 +- arch/arm64/include/asm/kvm_host.h | 3 +++ virt/kvm/arm/mmu.c | 12 ++++++++++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index efbbe570aa9b..0017f63fa44f 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -5777,7 +5777,7 @@ will be initialized to 1 when created. This also improves performance because dirty logging can be enabled gradually in small chunks on the first call to KVM_CLEAR_DIRTY_LOG. KVM_DIRTY_LOG_INITIALLY_SET depends on KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE (it is also only available on -x86 for now). +x86 and arm64 for now). KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 was previously available under the name KVM_CAP_MANUAL_DIRTY_LOG_PROTECT, but the implementation had bugs that make diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 32c8a675e5a4..a723f84fab83 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -46,6 +46,9 @@ #define KVM_REQ_RECORD_STEAL KVM_ARCH_REQ(3) #define KVM_REQ_RELOAD_GICv4 KVM_ARCH_REQ(4) +#define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \ + KVM_DIRTY_LOG_INITIALLY_SET) + DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use); extern unsigned int kvm_sve_max_vl; diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c index e3b9ee268823..1077f653a611 100644 --- a/virt/kvm/arm/mmu.c +++ b/virt/kvm/arm/mmu.c @@ -2265,8 +2265,16 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, * allocated dirty_bitmap[], dirty pages will be be tracked while the * memory slot is write protected. */ - if (change != KVM_MR_DELETE && mem->flags & KVM_MEM_LOG_DIRTY_PAGES) - kvm_mmu_wp_memory_region(kvm, mem->slot); + if (change != KVM_MR_DELETE && mem->flags & KVM_MEM_LOG_DIRTY_PAGES) { + /* + * If we're with initial-all-set, we don't need to write + * protect any pages because they're all reported as dirty. + * Huge pages and normal pages will be write protect gradually. + */ + if (!kvm_dirty_log_manual_protect_and_init_set(kvm)) { + kvm_mmu_wp_memory_region(kvm, mem->slot); + } + } } int kvm_arch_prepare_memory_region(struct kvm *kvm, -- 2.19.1