Commit dea8cfcc authored by Kajol Jain's avatar Kajol Jain Committed by Arnaldo Carvalho de Melo

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

Commit 48a1f565 ("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:

  068aeea3 ("perf powerpc: Support exposing Performance Monitor Counter SPRs as part of extended regs")
  d735599a ("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: 068aeea3 ("perf powerpc: Support exposing Performance Monitor Counter SPRs as part of extended regs")
Signed-off-by: default avatarKajol Jain <kjain@linux.ibm.com>
Tested-by: default avatarNageswara 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.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent e63cbfa3
...@@ -687,7 +687,7 @@ static void set_sample_datasrc_in_dict(PyObject *dict, ...@@ -687,7 +687,7 @@ static void set_sample_datasrc_in_dict(PyObject *dict,
_PyUnicode_FromString(decode)); _PyUnicode_FromString(decode));
} }
static int regs_map(struct regs_dump *regs, uint64_t mask, char *bf, int size) static void regs_map(struct regs_dump *regs, uint64_t mask, char *bf, int size)
{ {
unsigned int i = 0, r; unsigned int i = 0, r;
int printed = 0; int printed = 0;
...@@ -695,7 +695,7 @@ static int regs_map(struct regs_dump *regs, uint64_t mask, char *bf, int size) ...@@ -695,7 +695,7 @@ static int regs_map(struct regs_dump *regs, uint64_t mask, char *bf, int size)
bf[0] = 0; bf[0] = 0;
if (!regs || !regs->regs) if (!regs || !regs->regs)
return 0; return;
for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) { for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {
u64 val = regs->regs[i++]; u64 val = regs->regs[i++];
...@@ -704,8 +704,6 @@ static int regs_map(struct regs_dump *regs, uint64_t mask, char *bf, int size) ...@@ -704,8 +704,6 @@ static int regs_map(struct regs_dump *regs, uint64_t mask, char *bf, int size)
"%5s:0x%" PRIx64 " ", "%5s:0x%" PRIx64 " ",
perf_reg_name(r), val); perf_reg_name(r), val);
} }
return printed;
} }
static void set_regs_in_dict(PyObject *dict, static void set_regs_in_dict(PyObject *dict,
...@@ -713,7 +711,16 @@ static void set_regs_in_dict(PyObject *dict, ...@@ -713,7 +711,16 @@ static void set_regs_in_dict(PyObject *dict,
struct evsel *evsel) struct evsel *evsel)
{ {
struct perf_event_attr *attr = &evsel->core.attr; struct perf_event_attr *attr = &evsel->core.attr;
char bf[512];
/*
* Here value 28 is a constant size which can be used to print
* one register value and its corresponds to:
* 16 chars is to specify 64 bit register in hexadecimal.
* 2 chars is for appending "0x" to the hexadecimal value and
* 10 chars is for register name.
*/
int size = __sw_hweight64(attr->sample_regs_intr) * 28;
char bf[size];
regs_map(&sample->intr_regs, attr->sample_regs_intr, bf, sizeof(bf)); regs_map(&sample->intr_regs, attr->sample_regs_intr, bf, sizeof(bf));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment