From patchwork Mon Mar 21 00:26:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mingwei Zhang X-Patchwork-Id: 12786718 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 D6358C433F5 for ; Mon, 21 Mar 2022 00:26:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343897AbiCUA2H (ORCPT ); Sun, 20 Mar 2022 20:28:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50726 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343893AbiCUA2G (ORCPT ); Sun, 20 Mar 2022 20:28:06 -0400 Received: from mail-pg1-x54a.google.com (mail-pg1-x54a.google.com [IPv6:2607:f8b0:4864:20::54a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 96CCADE910 for ; Sun, 20 Mar 2022 17:26:42 -0700 (PDT) Received: by mail-pg1-x54a.google.com with SMTP id bj8-20020a056a02018800b0035ec8c16f0bso6625988pgb.11 for ; Sun, 20 Mar 2022 17:26:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=ZnD2DMccysTRV29OOaip4kblVakt/ZXloOGMe9n4Sq8=; b=KDMyBdZmkNm9VQre/sHHd+UF3yLIF3XPElWKa82CiPy1b7hEVh9nyWahmPuLote377 KSDkZZqhX/BR9824SpZY9nY/1qeWg5iLaIw79JX0wKagPNLtWpFCr9Xyk3iGC4svbs4H UMHBiMVexnJw3LuAwJeYPqtRSf7zqf3/bp32cAM0ZwjYjaqcZlFXOetCtOMQ9Z155UO4 nSaquyHHmSm+3HvKXJaY3xsm5XvZrXrene3Lp2Cto/v5sdLMOYM3DChdG5UoUllKEM8y MjjUnMWOvBoAOzLet0kHzmhoBrr7ttSa26hRSaztdAmnHtnAYPTNFoOCHh3thtt3uRpu /3sg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=ZnD2DMccysTRV29OOaip4kblVakt/ZXloOGMe9n4Sq8=; b=CMInBkNdCIOW6/ECVIvwaIyNLx1J5RldZzjDGdCSAG029amQn91x2qKWs1HAZEe4er EDI579GK+211YwxXOq9Jp4fWCya8/5j6vyfkN9+DQQ0mrHzNNxaJFIIYW83J4ai6wyXC zx6WN5Rf0za0BeuLe+db4vicosYBaG0YU7dKXdy8PDfq4IUxWcZHIcxPSMYMRMnlQ5AL /0W6qYAgFVQArkrJB/ECf1fsiDmh0wRKUEU8eYVh26f5JFAu+DgN3shH5MCX6hI7qw+l 6NESvn+ffWIIPtTD5KP2LExgknqgQBxoz03TM4Vnub8kLx2I6qkLq9AtN0DQtUxW3Vpx 34SA== X-Gm-Message-State: AOAM532zhP9z1QyUaZjub6wT3Kigi0n+pAe8XlykeIO+uoBfudUGuouL cKPPFS2rTgkBl5tGkQhLhOpafuGDrkb+ X-Google-Smtp-Source: ABdhPJxBa/87UWDZmU7EDsZl+WZSJ+96ppP55fnQay9zpPrkfeF9vKo9OqM19uQ4CNgZgV0Unu/Rdf89sZaW X-Received: from mizhang-super.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1071]) (user=mizhang job=sendgmr) by 2002:a05:6a00:1992:b0:4fa:7438:870a with SMTP id d18-20020a056a00199200b004fa7438870amr13100130pfl.48.1647822402113; Sun, 20 Mar 2022 17:26:42 -0700 (PDT) Reply-To: Mingwei Zhang Date: Mon, 21 Mar 2022 00:26:35 +0000 In-Reply-To: <20220321002638.379672-1-mizhang@google.com> Message-Id: <20220321002638.379672-2-mizhang@google.com> Mime-Version: 1.0 References: <20220321002638.379672-1-mizhang@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH 1/4] selftests: KVM: Dump VM stats in binary stats test From: Mingwei Zhang To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Ben Gardon , Mingwei Zhang , David Matlack , Jing Zhang , Peter Xu , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org From: Ben Gardon Add kvm_util library functions to read KVM stats through the binary stats interface and then dump them to stdout when running the binary stats test. Subsequent commits will extend the kvm_util code and use it to make assertions in a test for NX hugepages. CC: Jing Zhang Signed-off-by: Ben Gardon --- .../selftests/kvm/include/kvm_util_base.h | 1 + .../selftests/kvm/kvm_binary_stats_test.c | 3 + tools/testing/selftests/kvm/lib/kvm_util.c | 143 ++++++++++++++++++ 3 files changed, 147 insertions(+) diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h index 4ed6aa049a91..160b9ad8474a 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -392,6 +392,7 @@ void assert_on_unhandled_exception(struct kvm_vm *vm, uint32_t vcpuid); int vm_get_stats_fd(struct kvm_vm *vm); int vcpu_get_stats_fd(struct kvm_vm *vm, uint32_t vcpuid); +void dump_vm_stats(struct kvm_vm *vm); uint32_t guest_get_vcpuid(void); diff --git a/tools/testing/selftests/kvm/kvm_binary_stats_test.c b/tools/testing/selftests/kvm/kvm_binary_stats_test.c index 17f65d514915..afc4701ce8dd 100644 --- a/tools/testing/selftests/kvm/kvm_binary_stats_test.c +++ b/tools/testing/selftests/kvm/kvm_binary_stats_test.c @@ -174,6 +174,9 @@ static void vm_stats_test(struct kvm_vm *vm) stats_test(stats_fd); close(stats_fd); TEST_ASSERT(fcntl(stats_fd, F_GETFD) == -1, "Stats fd not freed"); + + /* Dump VM stats */ + dump_vm_stats(vm); } static void vcpu_stats_test(struct kvm_vm *vm, int vcpu_id) diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index d8cf851ab119..d9c660913403 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2517,3 +2517,146 @@ int vcpu_get_stats_fd(struct kvm_vm *vm, uint32_t vcpuid) return ioctl(vcpu->fd, KVM_GET_STATS_FD, NULL); } + +/* Caller is responsible for freeing the returned kvm_stats_header. */ +static struct kvm_stats_header *read_vm_stats_header(int stats_fd) +{ + struct kvm_stats_header *header; + ssize_t ret; + + /* Read kvm stats header */ + header = malloc(sizeof(*header)); + TEST_ASSERT(header, "Allocate memory for stats header"); + + ret = read(stats_fd, header, sizeof(*header)); + TEST_ASSERT(ret == sizeof(*header), "Read stats header"); + + return header; +} + +static void dump_header(int stats_fd, struct kvm_stats_header *header) +{ + ssize_t ret; + char *id; + + printf("flags: %u\n", header->flags); + printf("name size: %u\n", header->name_size); + printf("num_desc: %u\n", header->num_desc); + printf("id_offset: %u\n", header->id_offset); + printf("desc_offset: %u\n", header->desc_offset); + printf("data_offset: %u\n", header->data_offset); + + /* Read kvm stats id string */ + id = malloc(header->name_size); + TEST_ASSERT(id, "Allocate memory for id string"); + ret = pread(stats_fd, id, header->name_size, header->id_offset); + TEST_ASSERT(ret == header->name_size, "Read id string"); + + printf("id: %s\n", id); + + free(id); +} + +static ssize_t stats_desc_size(struct kvm_stats_header *header) +{ + return sizeof(struct kvm_stats_desc) + header->name_size; +} + +/* Caller is responsible for freeing the returned kvm_stats_desc. */ +static struct kvm_stats_desc *read_vm_stats_desc(int stats_fd, + struct kvm_stats_header *header) +{ + struct kvm_stats_desc *stats_desc; + size_t size_desc; + ssize_t ret; + + size_desc = header->num_desc * stats_desc_size(header); + + /* Allocate memory for stats descriptors */ + stats_desc = malloc(size_desc); + TEST_ASSERT(stats_desc, "Allocate memory for stats descriptors"); + + /* Read kvm stats descriptors */ + ret = pread(stats_fd, stats_desc, size_desc, header->desc_offset); + TEST_ASSERT(ret == size_desc, "Read KVM stats descriptors"); + + return stats_desc; +} + +/* Caller is responsible for freeing the memory *data. */ +static int read_stat_data(int stats_fd, struct kvm_stats_header *header, + struct kvm_stats_desc *desc, uint64_t **data) +{ + u64 *stats_data; + ssize_t ret; + + stats_data = malloc(desc->size * sizeof(*stats_data)); + + ret = pread(stats_fd, stats_data, desc->size * sizeof(*stats_data), + header->data_offset + desc->offset); + + /* ret is in bytes. */ + ret = ret / sizeof(*stats_data); + + TEST_ASSERT(ret == desc->size, + "Read data of KVM stats: %s", desc->name); + + *data = stats_data; + + return ret; +} + +static void dump_stat(int stats_fd, struct kvm_stats_header *header, + struct kvm_stats_desc *desc) +{ + u64 *stats_data; + ssize_t ret; + int i; + + printf("\tflags: %u\n", desc->flags); + printf("\texponent: %u\n", desc->exponent); + printf("\tsize: %u\n", desc->size); + printf("\toffset: %u\n", desc->offset); + printf("\tbucket_size: %u\n", desc->bucket_size); + printf("\tname: %s\n", (char *)&desc->name); + + ret = read_stat_data(stats_fd, header, desc, &stats_data); + + printf("\tdata: %lu", *stats_data); + for (i = 1; i < ret; i++) + printf(", %lu", *(stats_data + i)); + printf("\n\n"); + + free(stats_data); +} + +void dump_vm_stats(struct kvm_vm *vm) +{ + struct kvm_stats_desc *stats_desc; + struct kvm_stats_header *header; + struct kvm_stats_desc *desc; + size_t size_desc; + int stats_fd; + int i; + + stats_fd = vm_get_stats_fd(vm); + + header = read_vm_stats_header(stats_fd); + dump_header(stats_fd, header); + + stats_desc = read_vm_stats_desc(stats_fd, header); + + size_desc = stats_desc_size(header); + + /* Read kvm stats data one by one */ + for (i = 0; i < header->num_desc; ++i) { + desc = (void *)stats_desc + (i * size_desc); + dump_stat(stats_fd, header, desc); + } + + free(stats_desc); + free(header); + + close(stats_fd); +} + From patchwork Mon Mar 21 00:26:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mingwei Zhang X-Patchwork-Id: 12786720 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 DBB83C433F5 for ; Mon, 21 Mar 2022 00:26:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343922AbiCUA2N (ORCPT ); Sun, 20 Mar 2022 20:28:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50768 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343900AbiCUA2I (ORCPT ); Sun, 20 Mar 2022 20:28:08 -0400 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0A418DE91C for ; Sun, 20 Mar 2022 17:26:44 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id e2-20020a17090301c200b001545acd89c9so146637plh.3 for ; Sun, 20 Mar 2022 17:26:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=ONXdbAN8amlEB9qh6OgAKGOjSA/PDIQV8SIv35wcs8A=; b=M+NOaEnG6mj6JNTytwlFELsq2MhitrDFldJcZeXo09FgI1nAz5E+TAv3aUmQVZQZnj 3D1EbJ8yTnWcGrQnNk0NpqHgtPgIRkexkaos7Ic84kCeANiIoaiXaoVRmcNzC0r01STI BF33pX+0Uem/BI64+Tdln+4OqbAIgUNOoObYnK6wb6vPI/gWddA0PjEFLdkCMTcKfZdH M9ks8wNMR5HVMB/4es2FMurFj6AoIzhWTewYuQGw+DTIdzN/JK5ySU7ayXmkpgJYvXDv fq80XL3SnVLntF8x1coPEThYe+KNcfUz4NTk0WUSoiRjTJ0BCUV77/4evNYpEq0HIBK3 GN2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=ONXdbAN8amlEB9qh6OgAKGOjSA/PDIQV8SIv35wcs8A=; b=t/2RaLqmJqko2M0TssNt+BjiWlYexXekVV6QX7WmPLiWBsjVkrTQ2pAu4b3KWv1y5d Z6pjGC0ZgRTQ5S+c1kpegtyixfFR35E/jP6YiWCLGAB/sJUluTy+a9KtiSoOczgnLSB/ +5dfMRNDiUew5kQVQ/JiG+T+GlIEA0iQSZLISSUl8CVuRVwyx1JbgwV7JdHvH7qZCYFn iMHo44iZrVH4dJfr2DETGTy00szWuwCHWvoHNqWUkQKLESIaJsTKnlXPKSFcvXyuHswA JAbveYdvi4U7K5tcyy0nnQ9VwGCJLekpL4LOizA4CqYKFSZstphPrEi+TdoIX1r/2Vwe 3tJA== X-Gm-Message-State: AOAM530199Olx78vpon+LaLW/lpTV5BdU7IO7JSf8iVritdmB8wEMoJu YZ8/i4vimGi2ZC7G/pfdcI5uN/RsIfoR X-Google-Smtp-Source: ABdhPJyQh0cpfhcq39A4la7k4keyo7dVFdF0fGkivbfV/iyl7s5g/kW3RQ8CmP/A+Tpauwan61zOFPISJtTf X-Received: from mizhang-super.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1071]) (user=mizhang job=sendgmr) by 2002:a17:902:b097:b0:154:2bda:bd38 with SMTP id p23-20020a170902b09700b001542bdabd38mr9344521plr.155.1647822403459; Sun, 20 Mar 2022 17:26:43 -0700 (PDT) Reply-To: Mingwei Zhang Date: Mon, 21 Mar 2022 00:26:36 +0000 In-Reply-To: <20220321002638.379672-1-mizhang@google.com> Message-Id: <20220321002638.379672-3-mizhang@google.com> Mime-Version: 1.0 References: <20220321002638.379672-1-mizhang@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH 2/4] selftests: KVM: Test reading a single stat From: Mingwei Zhang To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Ben Gardon , Mingwei Zhang , David Matlack , Jing Zhang , Peter Xu , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org From: Ben Gardon Retrieve the value of a single stat by name in the binary stats test to ensure the kvm_util library functions work. CC: Jing Zhang Signed-off-by: Ben Gardon --- .../selftests/kvm/include/kvm_util_base.h | 1 + .../selftests/kvm/kvm_binary_stats_test.c | 3 ++ tools/testing/selftests/kvm/lib/kvm_util.c | 53 +++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h index 160b9ad8474a..a07964c95941 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -393,6 +393,7 @@ void assert_on_unhandled_exception(struct kvm_vm *vm, uint32_t vcpuid); int vm_get_stats_fd(struct kvm_vm *vm); int vcpu_get_stats_fd(struct kvm_vm *vm, uint32_t vcpuid); void dump_vm_stats(struct kvm_vm *vm); +uint64_t vm_get_single_stat(struct kvm_vm *vm, const char *stat_name); uint32_t guest_get_vcpuid(void); diff --git a/tools/testing/selftests/kvm/kvm_binary_stats_test.c b/tools/testing/selftests/kvm/kvm_binary_stats_test.c index afc4701ce8dd..97bde355f105 100644 --- a/tools/testing/selftests/kvm/kvm_binary_stats_test.c +++ b/tools/testing/selftests/kvm/kvm_binary_stats_test.c @@ -177,6 +177,9 @@ static void vm_stats_test(struct kvm_vm *vm) /* Dump VM stats */ dump_vm_stats(vm); + + /* Read a single stat. */ + printf("remote_tlb_flush: %lu\n", vm_get_single_stat(vm, "remote_tlb_flush")); } static void vcpu_stats_test(struct kvm_vm *vm, int vcpu_id) diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index d9c660913403..dad54f5d57e7 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2660,3 +2660,56 @@ void dump_vm_stats(struct kvm_vm *vm) close(stats_fd); } +static int vm_get_stat_data(struct kvm_vm *vm, const char *stat_name, + uint64_t **data) +{ + struct kvm_stats_desc *stats_desc; + struct kvm_stats_header *header; + struct kvm_stats_desc *desc; + size_t size_desc; + int stats_fd; + int ret = -EINVAL; + int i; + + *data = NULL; + + stats_fd = vm_get_stats_fd(vm); + + header = read_vm_stats_header(stats_fd); + + stats_desc = read_vm_stats_desc(stats_fd, header); + + size_desc = stats_desc_size(header); + + /* Read kvm stats data one by one */ + for (i = 0; i < header->num_desc; ++i) { + desc = (void *)stats_desc + (i * size_desc); + + if (strcmp(desc->name, stat_name)) + continue; + + ret = read_stat_data(stats_fd, header, desc, data); + } + + free(stats_desc); + free(header); + + close(stats_fd); + + return ret; +} + +uint64_t vm_get_single_stat(struct kvm_vm *vm, const char *stat_name) +{ + uint64_t *data; + uint64_t value; + int ret; + + ret = vm_get_stat_data(vm, stat_name, &data); + TEST_ASSERT(ret == 1, "Stat %s expected to have 1 element, but has %d", + stat_name, ret); + value = *data; + free(data); + return value; +} + From patchwork Mon Mar 21 00:26:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mingwei Zhang X-Patchwork-Id: 12786721 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 9EDADC433F5 for ; Mon, 21 Mar 2022 00:26:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343918AbiCUA2O (ORCPT ); Sun, 20 Mar 2022 20:28:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50798 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343903AbiCUA2J (ORCPT ); Sun, 20 Mar 2022 20:28:09 -0400 Received: from mail-pj1-x104a.google.com (mail-pj1-x104a.google.com [IPv6:2607:f8b0:4864:20::104a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8C106DE926 for ; Sun, 20 Mar 2022 17:26:45 -0700 (PDT) Received: by mail-pj1-x104a.google.com with SMTP id d7-20020a17090ad98700b001c6834c71ffso5951432pjv.1 for ; Sun, 20 Mar 2022 17:26:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=w72ktL2NVaulWnSOLwhUAw/SEUZ2qLk7Ydqg7suvoo4=; b=fx1XCeSYsDcHoKzCEPO5QZTH/7lJHeMLn4C/eT3bSq9992/wm8zBqAZSk2S8ps8OVp YVMnCJq6mRf809eIU4L/Cez2s4PciznmUAWKOwgFPAp82mqDTNJnQY4VLW7Odu7kWy5I K5X/MNocMz7n6KTZPyq7pkGdo5582uc8RzaV4LVqKe5OYI/C7nLQovCZYIQKKlT0jqGu H28bbR4alZOzfpAwlcHASL/0YDA46pxKWiSHQUpbGUQkE5ccSQDXy7tm3II7/dBe9UeA BXovdb4Gr/rmvzC405fiMovRJthVWFMRzeRyKDahyKfYQeVZ60hGjjcMbkUQ3fO7ZSE6 DpTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=w72ktL2NVaulWnSOLwhUAw/SEUZ2qLk7Ydqg7suvoo4=; b=r/370M9M2qwmmMGITKfk42XV0C/J0guZEs/yFo7eypg5yKJlypl1io3uAEZ+E3hLM6 zyA3Wfol96MVfeVbf8xenQQOkyZ+4ymYoU85iMFN/rm2KUe/4OdaWr5qNhfGZACLTyP7 UPHAa9isfifpNzwACckj4fnKws7WV0QYH6BSem5il4mYPkP0oATo9VanjPUBwS7S9Nus REYHaOzaRfOk1fPlyO3jQWs5s0JTPb5+m1MEB33r0ACFYkoK+G+Ms0XKanRPQGbYfjZT 5glruNsrzteQQqtYp+NMWCHlMdlkrOGwBoXZGULXN3BKyezbk8jwO5zdl2QrPP9cwCKS 9G1Q== X-Gm-Message-State: AOAM532VSlyLV2OfWLOuES/SOQcFTjONi4Y9cqFdUJI3+ZfPI/b/2dt5 53BtlSHQuhtvDdRHeW3C+6dWy/dxxEKx X-Google-Smtp-Source: ABdhPJxbX88VuJKl737VvBq/vCrgo6XQMNEN18CqZbwf3ZJmJ6wNbhkzBo6bEjn+oSxahPeVrtMULAZs1R6L X-Received: from mizhang-super.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1071]) (user=mizhang job=sendgmr) by 2002:aa7:8432:0:b0:4f6:6dcd:4f19 with SMTP id q18-20020aa78432000000b004f66dcd4f19mr21345407pfn.53.1647822405012; Sun, 20 Mar 2022 17:26:45 -0700 (PDT) Reply-To: Mingwei Zhang Date: Mon, 21 Mar 2022 00:26:37 +0000 In-Reply-To: <20220321002638.379672-1-mizhang@google.com> Message-Id: <20220321002638.379672-4-mizhang@google.com> Mime-Version: 1.0 References: <20220321002638.379672-1-mizhang@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH 3/4] KVM: x86/mmu: explicitly check nx_hugepage in disallowed_hugepage_adjust() From: Mingwei Zhang To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Ben Gardon , Mingwei Zhang , David Matlack , Jing Zhang , Peter Xu , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add extra check to specify the case of nx hugepage and allow KVM to reconstruct large mapping after dirty logging is disabled. Existing code works only for nx hugepage but the condition is too general in that does not consider other usage case (such as dirty logging). Moreover, existing code assumes that a present PMD or PUD indicates that there exist 'smaller SPTEs' under the paging structure. This assumption may no be true if consider the zapping leafs only behavior in MMU. Missing the check causes KVM incorrectly regards the faulting page as a NX huge page and refuse to map it at desired level. And this leads to back performance in shadow mmu and potentiall TDP mmu. Fixes: b8e8c8303ff2 ("kvm: mmu: ITLB_MULTIHIT mitigation") Cc: stable@vger.kernel.org Reviewed-by: Ben Gardon Signed-off-by: Mingwei Zhang --- arch/x86/kvm/mmu/mmu.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 5628d0ba637e..4d358c273f6c 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -2919,6 +2919,16 @@ void disallowed_hugepage_adjust(struct kvm_page_fault *fault, u64 spte, int cur_ cur_level == fault->goal_level && is_shadow_present_pte(spte) && !is_large_pte(spte)) { + struct kvm_mmu_page *sp; + u64 page_mask; + /* + * When nx hugepage flag is not set, there is no reason to + * go down to another level. This helps demand paging to + * generate large mappings. + */ + sp = to_shadow_page(spte & PT64_BASE_ADDR_MASK); + if (!sp->lpage_disallowed) + return; /* * A small SPTE exists for this pfn, but FNAME(fetch) * and __direct_map would like to create a large PTE @@ -2926,8 +2936,8 @@ void disallowed_hugepage_adjust(struct kvm_page_fault *fault, u64 spte, int cur_ * patching back for them into pfn the next 9 bits of * the address. */ - u64 page_mask = KVM_PAGES_PER_HPAGE(cur_level) - - KVM_PAGES_PER_HPAGE(cur_level - 1); + page_mask = KVM_PAGES_PER_HPAGE(cur_level) - + KVM_PAGES_PER_HPAGE(cur_level - 1); fault->pfn |= fault->gfn & page_mask; fault->goal_level--; } From patchwork Mon Mar 21 00:26:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mingwei Zhang X-Patchwork-Id: 12786722 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 D3F5BC433F5 for ; Mon, 21 Mar 2022 00:27:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343929AbiCUA2Y (ORCPT ); Sun, 20 Mar 2022 20:28:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50852 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343898AbiCUA2L (ORCPT ); Sun, 20 Mar 2022 20:28:11 -0400 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 064E3DE910 for ; Sun, 20 Mar 2022 17:26:47 -0700 (PDT) Received: by mail-pj1-x1049.google.com with SMTP id o12-20020a17090a420c00b001c65aec76c0so7689764pjg.8 for ; Sun, 20 Mar 2022 17:26:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=Fmv+HMc2DFxNt8CxUdSLz9dfbbTJJCLxSOxGsXm4RyU=; b=p6WWOu56th14hFbz/vDJsj1YNlhWpB7KWlRQjlG5lF4dyCxZxdkzJkQU/tJPoez92d maakq/dfxmhfKGNOZYWMgEKpDoKtFAgijvHMmtYdKhUALE5ymi1R5lTAcHpGpyth9NMf zLrmS3vhHPaaPsoQVmefiC/MjXoB0+gEZmiY0coOY2wrbWU/wCxd4F5t1N8bnMiJd+ab nhjgojLKs3DtNzC0Bm6ejviuERcb3oxb7/dkWQtPSyV0kSSm2ArXx1WZTCNoLXs8rwBY ecDJ78LUFg6Exe7b5GrWHuRX2wfCdtxK8sQe0zG5z1W/0Afu2KR9/lsuAYZrKEoSzkgu 7KrQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=Fmv+HMc2DFxNt8CxUdSLz9dfbbTJJCLxSOxGsXm4RyU=; b=bqw+YBKGjjBLoHkZolRgPRreKOD1fDwa6XoB3iTFsfs3mFHBWqasekKRgudl/9fKE1 IUOAIJV8bi1eMpBZsXkfLKKd8SaBirmoLhSeJJV6jKyj/xLdliE2QuZf1idgd4mYDp3t IScnNBb3Q7RnY/ge4UrHmleWT9HhUiq9Cnlcjgb8mPzyVaiXcjqDlWdKkt8yznQbtfGk r6GHoW4AZgDtOmAA1E/C8gdemTgwJ0FoVlqpwztL06g9rVOUt9XC1GnhCx9Zzlr0upkx vhrkwT0w2d4WBMX8NynlD8oKb7OdV+oLucLgq56Eji1Zp+mzhTyc5AwQr2b/ZIFXT1G1 mlRg== X-Gm-Message-State: AOAM532DUPZTtdgEiJQ4dgwZdqjrPBXPmqrA4ZredAA57Pa/dvw/EEhl I5CuhGlbaCE6t/3bLZaXFSw5nt4F7ro8 X-Google-Smtp-Source: ABdhPJyKZwK8L7OgfM5eCJrVgG7L/KDRJs9ML8qnRmGqUKzDjY6RiXCxrTBNf2fA8anI5bY3FN33eH2UxTo1 X-Received: from mizhang-super.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1071]) (user=mizhang job=sendgmr) by 2002:a17:902:b941:b0:14d:af72:3f23 with SMTP id h1-20020a170902b94100b0014daf723f23mr10621824pls.6.1647822406401; Sun, 20 Mar 2022 17:26:46 -0700 (PDT) Reply-To: Mingwei Zhang Date: Mon, 21 Mar 2022 00:26:38 +0000 In-Reply-To: <20220321002638.379672-1-mizhang@google.com> Message-Id: <20220321002638.379672-5-mizhang@google.com> Mime-Version: 1.0 References: <20220321002638.379672-1-mizhang@google.com> X-Mailer: git-send-email 2.35.1.894.gb6a874cedc-goog Subject: [PATCH 4/4] selftests: KVM: use dirty logging to check if page stats work correctly From: Mingwei Zhang To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Ben Gardon , Mingwei Zhang , David Matlack , Jing Zhang , Peter Xu , Ben Gardon Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org When dirty logging is enabled, KVM splits the all hugepage mapping in NPT/EPT into the smallest 4K size. This property could be used to check if the page stats metrics work properly in KVM mmu. At the same time, this logic might be used the other way around: using page stats to verify if dirty logging really splits all huge pages. Moreover, when dirty logging is disabled, KVM zaps corresponding SPTEs and we could check whether the large pages come back when guest touches the pages again. So add page stats checking in dirty logging performance selftest. In particular, add checks in three locations: - just after vm is created; - after populating memory into vm but before enabling dirty logging; - just after turning on dirty logging. - after one final iteration after turning off dirty logging. Tested using commands: - ./dirty_log_perf_test -s anonymous_hugetlb_1gb - ./dirty_log_perf_test -s anonymous_thp Cc: Sean Christopherson Cc: David Matlack Cc: Jing Zhang Cc: Peter Xu Suggested-by: Ben Gardon Signed-off-by: Mingwei Zhang --- .../selftests/kvm/dirty_log_perf_test.c | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/tools/testing/selftests/kvm/dirty_log_perf_test.c b/tools/testing/selftests/kvm/dirty_log_perf_test.c index 1954b964d1cf..ab0457d91658 100644 --- a/tools/testing/selftests/kvm/dirty_log_perf_test.c +++ b/tools/testing/selftests/kvm/dirty_log_perf_test.c @@ -19,6 +19,10 @@ #include "perf_test_util.h" #include "guest_modes.h" +#ifdef __x86_64__ +#include "processor.h" +#endif + /* How many host loops to run by default (one KVM_GET_DIRTY_LOG for each loop)*/ #define TEST_HOST_LOOP_N 2UL @@ -185,6 +189,14 @@ static void run_test(enum vm_guest_mode mode, void *arg) p->slots, p->backing_src, p->partition_vcpu_memory_access); +#ifdef __x86_64__ + TEST_ASSERT(vm_get_single_stat(vm, "pages_4k") == 0, + "4K page is non zero"); + TEST_ASSERT(vm_get_single_stat(vm, "pages_2m") == 0, + "2M page is non zero"); + TEST_ASSERT(vm_get_single_stat(vm, "pages_1g") == 0, + "1G page is non zero"); +#endif perf_test_set_wr_fract(vm, p->wr_fract); guest_num_pages = (nr_vcpus * guest_percpu_mem_size) >> vm_get_page_shift(vm); @@ -222,6 +234,16 @@ static void run_test(enum vm_guest_mode mode, void *arg) pr_info("Populate memory time: %ld.%.9lds\n", ts_diff.tv_sec, ts_diff.tv_nsec); +#ifdef __x86_64__ + TEST_ASSERT(vm_get_single_stat(vm, "pages_4k") != 0, + "4K page is zero"); + if (p->backing_src == VM_MEM_SRC_ANONYMOUS_THP) + TEST_ASSERT(vm_get_single_stat(vm, "pages_2m") != 0, + "2M page is zero"); + if (p->backing_src == VM_MEM_SRC_ANONYMOUS_HUGETLB_1GB) + TEST_ASSERT(vm_get_single_stat(vm, "pages_1g") != 0, + "1G page is zero"); +#endif /* Enable dirty logging */ clock_gettime(CLOCK_MONOTONIC, &start); enable_dirty_logging(vm, p->slots); @@ -267,6 +289,14 @@ static void run_test(enum vm_guest_mode mode, void *arg) iteration, ts_diff.tv_sec, ts_diff.tv_nsec); } } +#ifdef __x86_64__ + TEST_ASSERT(vm_get_single_stat(vm, "pages_4k") != 0, + "4K page is zero after dirty logging"); + TEST_ASSERT(vm_get_single_stat(vm, "pages_2m") == 0, + "2M page is non-zero after dirty logging"); + TEST_ASSERT(vm_get_single_stat(vm, "pages_1g") == 0, + "1G page is non-zero after dirty logging"); +#endif /* Disable dirty logging */ clock_gettime(CLOCK_MONOTONIC, &start); @@ -275,6 +305,28 @@ static void run_test(enum vm_guest_mode mode, void *arg) pr_info("Disabling dirty logging time: %ld.%.9lds\n", ts_diff.tv_sec, ts_diff.tv_nsec); +#ifdef __x86_64__ + /* + * Increment iteration to run the vcpus again to verify if huge pages + * come back. + */ + iteration++; + pr_info("Starting the final iteration to verify page stats\n"); + + for (vcpu_id = 0; vcpu_id < nr_vcpus; vcpu_id++) { + while (READ_ONCE(vcpu_last_completed_iteration[vcpu_id]) + != iteration) + ; + } + + if (p->backing_src == VM_MEM_SRC_ANONYMOUS_THP) + TEST_ASSERT(vm_get_single_stat(vm, "pages_2m") != 0, + "2M page is zero"); + if (p->backing_src == VM_MEM_SRC_ANONYMOUS_HUGETLB_1GB) + TEST_ASSERT(vm_get_single_stat(vm, "pages_1g") != 0, + "1G page is zero"); +#endif + /* Tell the vcpu thread to quit */ host_quit = true; perf_test_join_vcpu_threads(nr_vcpus);