On 3/2/21 9:10 PM, Liang, Kan wrote: > > > On 3/2/2021 12:08 PM, Thomas Richter wrote: >> On 3/2/21 4:23 PM, Liang, Kan wrote: >>> >>> >>> On 3/2/2021 9:48 AM, Thomas Richter wrote: >>>> On 3/2/21 3:03 PM, Liang, Kan wrote: >>>>> >>>>> + Athira Rajeev >>>>> >>>>> On 3/2/2021 8:31 AM, Thomas Richter wrote: >>>>>> Executing perf test 27 fails on s390: >>>>>> [root@t35lp46 perf]# ./perf test -Fv 27 >>>>>> 27: Sample parsing >>>>>> --- start --- >>>>>> ---- end ---- >>>>>> Sample parsing: FAILED! >>>>>> [root@t35lp46 perf]# >>>>>> >>>>>> The root cause is >>>>>> commit c7444297fd3769 ("perf test: Support PERF_SAMPLE_WEIGHT_STRUCT") >>>>>> This commit introduced a test case for PERF_SAMPLE_WEIGHT_STRUCT >>>>>> but does not adjust non-x86 weak linkage functions. >>>>>> >>>>>> The error is in test__sample_parsing() --> do_test() >>>>>> Function do_test() defines two structures of type struct perf_sample >>>>>> named >>>>>> sample and sample_out. The first sets member sample.ins_lat = 117 >>>>>> >>>>>> Structure sample_out is constructed dynamically using functions >>>>>> perf_event__synthesize_sample() and evsel__parse_sample(). >>>>>> Both functions have an x86 specific function version which sets member >>>>>> ins_lat. The weak common functions do not set member ins_lat. >>>>>> >>>>> >>>>> I don't think Power supports the instruction latency. As a request from >>>>> Athira Rajeev, I moved the PERF_SAMPLE_WEIGHT_STRUCT to the X86 specific >>>>> codes. >>>>> https://lore.kernel.org/lkml/d97fef4f-dd88-4760-885e-9a6161a9b...@linux.vnet.ibm.com/ >>>>> https://lore.kernel.org/lkml/1612540912-6562-1-git-send-email-kan.li...@linux.intel.com/ >>>>> >>>>> I don't think we want to add the ins_lat back in the weak common >>>>> functions. >>>>> >>>>> Could you please update the perf test and don't apply the >>>>> PERF_SAMPLE_WEIGHT_STRUCT for the non-X86 platform? >>>> >>>> I used offical linux git tree >>>> [root@t35lp46 perf]# git tag | fgrep 5.12 >>>> v5.12-rc1 >>>> [root@t35lp46 perf]# >>>> >>>> So this change is in the pipe. I do not plan to revert individual patches. >>> >>> No, we shouldn't revert the patch. >>> I mean can you fix the issue in perf test? >>> Don't test ins_lat or PERF_SAMPLE_WEIGHT_STRUCT for a non-X86 platform. >> >> That would be very ugly code. We would end up in conditional compiles like >> #ifdef __s390x__ >> #endif >> and other architectes like ARM/POWER etc come along. This is something I >> want to avoid. >> > > The ins_lat is a model specific variable. Maybe we should move it to the arch > specific test. > > >> And this fix only touches perf, not the kernel. > > The patch changes the behavior of the PERF_SAMPLE_WEIGHT. The high 32 bit > will be dropped. It should bring some problems if the high 32 bit contains > valid information. > >> >>>>> >>>>> >>>>>> Later in function samples_same() both data in variable sample and >>>>>> sample_out >>>>>> are compared. The comparison fails because sample.ins_lat is 117 >>>>>> and samples_out.ins_lat is 0, the weak functions never set member >>>>>> ins_lat. >>>>>> >>>>>> Output after: >>>>>> [root@t35lp46 perf]# ./perf test -Fv 27 >>>>>> 27: Sample parsing >>>>>> --- start --- >>>>>> ---- end ---- >>>>>> Sample parsing: Ok >>>>>> [root@t35lp46 perf]# >>>>>> >>>>>> Fixes: >>>>>> commit c7444297fd3769 ("perf test: Support PERF_SAMPLE_WEIGHT_STRUCT") >>>>> >>>>> I think the regression should start from >>>>> commit fbefe9c2f87f ("perf tools: Support arch specific >>>>> PERF_SAMPLE_WEIGHT_STRUCT processing") >>>>> >>>>> >>>>> Thanks, >>>>> Kan >>>> >>>> Kan, >>>> >>>> I do not follow you. Your commit c7444297fd3769d10c7ffb52c81d71503b3e268f >>>> adds this line >>>> >>>> @@ -242,6 +245,7 @@ static int do_test(u64 sample_type, u64 sample_regs, >>>> u64 read_format) >>>> .cgroup = 114, >>>> .data_page_size = 115, >>>> .code_page_size = 116, >>>> + .ins_lat = 117, >>>> >>>> And this assignment 117 breaks the test. As mentioned before, member >>>> ins_lat is never touched >>>> by the weak functions. >>>> >>> >>> Here is the timeline for the patches. >>> >>> 1. The commit c7444297fd3769 and other SPR patches are merged at >>> 2021-02-08. At that time, I don't think we have this issue. perf test >>> should work well. >> >> Nope, that line above 'ins_lat = 117.' breaks the test. Comment it out and >> it works well!!! > > If you revert the commit fbefe9c2f87f, perf test should work well too. > > The root cause of the issue is that the commit fbefe9c2f87f change the > ins_lat to a model-specific variable, but perf test still verify the variable > in the generic test. > > The below patch moves the PERF_SAMPLE_WEIGHT test into a X86 specific test. > > Does it work for you? > > --- > tools/perf/arch/x86/include/arch-tests.h | 1 + > tools/perf/arch/x86/tests/Build | 1 + > tools/perf/arch/x86/tests/arch-tests.c | 4 + > tools/perf/arch/x86/tests/sample-parsing.c | 125 > +++++++++++++++++++++++++++++ > tools/perf/tests/sample-parsing.c | 4 - > 5 files changed, 131 insertions(+), 4 deletions(-) > create mode 100644 tools/perf/arch/x86/tests/sample-parsing.c > > diff --git a/tools/perf/arch/x86/include/arch-tests.h > b/tools/perf/arch/x86/include/arch-tests.h > index 6a54b94..0e20f3d 100644 > --- a/tools/perf/arch/x86/include/arch-tests.h > +++ b/tools/perf/arch/x86/include/arch-tests.h > @@ -10,6 +10,7 @@ int test__rdpmc(struct test *test __maybe_unused, int > subtest); > int test__insn_x86(struct test *test __maybe_unused, int subtest); > int test__intel_pt_pkt_decoder(struct test *test, int subtest); > int test__bp_modify(struct test *test, int subtest); > +int test__x86_sample_parsing(struct test *test, int subtest); > > #ifdef HAVE_DWARF_UNWIND_SUPPORT > struct thread; > diff --git a/tools/perf/arch/x86/tests/Build b/tools/perf/arch/x86/tests/Build > index 36d4f24..28d7933 100644 > --- a/tools/perf/arch/x86/tests/Build > +++ b/tools/perf/arch/x86/tests/Build > @@ -3,5 +3,6 @@ perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o > > perf-y += arch-tests.o > perf-y += rdpmc.o > +perf-y += sample-parsing.o > perf-$(CONFIG_AUXTRACE) += insn-x86.o intel-pt-pkt-decoder-test.o > perf-$(CONFIG_X86_64) += bp-modify.o > diff --git a/tools/perf/arch/x86/tests/arch-tests.c > b/tools/perf/arch/x86/tests/arch-tests.c > index bc25d72..71aa673 100644 > --- a/tools/perf/arch/x86/tests/arch-tests.c > +++ b/tools/perf/arch/x86/tests/arch-tests.c > @@ -31,6 +31,10 @@ struct test arch_tests[] = { > }, > #endif > { > + .desc = "x86 Sample parsing", > + .func = test__x86_sample_parsing, > + }, > + { > .func = NULL, > }, > > diff --git a/tools/perf/arch/x86/tests/sample-parsing.c > b/tools/perf/arch/x86/tests/sample-parsing.c > new file mode 100644 > index 0000000..28bbc61 > --- /dev/null > +++ b/tools/perf/arch/x86/tests/sample-parsing.c > @@ -0,0 +1,125 @@ > +// SPDX-License-Identifier: GPL-2.0 > +#include <stdbool.h> > +#include <inttypes.h> > +#include <stdlib.h> > +#include <string.h> > +#include <linux/bitops.h> > +#include <linux/kernel.h> > +#include <linux/types.h> > + > +#include "map_symbol.h" > +#include "branch.h" > +#include "event.h" > +#include "evsel.h" > +#include "debug.h" > +#include "util/synthetic-events.h" > + > +#include "tests/tests.h" > +#include "arch-tests.h" > + > +#define COMP(m) do { \ > + if (s1->m != s2->m) { \ > + pr_debug("Samples differ at '"#m"'\n"); \ > + return false; \ > + } \ > +} while (0) > + > +static bool samples_same(const struct perf_sample *s1, > + const struct perf_sample *s2, > + u64 type) > +{ > + if (type & PERF_SAMPLE_WEIGHT_STRUCT) > + COMP(ins_lat); > + > + return true; > +} > + > +static int do_test(u64 sample_type, u64 read_format) > +{ > + struct evsel evsel = { > + .needs_swap = false, > + .core = { > + . attr = { > + .sample_type = sample_type, > + .read_format = read_format, > + }, > + }, > + }; > + union perf_event *event; > + struct perf_sample sample = { > + .weight = 101, > + .ins_lat = 102, > + }; > + struct perf_sample sample_out; > + size_t i, sz, bufsz; > + int err, ret = -1; > + > + sz = perf_event__sample_event_size(&sample, sample_type, read_format); > + bufsz = sz + 4096; /* Add a bit for overrun checking */ > + event = malloc(bufsz); > + if (!event) { > + pr_debug("malloc failed\n"); > + return -1; > + } > + > + memset(event, 0xff, bufsz); > + event->header.type = PERF_RECORD_SAMPLE; > + event->header.misc = 0; > + event->header.size = sz; > + > + err = perf_event__synthesize_sample(event, sample_type, read_format, > + &sample); > + if (err) { > + pr_debug("%s failed for sample_type %#"PRIx64", error %d\n", > + "perf_event__synthesize_sample", sample_type, err); > + goto out_free; > + } > + > + /* The data does not contain 0xff so we use that to check the size */ > + for (i = bufsz; i > 0; i--) { > + if (*(i - 1 + (u8 *)event) != 0xff) > + break; > + } > + if (i != sz) { > + pr_debug("Event size mismatch: actual %zu vs expected %zu\n", > + i, sz); > + goto out_free; > + } > + > + evsel.sample_size = __evsel__sample_size(sample_type); > + > + err = evsel__parse_sample(&evsel, event, &sample_out); > + if (err) { > + pr_debug("%s failed for sample_type %#"PRIx64", error %d\n", > + "evsel__parse_sample", sample_type, err); > + goto out_free; > + } > + > + if (!samples_same(&sample, &sample_out, sample_type)) { > + pr_debug("parsing failed for sample_type %#"PRIx64"\n", > + sample_type); > + goto out_free; > + } > + > + ret = 0; > +out_free: > + free(event); > + if (ret && read_format) > + pr_debug("read_format %#"PRIx64"\n", read_format); > + return ret; > +} > + > +/** > + * test__x86_sample_parsing - test X86 specific sample parsing > + * > + * This function implements a test that synthesizes a sample event, parses it > + * and then checks that the parsed sample matches the original sample. The > test > + * checks sample format bits separately and together. If the test passes %0 > is > + * returned, otherwise %-1 is returned. > + * > + * For now, PERF_SAMPLE_WEIGHT_STRUCT is the only X86 specific sample type. > + */ > +int test__x86_sample_parsing(struct test *test __maybe_unused, int subtest > __maybe_unused) > +{ > + return do_test(PERF_SAMPLE_WEIGHT_STRUCT, 0); > +} > diff --git a/tools/perf/tests/sample-parsing.c > b/tools/perf/tests/sample-parsing.c > index 0dbe3aa..8fd8a4e 100644 > --- a/tools/perf/tests/sample-parsing.c > +++ b/tools/perf/tests/sample-parsing.c > @@ -129,9 +129,6 @@ static bool samples_same(const struct perf_sample *s1, > if (type & PERF_SAMPLE_WEIGHT) > COMP(weight); > > - if (type & PERF_SAMPLE_WEIGHT_STRUCT) > - COMP(ins_lat); > - > if (type & PERF_SAMPLE_DATA_SRC) > COMP(data_src); > > @@ -245,7 +242,6 @@ static int do_test(u64 sample_type, u64 sample_regs, u64 > read_format) > .cgroup = 114, > .data_page_size = 115, > .code_page_size = 116, > - .ins_lat = 117, > .aux_sample = { > .size = sizeof(aux_data), > .data = (void *)aux_data,
Thanks Kan, I had several issues applying your patch: (Stripping trailing CRs from patch; use --binary to disable.) patching file tools/perf/arch/x86/tests/sample-parsing.c patch: **** malformed patch at line 421: parses it ... [root@t35lp46 perf]# ./perf test -F 27 27: Sample parsing : Ok [root@t35lp46 perf]# But as you can see, after applying your patch, the test works fine on non-x86 platforms. You have my Tested-by: Please submit it to the mailing list. -- Thomas Richter, Dept 3303, IBM s390 Linux Development, Boeblingen, Germany -- Vorsitzender des Aufsichtsrats: Gregor Pillen Geschäftsführung: Dirk Wittkopp Sitz der Gesellschaft: Böblingen / Registergericht: Amtsgericht Stuttgart, HRB 243294