From patchwork Tue Aug 2 19:39:18 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 655111 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3s3mzX5vqMz9t3D for ; Wed, 3 Aug 2016 05:51:20 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=P916a2uN; dkim-atps=neutral Received: from localhost ([::1]:58675 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bUfig-0001s6-IT for incoming@patchwork.ozlabs.org; Tue, 02 Aug 2016 15:51:18 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35861) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bUfXc-0006aN-6L for qemu-devel@nongnu.org; Tue, 02 Aug 2016 15:39:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bUfXa-0003Vk-FB for qemu-devel@nongnu.org; Tue, 02 Aug 2016 15:39:52 -0400 Received: from mail-wm0-x241.google.com ([2a00:1450:400c:c09::241]:36709) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bUfXa-0003VK-4y for qemu-devel@nongnu.org; Tue, 02 Aug 2016 15:39:50 -0400 Received: by mail-wm0-x241.google.com with SMTP id x83so32541380wma.3 for ; Tue, 02 Aug 2016 12:39:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=0AGrYcWRQiBEuVJ/6xpiELeq3fMGI36m1WzCY3meVMo=; b=P916a2uNqCQfIle9VGIB4l5D8SnUtYnDQf4wWzbRjWthjdAod9YsD1HCOLX5uCyzkI K5WQ+HEIu/e/IETg6dQMpDYpOK06N3v5IuN+j4JEwfpeYZVgw+wNEwyNQmnCB7/CY9iR tfTPH4f8GZ3SAaCDTkqzk3qt5I0BAZ8Ct5UJHDse4fI6ynDDJJ7jzkJFQPlebVONo+ez zwMjVAstaivkxEpt5MH0rMZd5G5QDccSOt3RpT3WDudLY2mu+EjoyYL/xfsnovsrxVkm ZGI1slIaqNItdpmnrJT1ixV2nEeOlzU9ueQ08ZY02Z+6vDh3/dVMIC/wUH/MmVxQAYW+ n34A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=0AGrYcWRQiBEuVJ/6xpiELeq3fMGI36m1WzCY3meVMo=; b=EO2sf2mfU0JlN9IpuTuK27yK+UOc/OcbcinjuyoRfc1phF4clc5K60ItJSkGuPQ8hO Jz5bkksjmH9lSXCEIX7GSzo2WJdGylcWepHBQwWTbcotD2M5gnFrIbebEL9liwaAjMDM sws6cLffvTsRdoFYEle2mMb/2TsSLJRrIX7V54Z8X0MV2ORPnv7P4KZuP7QgoFOJBCJw mn1VSt2ol//ArlK9T47Xz4OPZo7dejxfsjVRAA/ZSPkOm1Y7LabBsACWtgci4a72UBO/ 44jTLNKO1LSknMV+rwMc8d9+oLB+pNnaecQortkG4N7Kre46ImBKpZ2idEP3JGqC7UOF UFow== X-Gm-Message-State: AEkoouttDQVan8uED14pUU6ZAXVurIov5KqfMQ/17NV7kkcSpbQXwnFW/J7SDErt2PENqw== X-Received: by 10.194.72.226 with SMTP id g2mr61349195wjv.70.1470166789097; Tue, 02 Aug 2016 12:39:49 -0700 (PDT) Received: from donizetti.lan (94-39-152-88.adsl-ull.clienti.tiscali.it. [94.39.152.88]) by smtp.gmail.com with ESMTPSA id v134sm23554568wmf.10.2016.08.02.12.39.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 02 Aug 2016 12:39:48 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Tue, 2 Aug 2016 21:39:18 +0200 Message-Id: <1470166775-3671-9-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1470166775-3671-1-git-send-email-pbonzini@redhat.com> References: <1470166775-3671-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c09::241 Subject: [Qemu-devel] [PULL 08/25] qht: do not segfault when gathering stats from an uninitialized qht X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Emilio G. Cota" Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: "Emilio G. Cota" So far, QHT functions assume that the passed qht has previously been initialized--otherwise they segfault. This patch makes an exception for qht_statistics_init, with the goal of simplifying calling code. For instance, qht_statistics_init is called from the 'info jit' dump, and given that under KVM the TB qht is never initialized, we get a segfault. Thus, instead of complicating the 'info jit' code with additional checks, let's allow passing an uninitialized qht to qht_statistics_init. While at it, add a test for this to test-qht. Before the patch (for $ qemu -enable-kvm [...]): (qemu) info jit [...] direct jump count 0 (0%) (2 jumps=0 0%) Program received signal SIGSEGV, Segmentation fault. After the patch the "TB hash buckets", "TB hash occupancy" and "TB hash avg chain" lines are omitted. (qemu) info jit [...] direct jump count 0 (0%) (2 jumps=0 0%) TB hash buckets 0/0 (-nan% head buckets used) TB hash occupancy nan% avg chain occ. Histogram: (null) TB hash avg chain nan buckets. Histogram: (null) [...] Reported by: Changlong Xie Signed-off-by: Emilio G. Cota Message-Id: <1469205390-14369-1-git-send-email-cota@braap.org> [Extract printing statistics to an entirely separate function. - Paolo] Signed-off-by: Paolo Bonzini --- tests/test-qht.c | 4 ++++ translate-all.c | 70 +++++++++++++++++++++++++++++++------------------------- util/qht.c | 7 +++++- 3 files changed, 49 insertions(+), 32 deletions(-) diff --git a/tests/test-qht.c b/tests/test-qht.c index f1d6283..46a64b6 100644 --- a/tests/test-qht.c +++ b/tests/test-qht.c @@ -95,8 +95,12 @@ static void iter_check(unsigned int count) static void qht_do_test(unsigned int mode, size_t init_entries) { + /* under KVM we might fetch stats from an uninitialized qht */ + check_n(0); + qht_init(&ht, 0, mode); + check_n(0); insert(0, N); check(0, N, true); check_n(N); diff --git a/translate-all.c b/translate-all.c index 0d47c1c..efeba29 100644 --- a/translate-all.c +++ b/translate-all.c @@ -1663,15 +1663,50 @@ void tb_flush_jmp_cache(CPUState *cpu, target_ulong addr) TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *)); } +static void print_qht_statistics(FILE *f, fprintf_function cpu_fprintf, + struct qht_stats hst) +{ + uint32_t hgram_opts; + size_t hgram_bins; + char *hgram; + + if (!hst.head_buckets) { + return; + } + cpu_fprintf(f, "TB hash buckets %zu/%zu (%0.2f%% head buckets used)\n", + hst.used_head_buckets, hst.head_buckets, + (double)hst.used_head_buckets / hst.head_buckets * 100); + + hgram_opts = QDIST_PR_BORDER | QDIST_PR_LABELS; + hgram_opts |= QDIST_PR_100X | QDIST_PR_PERCENT; + if (qdist_xmax(&hst.occupancy) - qdist_xmin(&hst.occupancy) == 1) { + hgram_opts |= QDIST_PR_NODECIMAL; + } + hgram = qdist_pr(&hst.occupancy, 10, hgram_opts); + cpu_fprintf(f, "TB hash occupancy %0.2f%% avg chain occ. Histogram: %s\n", + qdist_avg(&hst.occupancy) * 100, hgram); + g_free(hgram); + + hgram_opts = QDIST_PR_BORDER | QDIST_PR_LABELS; + hgram_bins = qdist_xmax(&hst.chain) - qdist_xmin(&hst.chain); + if (hgram_bins > 10) { + hgram_bins = 10; + } else { + hgram_bins = 0; + hgram_opts |= QDIST_PR_NODECIMAL | QDIST_PR_NOBINRANGE; + } + hgram = qdist_pr(&hst.chain, hgram_bins, hgram_opts); + cpu_fprintf(f, "TB hash avg chain %0.3f buckets. Histogram: %s\n", + qdist_avg(&hst.chain), hgram); + g_free(hgram); +} + void dump_exec_info(FILE *f, fprintf_function cpu_fprintf) { int i, target_code_size, max_target_code_size; int direct_jmp_count, direct_jmp2_count, cross_page; TranslationBlock *tb; struct qht_stats hst; - uint32_t hgram_opts; - size_t hgram_bins; - char *hgram; target_code_size = 0; max_target_code_size = 0; @@ -1724,34 +1759,7 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf) tcg_ctx.tb_ctx.nb_tbs : 0); qht_statistics_init(&tcg_ctx.tb_ctx.htable, &hst); - - cpu_fprintf(f, "TB hash buckets %zu/%zu (%0.2f%% head buckets used)\n", - hst.used_head_buckets, hst.head_buckets, - (double)hst.used_head_buckets / hst.head_buckets * 100); - - hgram_opts = QDIST_PR_BORDER | QDIST_PR_LABELS; - hgram_opts |= QDIST_PR_100X | QDIST_PR_PERCENT; - if (qdist_xmax(&hst.occupancy) - qdist_xmin(&hst.occupancy) == 1) { - hgram_opts |= QDIST_PR_NODECIMAL; - } - hgram = qdist_pr(&hst.occupancy, 10, hgram_opts); - cpu_fprintf(f, "TB hash occupancy %0.2f%% avg chain occ. Histogram: %s\n", - qdist_avg(&hst.occupancy) * 100, hgram); - g_free(hgram); - - hgram_opts = QDIST_PR_BORDER | QDIST_PR_LABELS; - hgram_bins = qdist_xmax(&hst.chain) - qdist_xmin(&hst.chain); - if (hgram_bins > 10) { - hgram_bins = 10; - } else { - hgram_bins = 0; - hgram_opts |= QDIST_PR_NODECIMAL | QDIST_PR_NOBINRANGE; - } - hgram = qdist_pr(&hst.chain, hgram_bins, hgram_opts); - cpu_fprintf(f, "TB hash avg chain %0.3f buckets. Histogram: %s\n", - qdist_avg(&hst.chain), hgram); - g_free(hgram); - + print_qht_statistics(f, cpu_fprintf, hst); qht_statistics_destroy(&hst); cpu_fprintf(f, "\nStatistics:\n"); diff --git a/util/qht.c b/util/qht.c index 28ce289..16a8d79 100644 --- a/util/qht.c +++ b/util/qht.c @@ -789,11 +789,16 @@ void qht_statistics_init(struct qht *ht, struct qht_stats *stats) map = atomic_rcu_read(&ht->map); - stats->head_buckets = map->n_buckets; stats->used_head_buckets = 0; stats->entries = 0; qdist_init(&stats->chain); qdist_init(&stats->occupancy); + /* bail out if the qht has not yet been initialized */ + if (unlikely(map == NULL)) { + stats->head_buckets = 0; + return; + } + stats->head_buckets = map->n_buckets; for (i = 0; i < map->n_buckets; i++) { struct qht_bucket *head = &map->buckets[i];