Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf script python: Fix buffer size to report iregs in perf script

Commit 48a1f565261d2ab1 ("perf script python: Add more PMU fields to
event handler dict") added functionality to report fields like weight,
iregs, uregs etc via perf report. That commit predefined buffer size to
512 bytes to print those fields.

But in PowerPC, since we added extended regs support in:

068aeea3773a6f4c ("perf powerpc: Support exposing Performance Monitor Counter SPRs as part of extended regs")
d735599a069f6936 ("powerpc/perf: Add extended regs support for power10 platform")

Now iregs can carry more bytes of data and this predefined buffer size
can result to data loss in perf script output.

This patch resolves this issue by making the buffer size dynamic, based
on the number of registers needed to print. It also changes the
regs_map() return type from int to void, as it is not being used by the
set_regs_in_dict(), its only caller.

Fixes: 068aeea3773a6f4c ("perf powerpc: Support exposing Performance Monitor Counter SPRs as part of extended regs")
Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
Tested-by: Nageswara R Sastry <rnsastry@linux.ibm.com>
Cc: Athira Jajeev <atrajeev@linux.vnet.ibm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
Cc: Paul Clarke <pc@us.ibm.com>
Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
Cc: linuxppc-dev@lists.ozlabs.org
Link: http://lore.kernel.org/lkml/20210628062341.155839-1-kjain@linux.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Kajol Jain and committed by
Arnaldo Carvalho de Melo
dea8cfcc e63cbfa3

+12 -5
+12 -5
tools/perf/util/scripting-engines/trace-event-python.c
··· 687 687 _PyUnicode_FromString(decode)); 688 688 } 689 689 690 - static int regs_map(struct regs_dump *regs, uint64_t mask, char *bf, int size) 690 + static void regs_map(struct regs_dump *regs, uint64_t mask, char *bf, int size) 691 691 { 692 692 unsigned int i = 0, r; 693 693 int printed = 0; ··· 695 695 bf[0] = 0; 696 696 697 697 if (!regs || !regs->regs) 698 - return 0; 698 + return; 699 699 700 700 for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) { 701 701 u64 val = regs->regs[i++]; ··· 704 704 "%5s:0x%" PRIx64 " ", 705 705 perf_reg_name(r), val); 706 706 } 707 - 708 - return printed; 709 707 } 710 708 711 709 static void set_regs_in_dict(PyObject *dict, ··· 711 713 struct evsel *evsel) 712 714 { 713 715 struct perf_event_attr *attr = &evsel->core.attr; 714 - char bf[512]; 716 + 717 + /* 718 + * Here value 28 is a constant size which can be used to print 719 + * one register value and its corresponds to: 720 + * 16 chars is to specify 64 bit register in hexadecimal. 721 + * 2 chars is for appending "0x" to the hexadecimal value and 722 + * 10 chars is for register name. 723 + */ 724 + int size = __sw_hweight64(attr->sample_regs_intr) * 28; 725 + char bf[size]; 715 726 716 727 regs_map(&sample->intr_regs, attr->sample_regs_intr, bf, sizeof(bf)); 717 728