Message ID | 20221014170905.64069-6-adrian.hunter@intel.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp291052wrs; Fri, 14 Oct 2022 10:13:20 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6PJF0x01xApP/okojPeanwhFyl4lx9XPkfwQL4VQxJ+DECSJtO2d2xI9JJWFLBMGkQ28xP X-Received: by 2002:a17:907:2d06:b0:78d:50db:130e with SMTP id gs6-20020a1709072d0600b0078d50db130emr4326196ejc.371.1665767599726; Fri, 14 Oct 2022 10:13:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665767599; cv=none; d=google.com; s=arc-20160816; b=V7e0jPep/QUgvFaxNL6H+6l/jLI70qG9LJUWGbbA9Qy8/GSZk3wJhe9auJlTWGN6ed khG2dFxUZuiyJDYOTPIJukI+bbzEw3RfuJ5rKaGwBzDAtfXMjQib0j5RY4qvaDF7Stde +0jhTR06dO59ysVdgt11fnNE1s6igs4q+KKroOYg2k0YoeZsXaRbTjfI4lFJAN/kjDBx umfKrknArTSSohSqBa9ORDNvqmfcq2x9XYBtZX9/WIlzx+5jNrKAKW70fkE/Ylx6Qsa/ kK4M9PEFha0T+/QYdOPtrUPC9cSnHn5LbJJjvdiKCZYasZwQoJrbozD7WrwF0Hl+9mdG Q1jA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:organization :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=o53/4aNc+E13CXp4H20YRBY2z5ey25Hx9er/139oLaI=; b=ciuy7BBgqo2RZqgPAdjCIcxlaMhHucOtQbfDoUZgsIPm9C2Yb4U1gRxb3PPbdWh2U2 DQQhEhfR3TdAexKlO8BnWUmE05ImnjUqfkW6GYURYZi0z6fvv4nhmJbNNG1iy+WJdm6e LH7MUjfuDa5Hzvijjtj5VC1iSBfpx+2BXAkNhmMH/8xp9rOPaWpGAKFE/rnLcLoFniMs xk8CuokuqQN23zh/IQEISNizWqbbbvfbiMfnjIdJaFhUSJXMdD1+HTyG/5Y1Ecum6mqP vBu5ozQQUTzMom2OCdb2cnX+H3F/7BXNfqaHKyqLkMej+Ny+yoaHJ5K8rz+4e3kz1siZ W3/g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=U0IlDhdy; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id gn41-20020a1709070d2900b0077cfdda438csi2991696ejc.35.2022.10.14.10.12.51; Fri, 14 Oct 2022 10:13:19 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=U0IlDhdy; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231238AbiJNRKG (ORCPT <rfc822;ouuuleilei@gmail.com> + 99 others); Fri, 14 Oct 2022 13:10:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36292 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231235AbiJNRJ5 (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Fri, 14 Oct 2022 13:09:57 -0400 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 002361E730; Fri, 14 Oct 2022 10:09:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1665767386; x=1697303386; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=BfjeSY7KNgsN+P4GwvYyJZrJWkkSdPm7/zXQBtNNFk4=; b=U0IlDhdyvZhbsV/LC4L/j1/BucB5//BxJRMKM2PN19++Qq8qdTMpVeIu T5THxKIz3dWGHEX5lpO7pfdELg/9wZc6jV/O195D5TXsAcWGPvXOLNFah aYaXzb1+ayIEW0iEafBaTEDBg+m5L9+PMUEA5pXJxNJDaIKRCzoRizWRR DjfErPmmxPgx4ghOMZ4Zd+t1btcBBqR6pc5zrLhG0irIkxvGOJ2AlBfw0 d3EBGQETrbfF1I+ZdrKIS/XZZHe7kwA09cff9abixoHQEqnfbascTY8B9 p1dphRA8jLZp11OgC7+iJrfqHyjLIrAVd46Z7U3Hl2ISsa5O8Ne1EfoIW w==; X-IronPort-AV: E=McAfee;i="6500,9779,10500"; a="303041997" X-IronPort-AV: E=Sophos;i="5.95,184,1661842800"; d="scan'208";a="303041997" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Oct 2022 10:09:43 -0700 X-IronPort-AV: E=McAfee;i="6500,9779,10500"; a="696377013" X-IronPort-AV: E=Sophos;i="5.95,184,1661842800"; d="scan'208";a="696377013" Received: from ahunter6-mobl1.ger.corp.intel.com (HELO ahunter-VirtualBox.home\044ger.corp.intel.com) ([10.252.43.79]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Oct 2022 10:09:37 -0700 From: Adrian Hunter <adrian.hunter@intel.com> To: Arnaldo Carvalho de Melo <acme@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com>, Namhyung Kim <namhyung@kernel.org>, Ian Rogers <irogers@google.com>, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Subject: [PATCH 5/7] perf test: test_intel_pt.sh: Add jitdump test Date: Fri, 14 Oct 2022 20:09:03 +0300 Message-Id: <20221014170905.64069-6-adrian.hunter@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221014170905.64069-1-adrian.hunter@intel.com> References: <20221014170905.64069-1-adrian.hunter@intel.com> MIME-Version: 1.0 Organization: Intel Finland Oy, Registered Address: PL 281, 00181 Helsinki, Business Identity Code: 0357606 - 4, Domiciled in Helsinki Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746683926630931945?= X-GMAIL-MSGID: =?utf-8?q?1746683926630931945?= |
Series |
perf intel-pt: jitdump fix and test
|
|
Commit Message
Adrian Hunter
Oct. 14, 2022, 5:09 p.m. UTC
Add a test for decoding self-modifying code using a jitdump file.
The test creates a workload that uses self-modifying code and generates its
own jitdump file. The result is processed with perf inject --jit and
checked for decoding errors.
Note the test will fail without patch "perf inject: Fix GEN_ELF_TEXT_OFFSET
for jit" applied.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
tools/perf/tests/shell/test_intel_pt.sh | 162 ++++++++++++++++++++++++
1 file changed, 162 insertions(+)
Comments
Em Fri, Oct 14, 2022 at 08:09:03PM +0300, Adrian Hunter escreveu: > Add a test for decoding self-modifying code using a jitdump file. > > The test creates a workload that uses self-modifying code and generates its > own jitdump file. The result is processed with perf inject --jit and > checked for decoding errors. > > Note the test will fail without patch "perf inject: Fix GEN_ELF_TEXT_OFFSET > for jit" applied. > > Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> > --- > tools/perf/tests/shell/test_intel_pt.sh | 162 ++++++++++++++++++++++++ > 1 file changed, 162 insertions(+) > > diff --git a/tools/perf/tests/shell/test_intel_pt.sh b/tools/perf/tests/shell/test_intel_pt.sh > index 79dde57b561d..e0bf75981b9c 100755 > --- a/tools/perf/tests/shell/test_intel_pt.sh > +++ b/tools/perf/tests/shell/test_intel_pt.sh > @@ -22,6 +22,7 @@ outfile="${temp_dir}/test-out.txt" > errfile="${temp_dir}/test-err.txt" > workload="${temp_dir}/workload" > awkscript="${temp_dir}/awkscript" > +jitdump_workload="${temp_dir}/jitdump_workload" > > cleanup() > { > @@ -50,6 +51,13 @@ perf_record_no_decode() > perf record -B -N --no-bpf-event "$@" > } > > +# perf record for testing should not need BPF events > +perf_record_no_bpf() > +{ > + # Options for no BPF events > + perf record --no-bpf-event "$@" > +} > + > have_workload=false > cat << _end_of_file_ | /usr/bin/cc -o "${workload}" -xc - -pthread && have_workload=true > #include <time.h> > @@ -269,6 +277,159 @@ test_per_thread() > return 0 > } > > +test_jitdump() > +{ > + echo "--- Test tracing self-modifying code that uses jitdump ---" > + > + script_path=$(realpath "$0") > + script_dir=$(dirname "$script_path") > + jitdump_incl_dir="${script_dir}/../../util" > + jitdump_h="${jitdump_incl_dir}/jitdump.h" So this requires one to test this being on the kernel (perf) sources dir? I think we should add this header to some 'perf test' directory to remove this requirement, ok? But this can be done on top, right now we just don't test jitdump: fd 20 : idx 11: mmapping fd 20 Checking 16 fds OK --- Test tracing self-modifying code that uses jitdump --- SKIP: Include file jitdump.h not found --- Cleaning up --- --- Done --- test child finished with 0 ---- end ---- Miscellaneous Intel PT testing: Ok > + if [ ! -e "${jitdump_h}" ] ; then > + echo "SKIP: Include file jitdump.h not found" > + return 2 > + fi > + > + if [ -z "${have_jitdump_workload}" ] ; then > + have_jitdump_workload=false > + # Create a workload that uses self-modifying code and generates its own jitdump file > + cat <<- "_end_of_file_" | /usr/bin/cc -o "${jitdump_workload}" -I "${jitdump_incl_dir}" -xc - -pthread && have_jitdump_workload=true > + #define _GNU_SOURCE > + #include <sys/mman.h> > + #include <sys/types.h> > + #include <stddef.h> > + #include <stdio.h> > + #include <stdint.h> > + #include <unistd.h> > + #include <string.h> > + > + #include "jitdump.h" > + > + #define CHK_BYTE 0x5a > + > + static inline uint64_t rdtsc(void) > + { > + unsigned int low, high; > + > + asm volatile("rdtsc" : "=a" (low), "=d" (high)); > + > + return low | ((uint64_t)high) << 32; > + } > + > + static FILE *open_jitdump(void) > + { > + struct jitheader header = { > + .magic = JITHEADER_MAGIC, > + .version = JITHEADER_VERSION, > + .total_size = sizeof(header), > + .pid = getpid(), > + .timestamp = rdtsc(), > + .flags = JITDUMP_FLAGS_ARCH_TIMESTAMP, > + }; > + char filename[256]; > + FILE *f; > + void *m; > + > + snprintf(filename, sizeof(filename), "jit-%d.dump", getpid()); > + f = fopen(filename, "w+"); > + if (!f) > + goto err; > + /* Create an MMAP event for the jitdump file. That is how perf tool finds it. */ > + m = mmap(0, 4096, PROT_READ | PROT_EXEC, MAP_PRIVATE, fileno(f), 0); > + if (m == MAP_FAILED) > + goto err_close; > + munmap(m, 4096); > + if (fwrite(&header,sizeof(header),1,f) != 1) > + goto err_close; > + return f; > + > + err_close: > + fclose(f); > + err: > + return NULL; > + } > + > + static int write_jitdump(FILE *f, void *addr, const uint8_t *dat, size_t sz, uint64_t *idx) > + { > + struct jr_code_load rec = { > + .p.id = JIT_CODE_LOAD, > + .p.total_size = sizeof(rec) + sz, > + .p.timestamp = rdtsc(), > + .pid = getpid(), > + .tid = gettid(), > + .vma = (unsigned long)addr, > + .code_addr = (unsigned long)addr, > + .code_size = sz, > + .code_index = ++*idx, > + }; > + > + if (fwrite(&rec,sizeof(rec),1,f) != 1 || > + fwrite(dat, sz, 1, f) != 1) > + return -1; > + return 0; > + } > + > + static void close_jitdump(FILE *f) > + { > + fclose(f); > + } > + > + int main() > + { > + /* Get a memory page to store executable code */ > + void *addr = mmap(0, 4096, PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); > + /* Code to execute: mov CHK_BYTE, %eax ; ret */ > + uint8_t dat[] = {0xb8, CHK_BYTE, 0x00, 0x00, 0x00, 0xc3}; > + FILE *f = open_jitdump(); > + uint64_t idx = 0; > + int ret = 1; > + > + if (!f) > + return 1; > + /* Copy executable code to executable memory page */ > + memcpy(addr, dat, sizeof(dat)); > + /* Record it in the jitdump file */ > + if (write_jitdump(f, addr, dat, sizeof(dat), &idx)) > + goto out_close; > + /* Call it */ > + ret = ((int (*)(void))addr)() - CHK_BYTE; > + out_close: > + close_jitdump(f); > + return ret; > + } > + _end_of_file_ > + fi > + > + if ! $have_jitdump_workload ; then > + echo "SKIP: No jitdump workload" > + return 2 > + fi > + > + # Change to temp_dir so jitdump collateral files go there > + cd "${temp_dir}" > + perf_record_no_bpf -o "${tmpfile}" -e intel_pt//u "${jitdump_workload}" > + perf inject -i "${tmpfile}" -o "${perfdatafile}" --jit > + decode_br_cnt=$(perf script -i "${perfdatafile}" --itrace=b | wc -l) > + # Note that overflow and lost errors are suppressed for the error count > + decode_err_cnt=$(perf script -i "${perfdatafile}" --itrace=e-o-l | grep -ci error) > + cd - > + # Should be thousands of branches > + if [ "${decode_br_cnt}" -lt 1000 ] ; then > + echo "Decode failed, only ${decode_br_cnt} branches" > + return 1 > + fi > + # Should be no errors > + if [ "${decode_err_cnt}" -ne 0 ] ; then > + echo "Decode failed, ${decode_err_cnt} errors" > + perf script -i "${perfdatafile}" --itrace=e-o-l > + return 1 > + fi > + > + echo OK > + return 0 > +} > + > count_result() > { > if [ "$1" -eq 2 ] ; then > @@ -286,6 +447,7 @@ ret=0 > test_system_wide_side_band || ret=$? ; count_result $ret ; ret=0 > test_per_thread "" "" || ret=$? ; count_result $ret ; ret=0 > test_per_thread "k" "(incl. kernel) " || ret=$? ; count_result $ret ; ret=0 > +test_jitdump || ret=$? ; count_result $ret ; ret=0 > > cleanup > > -- > 2.25.1
Em Fri, Oct 14, 2022 at 02:28:58PM -0300, Arnaldo Carvalho de Melo escreveu: > Em Fri, Oct 14, 2022 at 08:09:03PM +0300, Adrian Hunter escreveu: > > Add a test for decoding self-modifying code using a jitdump file. > > > > The test creates a workload that uses self-modifying code and generates its > > own jitdump file. The result is processed with perf inject --jit and > > checked for decoding errors. > > > > Note the test will fail without patch "perf inject: Fix GEN_ELF_TEXT_OFFSET > > for jit" applied. > > > > Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> > > --- > > tools/perf/tests/shell/test_intel_pt.sh | 162 ++++++++++++++++++++++++ > > 1 file changed, 162 insertions(+) > > > > diff --git a/tools/perf/tests/shell/test_intel_pt.sh b/tools/perf/tests/shell/test_intel_pt.sh > > index 79dde57b561d..e0bf75981b9c 100755 > > --- a/tools/perf/tests/shell/test_intel_pt.sh > > +++ b/tools/perf/tests/shell/test_intel_pt.sh > > @@ -22,6 +22,7 @@ outfile="${temp_dir}/test-out.txt" > > errfile="${temp_dir}/test-err.txt" > > workload="${temp_dir}/workload" > > awkscript="${temp_dir}/awkscript" > > +jitdump_workload="${temp_dir}/jitdump_workload" > > > > cleanup() > > { > > @@ -50,6 +51,13 @@ perf_record_no_decode() > > perf record -B -N --no-bpf-event "$@" > > } > > > > +# perf record for testing should not need BPF events > > +perf_record_no_bpf() > > +{ > > + # Options for no BPF events > > + perf record --no-bpf-event "$@" > > +} > > + > > have_workload=false > > cat << _end_of_file_ | /usr/bin/cc -o "${workload}" -xc - -pthread && have_workload=true > > #include <time.h> > > @@ -269,6 +277,159 @@ test_per_thread() > > return 0 > > } > > > > +test_jitdump() > > +{ > > + echo "--- Test tracing self-modifying code that uses jitdump ---" > > + > > + script_path=$(realpath "$0") > > + script_dir=$(dirname "$script_path") > > + jitdump_incl_dir="${script_dir}/../../util" > > + jitdump_h="${jitdump_incl_dir}/jitdump.h" > > So this requires one to test this being on the kernel (perf) sources > dir? I think we should add this header to some 'perf test' directory to > remove this requirement, ok? > > But this can be done on top, right now we just don't test jitdump: > > fd 20 : idx 11: mmapping fd 20 > Checking 16 fds > OK > --- Test tracing self-modifying code that uses jitdump --- > SKIP: Include file jitdump.h not found > --- Cleaning up --- > --- Done --- > test child finished with 0 > ---- end ---- > Miscellaneous Intel PT testing: Ok Actually: --- Test tracing self-modifying code that uses jitdump --- [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.018 MB /tmp/perf-test-intel-pt-sh.GJoKOxGVFY/tmp-perf.data ] Warning: 1 instruction trace errors /home/acme/git/perf Decode failed, 1 errors Warning: 1 instruction trace errors instruction trace error type 1 time 494778.777081924 cpu 3 pid 309650 tid 309650 ip 0x7f0972f22009 code 5: Failed to get instruction --- Cleaning up --- --- Done --- test child finished with -1 ---- end ---- Miscellaneous Intel PT testing: FAILED! [root@quaco perf]# [root@quaco perf]# pwd /home/acme/git/perf Multiple runs end up failing, processor info: [root@quaco perf]# grep -m1 -A26 vendor_id /proc/cpuinfo vendor_id : GenuineIntel cpu family : 6 model : 142 model name : Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz stepping : 10 microcode : 0xf0 cpu MHz : 2100.000 cache size : 8192 KB physical id : 0 siblings : 8 core id : 0 cpu cores : 4 apicid : 0 initial apicid : 0 fpu : yes fpu_exception : yes cpuid level : 22 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d arch_capabilities vmx flags : vnmi preemption_timer invvpid ept_x_only ept_ad ept_1gb flexpriority tsc_offset vtpr mtf vapic ept vpid unrestricted_guest ple shadow_vmcs pml ept_mode_based_exec bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs taa itlb_multihit srbds mmio_stale_data retbleed bogomips : 4199.88 clflush size : 64 cache_alignment : 64 address sizes : 39 bits physical, 48 bits virtual power management: [root@quaco perf]#
Em Fri, Oct 14, 2022 at 02:32:19PM -0300, Arnaldo Carvalho de Melo escreveu: > Em Fri, Oct 14, 2022 at 02:28:58PM -0300, Arnaldo Carvalho de Melo escreveu: > > Miscellaneous Intel PT testing: Ok > Actually: > --- Test tracing self-modifying code that uses jitdump --- > [ perf record: Woken up 1 times to write data ] > [ perf record: Captured and wrote 0.018 MB /tmp/perf-test-intel-pt-sh.GJoKOxGVFY/tmp-perf.data ] > > Warning: > 1 instruction trace errors > /home/acme/git/perf > Decode failed, 1 errors > Warning: > 1 instruction trace errors > instruction trace error type 1 time 494778.777081924 cpu 3 pid 309650 tid 309650 ip 0x7f0972f22009 code 5: Failed to get instruction > --- Cleaning up --- > --- Done --- > test child finished with -1 > ---- end ---- > Miscellaneous Intel PT testing: FAILED! > [root@quaco perf]# > [root@quaco perf]# pwd > /home/acme/git/perf I see... nevermind, this is what is expected, failing now, then the fix, then stops failing, nothing to see here, move along 8-) - Arnaldo
Em Fri, Oct 14, 2022 at 02:33:39PM -0300, Arnaldo Carvalho de Melo escreveu: > Em Fri, Oct 14, 2022 at 02:32:19PM -0300, Arnaldo Carvalho de Melo escreveu: > > Em Fri, Oct 14, 2022 at 02:28:58PM -0300, Arnaldo Carvalho de Melo escreveu: > > > Miscellaneous Intel PT testing: Ok > > > Actually: > > > --- Test tracing self-modifying code that uses jitdump --- > > [ perf record: Woken up 1 times to write data ] > > [ perf record: Captured and wrote 0.018 MB /tmp/perf-test-intel-pt-sh.GJoKOxGVFY/tmp-perf.data ] > > > > Warning: > > 1 instruction trace errors > > /home/acme/git/perf > > Decode failed, 1 errors > > Warning: > > 1 instruction trace errors > > instruction trace error type 1 time 494778.777081924 cpu 3 pid 309650 tid 309650 ip 0x7f0972f22009 code 5: Failed to get instruction > > --- Cleaning up --- > > --- Done --- > > test child finished with -1 > > ---- end ---- > > Miscellaneous Intel PT testing: FAILED! > > [root@quaco perf]# > > [root@quaco perf]# pwd > > /home/acme/git/perf > > I see... nevermind, this is what is expected, failing now, then the fix, > then stops failing, nothing to see here, move along 8-) Just for completeness sake, after the genelf.h fix: [root@quaco perf]# perf test "Miscellaneous Intel PT testing" 110: Miscellaneous Intel PT testing : Ok [root@quaco perf]# perf test -v "Miscellaneous Intel PT testing" 110: Miscellaneous Intel PT testing : --- start --- test child forked, pid 314597 --- Test system-wide sideband --- Checking for CPU-wide recording on CPU 0 OK Checking for CPU-wide recording on CPU 1 OK Linux [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 1.189 MB /tmp/perf-test-intel-pt-sh.TRr45lCVrl/test-perf.data ] OK --- Test per-thread recording --- Workload PIDs are 314619 and 314620 perf PID is 314631 Waiting for "perf record has started" message OK pid 314619 cpu -1 fd 5 : sys_perf_event_open: pid 314619 cpu -1 group_fd -1 flags 0x8 = 5 pid 314623 cpu -1 fd 6 : sys_perf_event_open: pid 314623 cpu -1 group_fd -1 flags 0x8 = 6 pid 314620 cpu -1 fd 7 : sys_perf_event_open: pid 314620 cpu -1 group_fd -1 flags 0x8 = 7 pid 314622 cpu -1 fd 8 : sys_perf_event_open: pid 314622 cpu -1 group_fd -1 flags 0x8 = 8 pid 314619 cpu -1 fd 9 : sys_perf_event_open: pid 314619 cpu -1 group_fd -1 flags 0x8 = 9 pid 314623 cpu -1 fd 10 : sys_perf_event_open: pid 314623 cpu -1 group_fd -1 flags 0x8 = 10 pid 314620 cpu -1 fd 11 : sys_perf_event_open: pid 314620 cpu -1 group_fd -1 flags 0x8 = 11 pid 314622 cpu -1 fd 12 : sys_perf_event_open: pid 314622 cpu -1 group_fd -1 flags 0x8 = 12 fd 5 : idx 0: mmapping fd 5 fd 9 fd_to 5 : idx 0: set output fd 9 -> 5 fd 6 : idx 1: mmapping fd 6 fd 10 fd_to 6 : idx 1: set output fd 10 -> 6 fd 7 : idx 2: mmapping fd 7 fd 11 fd_to 7 : idx 2: set output fd 11 -> 7 fd 8 : idx 3: mmapping fd 8 fd 12 fd_to 8 : idx 3: set output fd 12 -> 8 Checking 8 fds OK --- Test per-thread (incl. kernel) recording --- Workload PIDs are 315355 and 315356 perf PID is 315367 Waiting for "perf record has started" message OK pid 315355 cpu -1 fd 5 : sys_perf_event_open: pid 315355 cpu -1 group_fd -1 flags 0x8 = 5 pid 315358 cpu -1 fd 6 : sys_perf_event_open: pid 315358 cpu -1 group_fd -1 flags 0x8 = 6 pid 315356 cpu -1 fd 7 : sys_perf_event_open: pid 315356 cpu -1 group_fd -1 flags 0x8 = 7 pid 315359 cpu -1 fd 8 : sys_perf_event_open: pid 315359 cpu -1 group_fd -1 flags 0x8 = 8 pid 315355 cpu -1 fd 9 : sys_perf_event_open: pid 315355 cpu -1 group_fd -1 flags 0x8 = 9 pid 315358 cpu -1 fd 10 : sys_perf_event_open: pid 315358 cpu -1 group_fd -1 flags 0x8 = 10 pid 315356 cpu -1 fd 11 : sys_perf_event_open: pid 315356 cpu -1 group_fd -1 flags 0x8 = 11 pid 315359 cpu -1 fd 12 : sys_perf_event_open: pid 315359 cpu -1 group_fd -1 flags 0x8 = 12 pid -1 cpu 0 fd 13 : sys_perf_event_open: pid -1 cpu 0 group_fd -1 flags 0x8 = 13 pid -1 cpu 1 fd 14 : sys_perf_event_open: pid -1 cpu 1 group_fd -1 flags 0x8 = 14 pid -1 cpu 2 fd 15 : sys_perf_event_open: pid -1 cpu 2 group_fd -1 flags 0x8 = 15 pid -1 cpu 3 fd 16 : sys_perf_event_open: pid -1 cpu 3 group_fd -1 flags 0x8 = 16 pid -1 cpu 4 fd 17 : sys_perf_event_open: pid -1 cpu 4 group_fd -1 flags 0x8 = 17 pid -1 cpu 5 fd 18 : sys_perf_event_open: pid -1 cpu 5 group_fd -1 flags 0x8 = 18 pid -1 cpu 6 fd 19 : sys_perf_event_open: pid -1 cpu 6 group_fd -1 flags 0x8 = 19 pid -1 cpu 7 fd 20 : sys_perf_event_open: pid -1 cpu 7 group_fd -1 flags 0x8 = 20 fd 5 : idx 0: mmapping fd 5 fd 9 fd_to 5 : idx 0: set output fd 9 -> 5 fd 6 : idx 1: mmapping fd 6 fd 10 fd_to 6 : idx 1: set output fd 10 -> 6 fd 7 : idx 2: mmapping fd 7 fd 11 fd_to 7 : idx 2: set output fd 11 -> 7 fd 8 : idx 3: mmapping fd 8 fd 12 fd_to 8 : idx 3: set output fd 12 -> 8 fd 13 : idx 4: mmapping fd 13 fd 14 : idx 5: mmapping fd 14 fd 15 : idx 6: mmapping fd 15 fd 16 : idx 7: mmapping fd 16 fd 17 : idx 8: mmapping fd 17 fd 18 : idx 9: mmapping fd 18 fd 19 : idx 10: mmapping fd 19 fd 20 : idx 11: mmapping fd 20 Checking 16 fds OK --- Test tracing self-modifying code that uses jitdump --- [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.021 MB /tmp/perf-test-intel-pt-sh.TRr45lCVrl/tmp-perf.data ] /home/acme/git/perf OK --- Cleaning up --- --- Done --- test child finished with 0 ---- end ---- Miscellaneous Intel PT testing: Ok [root@quaco perf]#
On 17/10/22 16:44, Arnaldo Carvalho de Melo wrote: > Em Mon, Oct 17, 2022 at 03:57:03PM +0300, Adrian Hunter escreveu: >> On 14/10/22 20:28, Arnaldo Carvalho de Melo wrote: >>> Em Fri, Oct 14, 2022 at 08:09:03PM +0300, Adrian Hunter escreveu: >>>> Add a test for decoding self-modifying code using a jitdump file. >>>> >>>> The test creates a workload that uses self-modifying code and generates its >>>> own jitdump file. The result is processed with perf inject --jit and >>>> checked for decoding errors. >>>> >>>> Note the test will fail without patch "perf inject: Fix GEN_ELF_TEXT_OFFSET >>>> for jit" applied. >>>> >>>> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> >>>> --- >>>> tools/perf/tests/shell/test_intel_pt.sh | 162 ++++++++++++++++++++++++ >>>> 1 file changed, 162 insertions(+) >>>> >>>> diff --git a/tools/perf/tests/shell/test_intel_pt.sh b/tools/perf/tests/shell/test_intel_pt.sh >>>> index 79dde57b561d..e0bf75981b9c 100755 >>>> --- a/tools/perf/tests/shell/test_intel_pt.sh >>>> +++ b/tools/perf/tests/shell/test_intel_pt.sh >>>> @@ -22,6 +22,7 @@ outfile="${temp_dir}/test-out.txt" >>>> errfile="${temp_dir}/test-err.txt" >>>> workload="${temp_dir}/workload" >>>> awkscript="${temp_dir}/awkscript" >>>> +jitdump_workload="${temp_dir}/jitdump_workload" >>>> >>>> cleanup() >>>> { >>>> @@ -50,6 +51,13 @@ perf_record_no_decode() >>>> perf record -B -N --no-bpf-event "$@" >>>> } >>>> >>>> +# perf record for testing should not need BPF events >>>> +perf_record_no_bpf() >>>> +{ >>>> + # Options for no BPF events >>>> + perf record --no-bpf-event "$@" >>>> +} >>>> + >>>> have_workload=false >>>> cat << _end_of_file_ | /usr/bin/cc -o "${workload}" -xc - -pthread && have_workload=true >>>> #include <time.h> >>>> @@ -269,6 +277,159 @@ test_per_thread() >>>> return 0 >>>> } >>>> >>>> +test_jitdump() >>>> +{ >>>> + echo "--- Test tracing self-modifying code that uses jitdump ---" >>>> + >>>> + script_path=$(realpath "$0") >>>> + script_dir=$(dirname "$script_path") >>>> + jitdump_incl_dir="${script_dir}/../../util" >>>> + jitdump_h="${jitdump_incl_dir}/jitdump.h" >>> >>> So this requires one to test this being on the kernel (perf) sources >>> dir? I think we should add this header to some 'perf test' directory to >>> remove this requirement, ok? >>> >> >> How about this: > > Better, but see below > >> From: Adrian Hunter <adrian.hunter@intel.com> >> Date: Mon, 17 Oct 2022 15:14:25 +0300 >> Subject: [PATCH] perf test: test_intel_pt.sh: Install jitdump.h for use by >> tests >> >> test_intel_pt.sh builds a workload for testing jitdump and the workload >> includes file jitdump.h. >> >> Currently, test_intel_pt.sh finds jitdump.h assuming the test is run in >> the kernel source directory, and skips that test if it is not found. >> >> To improve that situation, amend the build to install the jitdump.h file >> in the test shell directory, and look there first, falling back to the >> original way if that is not found. >> >> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> >> --- >> tools/perf/Makefile.perf | 1 + >> tools/perf/tests/shell/test_intel_pt.sh | 12 +++++++++--- >> 2 files changed, 10 insertions(+), 3 deletions(-) >> >> diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf >> index a432e59afc42..c4ec66194465 100644 >> --- a/tools/perf/Makefile.perf >> +++ b/tools/perf/Makefile.perf >> @@ -1013,6 +1013,7 @@ install-tests: all install-gtk >> $(INSTALL) tests/attr/* -m 644 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \ >> $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \ >> $(INSTALL) tests/shell/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \ >> + $(INSTALL) util/jitdump.h -m 644 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \ >> $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \ >> $(INSTALL) tests/shell/lib/*.sh -m 644 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \ >> $(INSTALL) tests/shell/lib/*.py -m 644 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \ >> diff --git a/tools/perf/tests/shell/test_intel_pt.sh b/tools/perf/tests/shell/test_intel_pt.sh >> index 4c0aabbe33bd..3abf803f96b9 100755 >> --- a/tools/perf/tests/shell/test_intel_pt.sh >> +++ b/tools/perf/tests/shell/test_intel_pt.sh >> @@ -284,14 +284,20 @@ test_jitdump() >> >> script_path=$(realpath "$0") >> script_dir=$(dirname "$script_path") >> - jitdump_incl_dir="${script_dir}/../../util" >> + jitdump_incl_dir="${script_dir}" >> jitdump_h="${jitdump_incl_dir}/jitdump.h" >> >> if [ ! -e "${jitdump_h}" ] ; then >> - echo "SKIP: Include file jitdump.h not found" >> - return 2 >> + jitdump_incl_dir="${script_dir}/../../util" >> + jitdump_h="${jitdump_incl_dir}/jitdump.h" >> + if [ ! -e "${jitdump_h}" ] ; then >> + echo "SKIP: Include file jitdump.h not found" >> + return 2 >> + fi >> fi >> >> + echo "Using include file: ${jitdump_h}" > > Shouldn't this appear only with -v? Yes, but shell scripts do not process -v. Instead all output is suppressed by perf test unless -v is used. So it should be OK? > > - Arnaldo > >> + >> if [ -z "${have_jitdump_workload}" ] ; then >> have_jitdump_workload=false >> # Create a workload that uses self-modifying code and generates its own jitdump file
On 14/10/22 20:28, Arnaldo Carvalho de Melo wrote: > Em Fri, Oct 14, 2022 at 08:09:03PM +0300, Adrian Hunter escreveu: >> Add a test for decoding self-modifying code using a jitdump file. >> >> The test creates a workload that uses self-modifying code and generates its >> own jitdump file. The result is processed with perf inject --jit and >> checked for decoding errors. >> >> Note the test will fail without patch "perf inject: Fix GEN_ELF_TEXT_OFFSET >> for jit" applied. >> >> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> >> --- >> tools/perf/tests/shell/test_intel_pt.sh | 162 ++++++++++++++++++++++++ >> 1 file changed, 162 insertions(+) >> >> diff --git a/tools/perf/tests/shell/test_intel_pt.sh b/tools/perf/tests/shell/test_intel_pt.sh >> index 79dde57b561d..e0bf75981b9c 100755 >> --- a/tools/perf/tests/shell/test_intel_pt.sh >> +++ b/tools/perf/tests/shell/test_intel_pt.sh >> @@ -22,6 +22,7 @@ outfile="${temp_dir}/test-out.txt" >> errfile="${temp_dir}/test-err.txt" >> workload="${temp_dir}/workload" >> awkscript="${temp_dir}/awkscript" >> +jitdump_workload="${temp_dir}/jitdump_workload" >> >> cleanup() >> { >> @@ -50,6 +51,13 @@ perf_record_no_decode() >> perf record -B -N --no-bpf-event "$@" >> } >> >> +# perf record for testing should not need BPF events >> +perf_record_no_bpf() >> +{ >> + # Options for no BPF events >> + perf record --no-bpf-event "$@" >> +} >> + >> have_workload=false >> cat << _end_of_file_ | /usr/bin/cc -o "${workload}" -xc - -pthread && have_workload=true >> #include <time.h> >> @@ -269,6 +277,159 @@ test_per_thread() >> return 0 >> } >> >> +test_jitdump() >> +{ >> + echo "--- Test tracing self-modifying code that uses jitdump ---" >> + >> + script_path=$(realpath "$0") >> + script_dir=$(dirname "$script_path") >> + jitdump_incl_dir="${script_dir}/../../util" >> + jitdump_h="${jitdump_incl_dir}/jitdump.h" > > So this requires one to test this being on the kernel (perf) sources > dir? I think we should add this header to some 'perf test' directory to > remove this requirement, ok? > How about this: From: Adrian Hunter <adrian.hunter@intel.com> Date: Mon, 17 Oct 2022 15:14:25 +0300 Subject: [PATCH] perf test: test_intel_pt.sh: Install jitdump.h for use by tests test_intel_pt.sh builds a workload for testing jitdump and the workload includes file jitdump.h. Currently, test_intel_pt.sh finds jitdump.h assuming the test is run in the kernel source directory, and skips that test if it is not found. To improve that situation, amend the build to install the jitdump.h file in the test shell directory, and look there first, falling back to the original way if that is not found. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> --- tools/perf/Makefile.perf | 1 + tools/perf/tests/shell/test_intel_pt.sh | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index a432e59afc42..c4ec66194465 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -1013,6 +1013,7 @@ install-tests: all install-gtk $(INSTALL) tests/attr/* -m 644 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \ $(INSTALL) tests/shell/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \ + $(INSTALL) util/jitdump.h -m 644 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \ $(INSTALL) tests/shell/lib/*.sh -m 644 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \ $(INSTALL) tests/shell/lib/*.py -m 644 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \ diff --git a/tools/perf/tests/shell/test_intel_pt.sh b/tools/perf/tests/shell/test_intel_pt.sh index 4c0aabbe33bd..3abf803f96b9 100755 --- a/tools/perf/tests/shell/test_intel_pt.sh +++ b/tools/perf/tests/shell/test_intel_pt.sh @@ -284,14 +284,20 @@ test_jitdump() script_path=$(realpath "$0") script_dir=$(dirname "$script_path") - jitdump_incl_dir="${script_dir}/../../util" + jitdump_incl_dir="${script_dir}" jitdump_h="${jitdump_incl_dir}/jitdump.h" if [ ! -e "${jitdump_h}" ] ; then - echo "SKIP: Include file jitdump.h not found" - return 2 + jitdump_incl_dir="${script_dir}/../../util" + jitdump_h="${jitdump_incl_dir}/jitdump.h" + if [ ! -e "${jitdump_h}" ] ; then + echo "SKIP: Include file jitdump.h not found" + return 2 + fi fi + echo "Using include file: ${jitdump_h}" + if [ -z "${have_jitdump_workload}" ] ; then have_jitdump_workload=false # Create a workload that uses self-modifying code and generates its own jitdump file
Em Mon, Oct 17, 2022 at 03:57:03PM +0300, Adrian Hunter escreveu: > On 14/10/22 20:28, Arnaldo Carvalho de Melo wrote: > > Em Fri, Oct 14, 2022 at 08:09:03PM +0300, Adrian Hunter escreveu: > >> Add a test for decoding self-modifying code using a jitdump file. > >> > >> The test creates a workload that uses self-modifying code and generates its > >> own jitdump file. The result is processed with perf inject --jit and > >> checked for decoding errors. > >> > >> Note the test will fail without patch "perf inject: Fix GEN_ELF_TEXT_OFFSET > >> for jit" applied. > >> > >> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> > >> --- > >> tools/perf/tests/shell/test_intel_pt.sh | 162 ++++++++++++++++++++++++ > >> 1 file changed, 162 insertions(+) > >> > >> diff --git a/tools/perf/tests/shell/test_intel_pt.sh b/tools/perf/tests/shell/test_intel_pt.sh > >> index 79dde57b561d..e0bf75981b9c 100755 > >> --- a/tools/perf/tests/shell/test_intel_pt.sh > >> +++ b/tools/perf/tests/shell/test_intel_pt.sh > >> @@ -22,6 +22,7 @@ outfile="${temp_dir}/test-out.txt" > >> errfile="${temp_dir}/test-err.txt" > >> workload="${temp_dir}/workload" > >> awkscript="${temp_dir}/awkscript" > >> +jitdump_workload="${temp_dir}/jitdump_workload" > >> > >> cleanup() > >> { > >> @@ -50,6 +51,13 @@ perf_record_no_decode() > >> perf record -B -N --no-bpf-event "$@" > >> } > >> > >> +# perf record for testing should not need BPF events > >> +perf_record_no_bpf() > >> +{ > >> + # Options for no BPF events > >> + perf record --no-bpf-event "$@" > >> +} > >> + > >> have_workload=false > >> cat << _end_of_file_ | /usr/bin/cc -o "${workload}" -xc - -pthread && have_workload=true > >> #include <time.h> > >> @@ -269,6 +277,159 @@ test_per_thread() > >> return 0 > >> } > >> > >> +test_jitdump() > >> +{ > >> + echo "--- Test tracing self-modifying code that uses jitdump ---" > >> + > >> + script_path=$(realpath "$0") > >> + script_dir=$(dirname "$script_path") > >> + jitdump_incl_dir="${script_dir}/../../util" > >> + jitdump_h="${jitdump_incl_dir}/jitdump.h" > > > > So this requires one to test this being on the kernel (perf) sources > > dir? I think we should add this header to some 'perf test' directory to > > remove this requirement, ok? > > > > How about this: Better, but see below > From: Adrian Hunter <adrian.hunter@intel.com> > Date: Mon, 17 Oct 2022 15:14:25 +0300 > Subject: [PATCH] perf test: test_intel_pt.sh: Install jitdump.h for use by > tests > > test_intel_pt.sh builds a workload for testing jitdump and the workload > includes file jitdump.h. > > Currently, test_intel_pt.sh finds jitdump.h assuming the test is run in > the kernel source directory, and skips that test if it is not found. > > To improve that situation, amend the build to install the jitdump.h file > in the test shell directory, and look there first, falling back to the > original way if that is not found. > > Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> > --- > tools/perf/Makefile.perf | 1 + > tools/perf/tests/shell/test_intel_pt.sh | 12 +++++++++--- > 2 files changed, 10 insertions(+), 3 deletions(-) > > diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf > index a432e59afc42..c4ec66194465 100644 > --- a/tools/perf/Makefile.perf > +++ b/tools/perf/Makefile.perf > @@ -1013,6 +1013,7 @@ install-tests: all install-gtk > $(INSTALL) tests/attr/* -m 644 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \ > $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \ > $(INSTALL) tests/shell/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \ > + $(INSTALL) util/jitdump.h -m 644 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \ > $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \ > $(INSTALL) tests/shell/lib/*.sh -m 644 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \ > $(INSTALL) tests/shell/lib/*.py -m 644 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \ > diff --git a/tools/perf/tests/shell/test_intel_pt.sh b/tools/perf/tests/shell/test_intel_pt.sh > index 4c0aabbe33bd..3abf803f96b9 100755 > --- a/tools/perf/tests/shell/test_intel_pt.sh > +++ b/tools/perf/tests/shell/test_intel_pt.sh > @@ -284,14 +284,20 @@ test_jitdump() > > script_path=$(realpath "$0") > script_dir=$(dirname "$script_path") > - jitdump_incl_dir="${script_dir}/../../util" > + jitdump_incl_dir="${script_dir}" > jitdump_h="${jitdump_incl_dir}/jitdump.h" > > if [ ! -e "${jitdump_h}" ] ; then > - echo "SKIP: Include file jitdump.h not found" > - return 2 > + jitdump_incl_dir="${script_dir}/../../util" > + jitdump_h="${jitdump_incl_dir}/jitdump.h" > + if [ ! -e "${jitdump_h}" ] ; then > + echo "SKIP: Include file jitdump.h not found" > + return 2 > + fi > fi > > + echo "Using include file: ${jitdump_h}" Shouldn't this appear only with -v? - Arnaldo > + > if [ -z "${have_jitdump_workload}" ] ; then > have_jitdump_workload=false > # Create a workload that uses self-modifying code and generates its own jitdump file
diff --git a/tools/perf/tests/shell/test_intel_pt.sh b/tools/perf/tests/shell/test_intel_pt.sh index 79dde57b561d..e0bf75981b9c 100755 --- a/tools/perf/tests/shell/test_intel_pt.sh +++ b/tools/perf/tests/shell/test_intel_pt.sh @@ -22,6 +22,7 @@ outfile="${temp_dir}/test-out.txt" errfile="${temp_dir}/test-err.txt" workload="${temp_dir}/workload" awkscript="${temp_dir}/awkscript" +jitdump_workload="${temp_dir}/jitdump_workload" cleanup() { @@ -50,6 +51,13 @@ perf_record_no_decode() perf record -B -N --no-bpf-event "$@" } +# perf record for testing should not need BPF events +perf_record_no_bpf() +{ + # Options for no BPF events + perf record --no-bpf-event "$@" +} + have_workload=false cat << _end_of_file_ | /usr/bin/cc -o "${workload}" -xc - -pthread && have_workload=true #include <time.h> @@ -269,6 +277,159 @@ test_per_thread() return 0 } +test_jitdump() +{ + echo "--- Test tracing self-modifying code that uses jitdump ---" + + script_path=$(realpath "$0") + script_dir=$(dirname "$script_path") + jitdump_incl_dir="${script_dir}/../../util" + jitdump_h="${jitdump_incl_dir}/jitdump.h" + + if [ ! -e "${jitdump_h}" ] ; then + echo "SKIP: Include file jitdump.h not found" + return 2 + fi + + if [ -z "${have_jitdump_workload}" ] ; then + have_jitdump_workload=false + # Create a workload that uses self-modifying code and generates its own jitdump file + cat <<- "_end_of_file_" | /usr/bin/cc -o "${jitdump_workload}" -I "${jitdump_incl_dir}" -xc - -pthread && have_jitdump_workload=true + #define _GNU_SOURCE + #include <sys/mman.h> + #include <sys/types.h> + #include <stddef.h> + #include <stdio.h> + #include <stdint.h> + #include <unistd.h> + #include <string.h> + + #include "jitdump.h" + + #define CHK_BYTE 0x5a + + static inline uint64_t rdtsc(void) + { + unsigned int low, high; + + asm volatile("rdtsc" : "=a" (low), "=d" (high)); + + return low | ((uint64_t)high) << 32; + } + + static FILE *open_jitdump(void) + { + struct jitheader header = { + .magic = JITHEADER_MAGIC, + .version = JITHEADER_VERSION, + .total_size = sizeof(header), + .pid = getpid(), + .timestamp = rdtsc(), + .flags = JITDUMP_FLAGS_ARCH_TIMESTAMP, + }; + char filename[256]; + FILE *f; + void *m; + + snprintf(filename, sizeof(filename), "jit-%d.dump", getpid()); + f = fopen(filename, "w+"); + if (!f) + goto err; + /* Create an MMAP event for the jitdump file. That is how perf tool finds it. */ + m = mmap(0, 4096, PROT_READ | PROT_EXEC, MAP_PRIVATE, fileno(f), 0); + if (m == MAP_FAILED) + goto err_close; + munmap(m, 4096); + if (fwrite(&header,sizeof(header),1,f) != 1) + goto err_close; + return f; + + err_close: + fclose(f); + err: + return NULL; + } + + static int write_jitdump(FILE *f, void *addr, const uint8_t *dat, size_t sz, uint64_t *idx) + { + struct jr_code_load rec = { + .p.id = JIT_CODE_LOAD, + .p.total_size = sizeof(rec) + sz, + .p.timestamp = rdtsc(), + .pid = getpid(), + .tid = gettid(), + .vma = (unsigned long)addr, + .code_addr = (unsigned long)addr, + .code_size = sz, + .code_index = ++*idx, + }; + + if (fwrite(&rec,sizeof(rec),1,f) != 1 || + fwrite(dat, sz, 1, f) != 1) + return -1; + return 0; + } + + static void close_jitdump(FILE *f) + { + fclose(f); + } + + int main() + { + /* Get a memory page to store executable code */ + void *addr = mmap(0, 4096, PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + /* Code to execute: mov CHK_BYTE, %eax ; ret */ + uint8_t dat[] = {0xb8, CHK_BYTE, 0x00, 0x00, 0x00, 0xc3}; + FILE *f = open_jitdump(); + uint64_t idx = 0; + int ret = 1; + + if (!f) + return 1; + /* Copy executable code to executable memory page */ + memcpy(addr, dat, sizeof(dat)); + /* Record it in the jitdump file */ + if (write_jitdump(f, addr, dat, sizeof(dat), &idx)) + goto out_close; + /* Call it */ + ret = ((int (*)(void))addr)() - CHK_BYTE; + out_close: + close_jitdump(f); + return ret; + } + _end_of_file_ + fi + + if ! $have_jitdump_workload ; then + echo "SKIP: No jitdump workload" + return 2 + fi + + # Change to temp_dir so jitdump collateral files go there + cd "${temp_dir}" + perf_record_no_bpf -o "${tmpfile}" -e intel_pt//u "${jitdump_workload}" + perf inject -i "${tmpfile}" -o "${perfdatafile}" --jit + decode_br_cnt=$(perf script -i "${perfdatafile}" --itrace=b | wc -l) + # Note that overflow and lost errors are suppressed for the error count + decode_err_cnt=$(perf script -i "${perfdatafile}" --itrace=e-o-l | grep -ci error) + cd - + # Should be thousands of branches + if [ "${decode_br_cnt}" -lt 1000 ] ; then + echo "Decode failed, only ${decode_br_cnt} branches" + return 1 + fi + # Should be no errors + if [ "${decode_err_cnt}" -ne 0 ] ; then + echo "Decode failed, ${decode_err_cnt} errors" + perf script -i "${perfdatafile}" --itrace=e-o-l + return 1 + fi + + echo OK + return 0 +} + count_result() { if [ "$1" -eq 2 ] ; then @@ -286,6 +447,7 @@ ret=0 test_system_wide_side_band || ret=$? ; count_result $ret ; ret=0 test_per_thread "" "" || ret=$? ; count_result $ret ; ret=0 test_per_thread "k" "(incl. kernel) " || ret=$? ; count_result $ret ; ret=0 +test_jitdump || ret=$? ; count_result $ret ; ret=0 cleanup