linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] Add data type profiling support for powerpc
@ 2024-03-09  7:25 Athira Rajeev
  2024-03-09  7:25 ` [PATCH 1/3] tools/perf/arch/powerpc: Add load/store in powerpc annotate instructions for data type profling Athira Rajeev
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Athira Rajeev @ 2024-03-09  7:25 UTC (permalink / raw)
  To: acme, jolsa, adrian.hunter, irogers, namhyung
  Cc: atrajeev, kjain, linux-perf-users, maddy, disgoel, linuxppc-dev

The patchset from Namhyung added support for data type profiling
in perf tool. This enabled support to associate PMU samples to data
types they refer using DWARF debug information. With the upstream
perf, currently it possible to run perf report or perf annotate to
view the data type information on x86.

This patchset includes changes need to enable data type profiling
support for powerpc. Main change are:
1. powerpc instruction nmemonic table to associate load/store
instructions with move_ops which is use to identify if instruction
is a memory access one.
2. To get register number and access offset from the given
instruction, code uses fields from "struct arch" -> objump.
Add entry for powerpc here.
3. A get_arch_regnum to return register number from the
register name string.

These three patches are the basic foundational patches.
With these changes, data types is getting identified for kernel
and user-space samples. There are still samples, which comes as
"unknown" and needs to be checked. We plan to get those addressed
in follow up. With the current patchset:

 ./perf record -a -e mem-loads sleep 1
 ./perf report -s type,typeoff --hierarchy --group --stdio
Snippet of logs:

 Total Lost Samples: 0

 Samples: 277  of events 'mem-loads, dummy:u'
 Event count (approx.): 149813

            Overhead  Data Type / Data Type Offset
 ...................  ............................

    65.93%   0.00%     (unknown)
       65.93%   0.00%     (unknown) +0 (no field)
     8.19%   0.00%     struct vm_area_struct
        8.19%   0.00%     struct vm_area_struct +136 (vm_file)
     4.53%   0.00%     struct rq
        3.14%   0.00%     struct rq +0 (__lock.raw_lock.val)
        0.83%   0.00%     struct rq +3216 (avg_irq.runnable_sum)
        0.24%   0.00%     struct rq +4 (nr_running)
        0.14%   0.00%     struct rq +12 (nr_preferred_running)
        0.12%   0.00%     struct rq +2760 (sd)
        0.06%   0.00%     struct rq +3368 (prev_steal_time_rq)
        0.01%   0.00%     struct rq +2592 (curr)
     3.53%   0.00%     struct rb_node
        3.53%   0.00%     struct rb_node +0 (__rb_parent_color)
     3.43%   0.00%     struct slab
        3.43%   0.00%     struct slab +32 (freelist)
     3.30%   0.00%     unsigned int
        3.30%   0.00%     unsigned int +0 (no field)
     3.22%   0.00%     struct vm_fault
        3.22%   0.00%     struct vm_fault +48 (pmd)
     2.55%   0.00%     unsigned char
        2.55%   0.00%     unsigned char +0 (no field)
     1.06%   0.00%     struct task_struct
        1.06%   0.00%     struct task_struct +4 (thread_info.cpu)
     0.92%   0.00%     void*
        0.92%   0.00%     void* +0 (no field)
     0.74%   0.00%     __int128 unsigned
        0.74%   0.00%     __int128 unsigned +8 (no field)
     0.59%   0.00%     struct perf_event
        0.54%   0.00%     struct perf_event +552 (ctx)
        0.04%   0.00%     struct perf_event +152 (pmu)
     0.20%   0.00%     struct sched_entity
        0.20%   0.00%     struct sched_entity +0 (load.weight)
     0.18%   0.00%     struct cfs_rq
        0.18%   0.00%     struct cfs_rq +96 (curr)

Thanks
Athira

Athira Rajeev (3):
  tools/perf/arch/powerpc: Add load/store in powerpc annotate
    instructions for data type profling
  tools/erf/util/annotate: Set register_char and memory_ref_char for
    powerpc
  tools/perf/arch/powerc: Add get_arch_regnum for powerpc

 .../perf/arch/powerpc/annotate/instructions.c | 66 +++++++++++++++++++
 tools/perf/arch/powerpc/util/dwarf-regs.c     | 29 ++++++++
 tools/perf/util/annotate.c                    |  5 ++
 3 files changed, 100 insertions(+)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/3] tools/perf/arch/powerpc: Add load/store in powerpc annotate instructions for data type profling
  2024-03-09  7:25 [PATCH 0/3] Add data type profiling support for powerpc Athira Rajeev
@ 2024-03-09  7:25 ` Athira Rajeev
  2024-03-09  9:48   ` Christophe Leroy
  2024-03-09  7:25 ` [PATCH 2/3] tools/erf/util/annotate: Set register_char and memory_ref_char for powerpc Athira Rajeev
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 14+ messages in thread
From: Athira Rajeev @ 2024-03-09  7:25 UTC (permalink / raw)
  To: acme, jolsa, adrian.hunter, irogers, namhyung
  Cc: atrajeev, kjain, linux-perf-users, maddy, disgoel, linuxppc-dev

Add powerpc instruction nmemonic table to associate load/store
instructions with move_ops. mov_ops is used to identify mem_type
to associate instruction with data type and offset. Also initialize
and allocate arch specific fields for nr_instructions, instructions and
nr_instructions_allocate.

Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
---
 .../perf/arch/powerpc/annotate/instructions.c | 66 +++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/tools/perf/arch/powerpc/annotate/instructions.c b/tools/perf/arch/powerpc/annotate/instructions.c
index a3f423c27cae..07af4442be38 100644
--- a/tools/perf/arch/powerpc/annotate/instructions.c
+++ b/tools/perf/arch/powerpc/annotate/instructions.c
@@ -1,6 +1,65 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/compiler.h>
 
+/*
+ * powerpc instruction nmemonic table to associate load/store instructions with
+ * move_ops. mov_ops is used to identify mem_type to associate instruction with
+ * data type and offset.
+ */
+static struct ins powerpc__instructions[] = {
+	{ .name = "lbz",	.ops = &mov_ops,  },
+	{ .name = "lbzx",	.ops = &mov_ops,  },
+	{ .name = "lbzu",	.ops = &mov_ops,  },
+	{ .name = "lbzux",	.ops = &mov_ops,  },
+	{ .name = "lhz",	.ops = &mov_ops,  },
+	{ .name = "lhzx",	.ops = &mov_ops,  },
+	{ .name = "lhzu",	.ops = &mov_ops,  },
+	{ .name = "lhzux",	.ops = &mov_ops,  },
+	{ .name = "lha",	.ops = &mov_ops,  },
+	{ .name = "lhax",	.ops = &mov_ops,  },
+	{ .name = "lhau",	.ops = &mov_ops,  },
+	{ .name = "lhaux",	.ops = &mov_ops,  },
+	{ .name = "lwz",	.ops = &mov_ops,  },
+	{ .name = "lwzx",	.ops = &mov_ops,  },
+	{ .name = "lwzu",	.ops = &mov_ops,  },
+	{ .name = "lwzux",	.ops = &mov_ops,  },
+	{ .name = "lwa",	.ops = &mov_ops,  },
+	{ .name = "lwax",	.ops = &mov_ops,  },
+	{ .name = "lwaux",	.ops = &mov_ops,  },
+	{ .name = "ld",		.ops = &mov_ops,  },
+	{ .name = "ldx",	.ops = &mov_ops,  },
+	{ .name = "ldu",	.ops = &mov_ops,  },
+	{ .name = "ldux",	.ops = &mov_ops,  },
+	{ .name = "stb",	.ops = &mov_ops,  },
+	{ .name = "stbx",	.ops = &mov_ops,  },
+	{ .name = "stbu",	.ops = &mov_ops,  },
+	{ .name = "stbux",	.ops = &mov_ops,  },
+	{ .name = "sth",	.ops = &mov_ops,  },
+	{ .name = "sthx",	.ops = &mov_ops,  },
+	{ .name = "sthu",	.ops = &mov_ops,  },
+	{ .name = "sthux",	.ops = &mov_ops,  },
+	{ .name = "stw",	.ops = &mov_ops,  },
+	{ .name = "stwx",	.ops = &mov_ops,  },
+	{ .name = "stwu",	.ops = &mov_ops,  },
+	{ .name = "stwux",	.ops = &mov_ops,  },
+	{ .name = "std",	.ops = &mov_ops,  },
+	{ .name = "stdx",	.ops = &mov_ops,  },
+	{ .name = "stdu",	.ops = &mov_ops,  },
+	{ .name = "stdux",	.ops = &mov_ops,  },
+	{ .name = "lhbrx",	.ops = &mov_ops,  },
+	{ .name = "sthbrx",	.ops = &mov_ops,  },
+	{ .name = "lwbrx",	.ops = &mov_ops,  },
+	{ .name = "stwbrx",	.ops = &mov_ops,  },
+	{ .name = "ldbrx",	.ops = &mov_ops,  },
+	{ .name = "stdbrx",	.ops = &mov_ops,  },
+	{ .name = "lmw",	.ops = &mov_ops,  },
+	{ .name = "stmw",	.ops = &mov_ops,  },
+	{ .name = "lswi",	.ops = &mov_ops,  },
+	{ .name = "lswx",	.ops = &mov_ops,  },
+	{ .name = "stswi",	.ops = &mov_ops,  },
+	{ .name = "stswx",	.ops = &mov_ops,  },
+};
+
 static struct ins_ops *powerpc__associate_instruction_ops(struct arch *arch, const char *name)
 {
 	int i;
@@ -52,6 +111,13 @@ static struct ins_ops *powerpc__associate_instruction_ops(struct arch *arch, con
 static int powerpc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
 {
 	if (!arch->initialized) {
+		arch->nr_instructions = ARRAY_SIZE(powerpc__instructions);
+		arch->instructions = calloc(arch->nr_instructions, sizeof(struct ins));
+		if (arch->instructions == NULL)
+			return -ENOMEM;
+
+		memcpy(arch->instructions, (struct ins *)powerpc__instructions, sizeof(struct ins) * arch->nr_instructions);
+		arch->nr_instructions_allocated = arch->nr_instructions;
 		arch->initialized = true;
 		arch->associate_instruction_ops = powerpc__associate_instruction_ops;
 		arch->objdump.comment_char      = '#';
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/3] tools/erf/util/annotate: Set register_char and memory_ref_char for powerpc
  2024-03-09  7:25 [PATCH 0/3] Add data type profiling support for powerpc Athira Rajeev
  2024-03-09  7:25 ` [PATCH 1/3] tools/perf/arch/powerpc: Add load/store in powerpc annotate instructions for data type profling Athira Rajeev
@ 2024-03-09  7:25 ` Athira Rajeev
  2024-03-09 17:43   ` Segher Boessenkool
  2024-03-09  7:25 ` [PATCH 3/3] tools/perf/arch/powerc: Add get_arch_regnum " Athira Rajeev
  2024-04-01 21:57 ` [PATCH 0/3] Add data type profiling support " Namhyung Kim
  3 siblings, 1 reply; 14+ messages in thread
From: Athira Rajeev @ 2024-03-09  7:25 UTC (permalink / raw)
  To: acme, jolsa, adrian.hunter, irogers, namhyung
  Cc: atrajeev, kjain, linux-perf-users, maddy, disgoel, linuxppc-dev

To identify if the instruction has any memory reference,
"memory_ref_char" field needs to be set for specific architecture.
Example memory instruction:
lwz     r10,0(r9)

Here "(" is the memory_ref_char. Set this as part of arch->objdump

To get register number and access offset from the given instruction,
arch->objdump.register_char is used. In case of powerpc, the register
char is "r" (since reg names are r0 to r31). Hence set register_char
as "r".

Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
---
 tools/perf/util/annotate.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index ac002d907d81..d69bd6edafcb 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -216,6 +216,11 @@ static struct arch architectures[] = {
 	{
 		.name = "powerpc",
 		.init = powerpc__annotate_init,
+		.objdump =  {
+			.comment_char = '#',
+			.register_char = 'r',
+			.memory_ref_char = '(',
+		},
 	},
 	{
 		.name = "riscv64",
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/3] tools/perf/arch/powerc: Add get_arch_regnum for powerpc
  2024-03-09  7:25 [PATCH 0/3] Add data type profiling support for powerpc Athira Rajeev
  2024-03-09  7:25 ` [PATCH 1/3] tools/perf/arch/powerpc: Add load/store in powerpc annotate instructions for data type profling Athira Rajeev
  2024-03-09  7:25 ` [PATCH 2/3] tools/erf/util/annotate: Set register_char and memory_ref_char for powerpc Athira Rajeev
@ 2024-03-09  7:25 ` Athira Rajeev
  2024-03-09  9:54   ` Christophe Leroy
  2024-03-26  9:35   ` Tiezhu Yang
  2024-04-01 21:57 ` [PATCH 0/3] Add data type profiling support " Namhyung Kim
  3 siblings, 2 replies; 14+ messages in thread
From: Athira Rajeev @ 2024-03-09  7:25 UTC (permalink / raw)
  To: acme, jolsa, adrian.hunter, irogers, namhyung
  Cc: atrajeev, kjain, linux-perf-users, maddy, disgoel, linuxppc-dev

The function get_dwarf_regnum() returns a DWARF register number
from a register name string. This calls arch specific function
get_arch_regnum to return register number for corresponding arch.
Add mappings for register name to register number in powerpc code:
arch/powerpc/util/dwarf-regs.c

Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
---
 tools/perf/arch/powerpc/util/dwarf-regs.c | 29 +++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/tools/perf/arch/powerpc/util/dwarf-regs.c b/tools/perf/arch/powerpc/util/dwarf-regs.c
index 0c4f4caf53ac..d955e3e577ea 100644
--- a/tools/perf/arch/powerpc/util/dwarf-regs.c
+++ b/tools/perf/arch/powerpc/util/dwarf-regs.c
@@ -98,3 +98,32 @@ int regs_query_register_offset(const char *name)
 			return roff->ptregs_offset;
 	return -EINVAL;
 }
+
+struct dwarf_regs_idx {
+	const char *name;
+	int idx;
+};
+
+static const struct dwarf_regs_idx powerpc_regidx_table[] = {
+	{ "r0", 0 }, { "r1", 1 }, { "r2", 2 }, { "r3", 3 }, { "r4", 4 },
+	{ "r5", 5 }, { "r6", 6 }, { "r7", 7 }, { "r8", 8 }, { "r9", 9 },
+	{ "r10", 10 }, { "r11", 11 }, { "r12", 12 }, { "r13", 13 }, { "r14", 14 },
+	{ "r15", 15 }, { "r16", 16 }, { "r17", 17 }, { "r18", 18 }, { "r19", 19 },
+	{ "r20", 20 }, { "r21", 21 }, { "r22", 22 }, { "r23", 23 }, { "r24", 24 },
+	{ "r25", 25 }, { "r26", 26 }, { "r27", 27 }, { "r27", 27 }, { "r28", 28 },
+	{ "r29", 29 }, { "r30", 30 }, { "r31", 31 },
+};
+
+int get_arch_regnum(const char *name)
+{
+	unsigned int i;
+
+	if (*name != 'r')
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(powerpc_regidx_table); i++)
+		if (!strcmp(powerpc_regidx_table[i].name, name))
+			return powerpc_regidx_table[i].idx;
+
+	return -ENOENT;
+}
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/3] tools/perf/arch/powerpc: Add load/store in powerpc annotate instructions for data type profling
  2024-03-09  7:25 ` [PATCH 1/3] tools/perf/arch/powerpc: Add load/store in powerpc annotate instructions for data type profling Athira Rajeev
@ 2024-03-09  9:48   ` Christophe Leroy
  2024-03-18 11:01     ` Athira Rajeev
  0 siblings, 1 reply; 14+ messages in thread
From: Christophe Leroy @ 2024-03-09  9:48 UTC (permalink / raw)
  To: Athira Rajeev, acme, jolsa, adrian.hunter, irogers, namhyung
  Cc: linux-perf-users, kjain, maddy, linuxppc-dev, disgoel



Le 09/03/2024 à 08:25, Athira Rajeev a écrit :
> Add powerpc instruction nmemonic table to associate load/store
> instructions with move_ops. mov_ops is used to identify mem_type
> to associate instruction with data type and offset. Also initialize
> and allocate arch specific fields for nr_instructions, instructions and
> nr_instructions_allocate.
> 
> Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
> ---
>   .../perf/arch/powerpc/annotate/instructions.c | 66 +++++++++++++++++++
>   1 file changed, 66 insertions(+)
> 
> diff --git a/tools/perf/arch/powerpc/annotate/instructions.c b/tools/perf/arch/powerpc/annotate/instructions.c
> index a3f423c27cae..07af4442be38 100644
> --- a/tools/perf/arch/powerpc/annotate/instructions.c
> +++ b/tools/perf/arch/powerpc/annotate/instructions.c
> @@ -1,6 +1,65 @@
>   // SPDX-License-Identifier: GPL-2.0
>   #include <linux/compiler.h>
>   
> +/*
> + * powerpc instruction nmemonic table to associate load/store instructions with
> + * move_ops. mov_ops is used to identify mem_type to associate instruction with
> + * data type and offset.
> + */
> +static struct ins powerpc__instructions[] = {
> +	{ .name = "lbz",	.ops = &mov_ops,  },
> +	{ .name = "lbzx",	.ops = &mov_ops,  },
> +	{ .name = "lbzu",	.ops = &mov_ops,  },
> +	{ .name = "lbzux",	.ops = &mov_ops,  },
> +	{ .name = "lhz",	.ops = &mov_ops,  },
> +	{ .name = "lhzx",	.ops = &mov_ops,  },
> +	{ .name = "lhzu",	.ops = &mov_ops,  },
> +	{ .name = "lhzux",	.ops = &mov_ops,  },
> +	{ .name = "lha",	.ops = &mov_ops,  },
> +	{ .name = "lhax",	.ops = &mov_ops,  },
> +	{ .name = "lhau",	.ops = &mov_ops,  },
> +	{ .name = "lhaux",	.ops = &mov_ops,  },
> +	{ .name = "lwz",	.ops = &mov_ops,  },
> +	{ .name = "lwzx",	.ops = &mov_ops,  },
> +	{ .name = "lwzu",	.ops = &mov_ops,  },
> +	{ .name = "lwzux",	.ops = &mov_ops,  },
> +	{ .name = "lwa",	.ops = &mov_ops,  },
> +	{ .name = "lwax",	.ops = &mov_ops,  },
> +	{ .name = "lwaux",	.ops = &mov_ops,  },
> +	{ .name = "ld",		.ops = &mov_ops,  },
> +	{ .name = "ldx",	.ops = &mov_ops,  },
> +	{ .name = "ldu",	.ops = &mov_ops,  },
> +	{ .name = "ldux",	.ops = &mov_ops,  },
> +	{ .name = "stb",	.ops = &mov_ops,  },
> +	{ .name = "stbx",	.ops = &mov_ops,  },
> +	{ .name = "stbu",	.ops = &mov_ops,  },
> +	{ .name = "stbux",	.ops = &mov_ops,  },
> +	{ .name = "sth",	.ops = &mov_ops,  },
> +	{ .name = "sthx",	.ops = &mov_ops,  },
> +	{ .name = "sthu",	.ops = &mov_ops,  },
> +	{ .name = "sthux",	.ops = &mov_ops,  },
> +	{ .name = "stw",	.ops = &mov_ops,  },
> +	{ .name = "stwx",	.ops = &mov_ops,  },
> +	{ .name = "stwu",	.ops = &mov_ops,  },
> +	{ .name = "stwux",	.ops = &mov_ops,  },
> +	{ .name = "std",	.ops = &mov_ops,  },
> +	{ .name = "stdx",	.ops = &mov_ops,  },
> +	{ .name = "stdu",	.ops = &mov_ops,  },
> +	{ .name = "stdux",	.ops = &mov_ops,  },
> +	{ .name = "lhbrx",	.ops = &mov_ops,  },
> +	{ .name = "sthbrx",	.ops = &mov_ops,  },
> +	{ .name = "lwbrx",	.ops = &mov_ops,  },
> +	{ .name = "stwbrx",	.ops = &mov_ops,  },
> +	{ .name = "ldbrx",	.ops = &mov_ops,  },
> +	{ .name = "stdbrx",	.ops = &mov_ops,  },
> +	{ .name = "lmw",	.ops = &mov_ops,  },
> +	{ .name = "stmw",	.ops = &mov_ops,  },
> +	{ .name = "lswi",	.ops = &mov_ops,  },
> +	{ .name = "lswx",	.ops = &mov_ops,  },
> +	{ .name = "stswi",	.ops = &mov_ops,  },
> +	{ .name = "stswx",	.ops = &mov_ops,  },
> +};

What about lwarx and stwcx ?

> +
>   static struct ins_ops *powerpc__associate_instruction_ops(struct arch *arch, const char *name)
>   {
>   	int i;
> @@ -52,6 +111,13 @@ static struct ins_ops *powerpc__associate_instruction_ops(struct arch *arch, con
>   static int powerpc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
>   {
>   	if (!arch->initialized) {
> +		arch->nr_instructions = ARRAY_SIZE(powerpc__instructions);
> +		arch->instructions = calloc(arch->nr_instructions, sizeof(struct ins));
> +		if (arch->instructions == NULL)

Prefered form is

	if (!arch->instructions)

> +			return -ENOMEM;
> +
> +		memcpy(arch->instructions, (struct ins *)powerpc__instructions, sizeof(struct ins) * arch->nr_instructions);

No need to cast powerpc__instructions, it is already a pointer.


> +		arch->nr_instructions_allocated = arch->nr_instructions;
>   		arch->initialized = true;
>   		arch->associate_instruction_ops = powerpc__associate_instruction_ops;
>   		arch->objdump.comment_char      = '#';

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/3] tools/perf/arch/powerc: Add get_arch_regnum for powerpc
  2024-03-09  7:25 ` [PATCH 3/3] tools/perf/arch/powerc: Add get_arch_regnum " Athira Rajeev
@ 2024-03-09  9:54   ` Christophe Leroy
  2024-03-18 11:00     ` Athira Rajeev
  2024-03-26  9:35   ` Tiezhu Yang
  1 sibling, 1 reply; 14+ messages in thread
From: Christophe Leroy @ 2024-03-09  9:54 UTC (permalink / raw)
  To: Athira Rajeev, acme, jolsa, adrian.hunter, irogers, namhyung
  Cc: linux-perf-users, kjain, maddy, linuxppc-dev, disgoel



Le 09/03/2024 à 08:25, Athira Rajeev a écrit :
> The function get_dwarf_regnum() returns a DWARF register number
> from a register name string. This calls arch specific function
> get_arch_regnum to return register number for corresponding arch.
> Add mappings for register name to register number in powerpc code:
> arch/powerpc/util/dwarf-regs.c
> 
> Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
> ---
>   tools/perf/arch/powerpc/util/dwarf-regs.c | 29 +++++++++++++++++++++++
>   1 file changed, 29 insertions(+)
> 
> diff --git a/tools/perf/arch/powerpc/util/dwarf-regs.c b/tools/perf/arch/powerpc/util/dwarf-regs.c
> index 0c4f4caf53ac..d955e3e577ea 100644
> --- a/tools/perf/arch/powerpc/util/dwarf-regs.c
> +++ b/tools/perf/arch/powerpc/util/dwarf-regs.c
> @@ -98,3 +98,32 @@ int regs_query_register_offset(const char *name)
>   			return roff->ptregs_offset;
>   	return -EINVAL;
>   }
> +
> +struct dwarf_regs_idx {
> +	const char *name;
> +	int idx;
> +};
> +
> +static const struct dwarf_regs_idx powerpc_regidx_table[] = {
> +	{ "r0", 0 }, { "r1", 1 }, { "r2", 2 }, { "r3", 3 }, { "r4", 4 },
> +	{ "r5", 5 }, { "r6", 6 }, { "r7", 7 }, { "r8", 8 }, { "r9", 9 },
> +	{ "r10", 10 }, { "r11", 11 }, { "r12", 12 }, { "r13", 13 }, { "r14", 14 },
> +	{ "r15", 15 }, { "r16", 16 }, { "r17", 17 }, { "r18", 18 }, { "r19", 19 },
> +	{ "r20", 20 }, { "r21", 21 }, { "r22", 22 }, { "r23", 23 }, { "r24", 24 },
> +	{ "r25", 25 }, { "r26", 26 }, { "r27", 27 }, { "r27", 27 }, { "r28", 28 },
> +	{ "r29", 29 }, { "r30", 30 }, { "r31", 31 },
> +};
> +
> +int get_arch_regnum(const char *name)
> +{
> +	unsigned int i;
> +
> +	if (*name != 'r')
> +		return -EINVAL;
> +
> +	for (i = 0; i < ARRAY_SIZE(powerpc_regidx_table); i++)
> +		if (!strcmp(powerpc_regidx_table[i].name, name))
> +			return powerpc_regidx_table[i].idx;

Can you do more simple ?

Something like:

	int n;

	if (*name != 'r')
		return -EINVAL;
	n = atoi(name + 1);
	return n >= 0 && n < 32 ? n : -ENOENT;

> +
> +	return -ENOENT;
> +}

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/3] tools/erf/util/annotate: Set register_char and memory_ref_char for powerpc
  2024-03-09  7:25 ` [PATCH 2/3] tools/erf/util/annotate: Set register_char and memory_ref_char for powerpc Athira Rajeev
@ 2024-03-09 17:43   ` Segher Boessenkool
  2024-03-18 11:33     ` Athira Rajeev
  0 siblings, 1 reply; 14+ messages in thread
From: Segher Boessenkool @ 2024-03-09 17:43 UTC (permalink / raw)
  To: Athira Rajeev
  Cc: irogers, maddy, kjain, adrian.hunter, acme, linux-perf-users,
	jolsa, namhyung, disgoel, linuxppc-dev

All instructions with a primary opcode from 32 to 63 are memory insns,
and no others.  It's trivial to see whether it is a load or store, too
(just bit 3 of the insn).  Trying to parse disassembled code is much
harder, and you easily make some mistakes here.

On Sat, Mar 09, 2024 at 12:55:12PM +0530, Athira Rajeev wrote:
> To identify if the instruction has any memory reference,
> "memory_ref_char" field needs to be set for specific architecture.
> Example memory instruction:
> lwz     r10,0(r9)
> 
> Here "(" is the memory_ref_char. Set this as part of arch->objdump

What about "lwzx r10,0,r19", semantically exactly the same instruction?
There is no paren in there.  Not all instructions using parens are
memory insns, either, not in assembler code at least.

> To get register number and access offset from the given instruction,
> arch->objdump.register_char is used. In case of powerpc, the register
> char is "r" (since reg names are r0 to r31). Hence set register_char
> as "r".

cr0..cr7
r0..r31
f0..f31
v0..v31
vs0..vs63
and many other spellings.  Plain "0..63" is also fine.

The "0" in my lwzx example is a register field as well (and it stands
for "no register", not for "r0").  Called "(RA|0)" usually (incidentally,
see the parens there as well, oh joy).

Don't you have the binary code here as well, not just a disassembled
representation of it?  It is way easier to just use that, and you'll get
much better results that way :-)


Segher

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/3] tools/perf/arch/powerc: Add get_arch_regnum for powerpc
  2024-03-09  9:54   ` Christophe Leroy
@ 2024-03-18 11:00     ` Athira Rajeev
  0 siblings, 0 replies; 14+ messages in thread
From: Athira Rajeev @ 2024-03-18 11:00 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: irogers, maddy, kjain, adrian.hunter, acme, linux-perf-users,
	jolsa, namhyung, disgoel, linuxppc-dev



> On 09-Mar-2024, at 3:24 PM, Christophe Leroy <christophe.leroy@csgroup.eu> wrote:
> 
> 
> 
> Le 09/03/2024 à 08:25, Athira Rajeev a écrit :
>> The function get_dwarf_regnum() returns a DWARF register number
>> from a register name string. This calls arch specific function
>> get_arch_regnum to return register number for corresponding arch.
>> Add mappings for register name to register number in powerpc code:
>> arch/powerpc/util/dwarf-regs.c
>> 
>> Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
>> ---
>>  tools/perf/arch/powerpc/util/dwarf-regs.c | 29 +++++++++++++++++++++++
>>  1 file changed, 29 insertions(+)
>> 
>> diff --git a/tools/perf/arch/powerpc/util/dwarf-regs.c b/tools/perf/arch/powerpc/util/dwarf-regs.c
>> index 0c4f4caf53ac..d955e3e577ea 100644
>> --- a/tools/perf/arch/powerpc/util/dwarf-regs.c
>> +++ b/tools/perf/arch/powerpc/util/dwarf-regs.c
>> @@ -98,3 +98,32 @@ int regs_query_register_offset(const char *name)
>>   return roff->ptregs_offset;
>>   return -EINVAL;
>>  }
>> +
>> +struct dwarf_regs_idx {
>> + const char *name;
>> + int idx;
>> +};
>> +
>> +static const struct dwarf_regs_idx powerpc_regidx_table[] = {
>> + { "r0", 0 }, { "r1", 1 }, { "r2", 2 }, { "r3", 3 }, { "r4", 4 },
>> + { "r5", 5 }, { "r6", 6 }, { "r7", 7 }, { "r8", 8 }, { "r9", 9 },
>> + { "r10", 10 }, { "r11", 11 }, { "r12", 12 }, { "r13", 13 }, { "r14", 14 },
>> + { "r15", 15 }, { "r16", 16 }, { "r17", 17 }, { "r18", 18 }, { "r19", 19 },
>> + { "r20", 20 }, { "r21", 21 }, { "r22", 22 }, { "r23", 23 }, { "r24", 24 },
>> + { "r25", 25 }, { "r26", 26 }, { "r27", 27 }, { "r27", 27 }, { "r28", 28 },
>> + { "r29", 29 }, { "r30", 30 }, { "r31", 31 },
>> +};
>> +
>> +int get_arch_regnum(const char *name)
>> +{
>> + unsigned int i;
>> +
>> + if (*name != 'r')
>> + return -EINVAL;
>> +
>> + for (i = 0; i < ARRAY_SIZE(powerpc_regidx_table); i++)
>> + if (!strcmp(powerpc_regidx_table[i].name, name))
>> + return powerpc_regidx_table[i].idx;
> 
> Can you do more simple ?
> 
> Something like:
> 
> int n;
> 
> if (*name != 'r')
> return -EINVAL;
> n = atoi(name + 1);
> return n >= 0 && n < 32 ? n : -ENOENT;

Hi Christophe,

Thanks for reviewing patch and for the suggestions.

Sure, I will check this approach and address in V2

Thanks
Athira
> 
>> +
>> + return -ENOENT;
>> +}


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/3] tools/perf/arch/powerpc: Add load/store in powerpc annotate instructions for data type profling
  2024-03-09  9:48   ` Christophe Leroy
@ 2024-03-18 11:01     ` Athira Rajeev
  0 siblings, 0 replies; 14+ messages in thread
From: Athira Rajeev @ 2024-03-18 11:01 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: irogers, maddy, kjain, adrian.hunter, acme, linux-perf-users,
	jolsa, namhyung, disgoel, linuxppc-dev



> On 09-Mar-2024, at 3:18 PM, Christophe Leroy <christophe.leroy@csgroup.eu> wrote:
> 
> 
> 
> Le 09/03/2024 à 08:25, Athira Rajeev a écrit :
>> Add powerpc instruction nmemonic table to associate load/store
>> instructions with move_ops. mov_ops is used to identify mem_type
>> to associate instruction with data type and offset. Also initialize
>> and allocate arch specific fields for nr_instructions, instructions and
>> nr_instructions_allocate.
>> 
>> Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
>> ---
>>  .../perf/arch/powerpc/annotate/instructions.c | 66 +++++++++++++++++++
>>  1 file changed, 66 insertions(+)
>> 
>> diff --git a/tools/perf/arch/powerpc/annotate/instructions.c b/tools/perf/arch/powerpc/annotate/instructions.c
>> index a3f423c27cae..07af4442be38 100644
>> --- a/tools/perf/arch/powerpc/annotate/instructions.c
>> +++ b/tools/perf/arch/powerpc/annotate/instructions.c
>> @@ -1,6 +1,65 @@
>>  // SPDX-License-Identifier: GPL-2.0
>>  #include <linux/compiler.h>
>> 
>> +/*
>> + * powerpc instruction nmemonic table to associate load/store instructions with
>> + * move_ops. mov_ops is used to identify mem_type to associate instruction with
>> + * data type and offset.
>> + */
>> +static struct ins powerpc__instructions[] = {
>> + { .name = "lbz", .ops = &mov_ops,  },
>> + { .name = "lbzx", .ops = &mov_ops,  },
>> + { .name = "lbzu", .ops = &mov_ops,  },
>> + { .name = "lbzux", .ops = &mov_ops,  },
>> + { .name = "lhz", .ops = &mov_ops,  },
>> + { .name = "lhzx", .ops = &mov_ops,  },
>> + { .name = "lhzu", .ops = &mov_ops,  },
>> + { .name = "lhzux", .ops = &mov_ops,  },
>> + { .name = "lha", .ops = &mov_ops,  },
>> + { .name = "lhax", .ops = &mov_ops,  },
>> + { .name = "lhau", .ops = &mov_ops,  },
>> + { .name = "lhaux", .ops = &mov_ops,  },
>> + { .name = "lwz", .ops = &mov_ops,  },
>> + { .name = "lwzx", .ops = &mov_ops,  },
>> + { .name = "lwzu", .ops = &mov_ops,  },
>> + { .name = "lwzux", .ops = &mov_ops,  },
>> + { .name = "lwa", .ops = &mov_ops,  },
>> + { .name = "lwax", .ops = &mov_ops,  },
>> + { .name = "lwaux", .ops = &mov_ops,  },
>> + { .name = "ld", .ops = &mov_ops,  },
>> + { .name = "ldx", .ops = &mov_ops,  },
>> + { .name = "ldu", .ops = &mov_ops,  },
>> + { .name = "ldux", .ops = &mov_ops,  },
>> + { .name = "stb", .ops = &mov_ops,  },
>> + { .name = "stbx", .ops = &mov_ops,  },
>> + { .name = "stbu", .ops = &mov_ops,  },
>> + { .name = "stbux", .ops = &mov_ops,  },
>> + { .name = "sth", .ops = &mov_ops,  },
>> + { .name = "sthx", .ops = &mov_ops,  },
>> + { .name = "sthu", .ops = &mov_ops,  },
>> + { .name = "sthux", .ops = &mov_ops,  },
>> + { .name = "stw", .ops = &mov_ops,  },
>> + { .name = "stwx", .ops = &mov_ops,  },
>> + { .name = "stwu", .ops = &mov_ops,  },
>> + { .name = "stwux", .ops = &mov_ops,  },
>> + { .name = "std", .ops = &mov_ops,  },
>> + { .name = "stdx", .ops = &mov_ops,  },
>> + { .name = "stdu", .ops = &mov_ops,  },
>> + { .name = "stdux", .ops = &mov_ops,  },
>> + { .name = "lhbrx", .ops = &mov_ops,  },
>> + { .name = "sthbrx", .ops = &mov_ops,  },
>> + { .name = "lwbrx", .ops = &mov_ops,  },
>> + { .name = "stwbrx", .ops = &mov_ops,  },
>> + { .name = "ldbrx", .ops = &mov_ops,  },
>> + { .name = "stdbrx", .ops = &mov_ops,  },
>> + { .name = "lmw", .ops = &mov_ops,  },
>> + { .name = "stmw", .ops = &mov_ops,  },
>> + { .name = "lswi", .ops = &mov_ops,  },
>> + { .name = "lswx", .ops = &mov_ops,  },
>> + { .name = "stswi", .ops = &mov_ops,  },
>> + { .name = "stswx", .ops = &mov_ops,  },
>> +};
> 
> What about lwarx and stwcx ?
Yes, Will add those in next version

> 
>> +
>>  static struct ins_ops *powerpc__associate_instruction_ops(struct arch *arch, const char *name)
>>  {
>>   int i;
>> @@ -52,6 +111,13 @@ static struct ins_ops *powerpc__associate_instruction_ops(struct arch *arch, con
>>  static int powerpc__annotate_init(struct arch *arch, char *cpuid __maybe_unused)
>>  {
>>   if (!arch->initialized) {
>> + arch->nr_instructions = ARRAY_SIZE(powerpc__instructions);
>> + arch->instructions = calloc(arch->nr_instructions, sizeof(struct ins));
>> + if (arch->instructions == NULL)
> 
> Prefered form is
> 
> if (!arch->instructions)
Ok , will make this change

> 
>> + return -ENOMEM;
>> +
>> + memcpy(arch->instructions, (struct ins *)powerpc__instructions, sizeof(struct ins) * arch->nr_instructions);
> 
> No need to cast powerpc__instructions, it is already a pointer.
Yes, I will correct it


Thanks
Athira Rajeev
> 
> 
>> + arch->nr_instructions_allocated = arch->nr_instructions;
>>   arch->initialized = true;
>>   arch->associate_instruction_ops = powerpc__associate_instruction_ops;
>>   arch->objdump.comment_char      = '#';



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/3] tools/erf/util/annotate: Set register_char and memory_ref_char for powerpc
  2024-03-09 17:43   ` Segher Boessenkool
@ 2024-03-18 11:33     ` Athira Rajeev
  0 siblings, 0 replies; 14+ messages in thread
From: Athira Rajeev @ 2024-03-18 11:33 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Ian Rogers, maddy, kjain, Adrian Hunter,
	Arnaldo Carvalho de Melo, linux-perf-users, Jiri Olsa, namhyung,
	disgoel, linuxppc-dev



> On 09-Mar-2024, at 11:13 PM, Segher Boessenkool <segher@kernel.crashing.org> wrote:
> 
> All instructions with a primary opcode from 32 to 63 are memory insns,
> and no others.  It's trivial to see whether it is a load or store, too
> (just bit 3 of the insn).  Trying to parse disassembled code is much
> harder, and you easily make some mistakes here.

Hi Segher

Thanks for checking the patch and sharing review comments.

Ok, I am checking on this part.

> 
> On Sat, Mar 09, 2024 at 12:55:12PM +0530, Athira Rajeev wrote:
>> To identify if the instruction has any memory reference,
>> "memory_ref_char" field needs to be set for specific architecture.
>> Example memory instruction:
>> lwz     r10,0(r9)
>> 
>> Here "(" is the memory_ref_char. Set this as part of arch->objdump
> 
> What about "lwzx r10,0,r19", semantically exactly the same instruction?
> There is no paren in there.  Not all instructions using parens are
> memory insns, either, not in assembler code at least.
Yes, right Segher.

So, for the basic foundational patches, I targeted for instructions of this form (D form)
There are still samples, which comes as unknown and in that, X form instructions also needs to be checked.
Targeted to first get these basic foundational patches to add support in powerpc and get the remaining “unknowns” addressed in follow up.
But yes, X-form instructions also will be covered as part of the changes needed for powerpc.

> 
>> To get register number and access offset from the given instruction,
>> arch->objdump.register_char is used. In case of powerpc, the register
>> char is "r" (since reg names are r0 to r31). Hence set register_char
>> as "r".
> 
> cr0..cr7
> r0..r31
> f0..f31
> v0..v31
> vs0..vs63
> and many other spellings.  Plain "0..63" is also fine.
Ok 
> 
> The "0" in my lwzx example is a register field as well (and it stands
> for "no register", not for "r0").  Called "(RA|0)" usually (incidentally,
> see the parens there as well, oh joy).
> 
> Don't you have the binary code here as well, not just a disassembled
> representation of it?  It is way easier to just use that, and you'll get
> much better results that way :-)
> 

Thanks Segher for the suggestion on this. I will check on this as well.

Thanks
Athira Rajeev

> 
> Segher


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/3] tools/perf/arch/powerc: Add get_arch_regnum for powerpc
  2024-03-09  7:25 ` [PATCH 3/3] tools/perf/arch/powerc: Add get_arch_regnum " Athira Rajeev
  2024-03-09  9:54   ` Christophe Leroy
@ 2024-03-26  9:35   ` Tiezhu Yang
  2024-04-01 21:46     ` Namhyung Kim
  1 sibling, 1 reply; 14+ messages in thread
From: Tiezhu Yang @ 2024-03-26  9:35 UTC (permalink / raw)
  To: Athira Rajeev, acme, jolsa, adrian.hunter, irogers, namhyung
  Cc: linux-perf-users, kjain, maddy, linuxppc-dev, disgoel

Hi Athira and Namhyung,

On 03/09/2024 03:25 PM, Athira Rajeev wrote:
> The function get_dwarf_regnum() returns a DWARF register number
> from a register name string. This calls arch specific function
> get_arch_regnum to return register number for corresponding arch.
> Add mappings for register name to register number in powerpc code:
> arch/powerpc/util/dwarf-regs.c
>
> Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
> ---
>  tools/perf/arch/powerpc/util/dwarf-regs.c | 29 +++++++++++++++++++++++
>  1 file changed, 29 insertions(+)

I found commit 3eee606757ad ("perf dwarf-regs: Add get_dwarf_regnum()")
for x86, would you be able to share how to test these changes? What is
the difference with and without the patches?

Thanks,
Tiezhu


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/3] tools/perf/arch/powerc: Add get_arch_regnum for powerpc
  2024-03-26  9:35   ` Tiezhu Yang
@ 2024-04-01 21:46     ` Namhyung Kim
  0 siblings, 0 replies; 14+ messages in thread
From: Namhyung Kim @ 2024-04-01 21:46 UTC (permalink / raw)
  To: Tiezhu Yang
  Cc: irogers, Athira Rajeev, kjain, adrian.hunter, acme,
	linux-perf-users, maddy, jolsa, disgoel, linuxppc-dev

Hello,

On Tue, Mar 26, 2024 at 2:35 AM Tiezhu Yang <yangtiezhu@loongson.cn> wrote:
>
> Hi Athira and Namhyung,
>
> On 03/09/2024 03:25 PM, Athira Rajeev wrote:
> > The function get_dwarf_regnum() returns a DWARF register number
> > from a register name string. This calls arch specific function
> > get_arch_regnum to return register number for corresponding arch.
> > Add mappings for register name to register number in powerpc code:
> > arch/powerpc/util/dwarf-regs.c
> >
> > Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
> > ---
> >  tools/perf/arch/powerpc/util/dwarf-regs.c | 29 +++++++++++++++++++++++
> >  1 file changed, 29 insertions(+)
>
> I found commit 3eee606757ad ("perf dwarf-regs: Add get_dwarf_regnum()")
> for x86, would you be able to share how to test these changes? What is
> the difference with and without the patches?

Hmm.. I guess it won't work well without the patch.  This is
needed to map register numbers (from objdump) to what
DWARF can understand (IOW they use different numbers).

Thanks,
Namhyung

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 0/3] Add data type profiling support for powerpc
  2024-03-09  7:25 [PATCH 0/3] Add data type profiling support for powerpc Athira Rajeev
                   ` (2 preceding siblings ...)
  2024-03-09  7:25 ` [PATCH 3/3] tools/perf/arch/powerc: Add get_arch_regnum " Athira Rajeev
@ 2024-04-01 21:57 ` Namhyung Kim
  3 siblings, 0 replies; 14+ messages in thread
From: Namhyung Kim @ 2024-04-01 21:57 UTC (permalink / raw)
  To: Athira Rajeev
  Cc: irogers, maddy, kjain, adrian.hunter, acme, linux-perf-users,
	jolsa, disgoel, linuxppc-dev

Hello,

Sorry for the super late reply.


On Fri, Mar 8, 2024 at 11:25 PM Athira Rajeev
<atrajeev@linux.vnet.ibm.com> wrote:
>
> The patchset from Namhyung added support for data type profiling
> in perf tool. This enabled support to associate PMU samples to data
> types they refer using DWARF debug information. With the upstream
> perf, currently it possible to run perf report or perf annotate to
> view the data type information on x86.
>
> This patchset includes changes need to enable data type profiling
> support for powerpc. Main change are:
> 1. powerpc instruction nmemonic table to associate load/store
> instructions with move_ops which is use to identify if instruction
> is a memory access one.
> 2. To get register number and access offset from the given
> instruction, code uses fields from "struct arch" -> objump.
> Add entry for powerpc here.
> 3. A get_arch_regnum to return register number from the
> register name string.
>
> These three patches are the basic foundational patches.
> With these changes, data types is getting identified for kernel
> and user-space samples. There are still samples, which comes as
> "unknown" and needs to be checked. We plan to get those addressed
> in follow up. With the current patchset:
>
>  ./perf record -a -e mem-loads sleep 1
>  ./perf report -s type,typeoff --hierarchy --group --stdio
> Snippet of logs:
>
>  Total Lost Samples: 0
>
>  Samples: 277  of events 'mem-loads, dummy:u'
>  Event count (approx.): 149813
>
>             Overhead  Data Type / Data Type Offset
>  ...................  ............................
>
>     65.93%   0.00%     (unknown)
>        65.93%   0.00%     (unknown) +0 (no field)
>      8.19%   0.00%     struct vm_area_struct
>         8.19%   0.00%     struct vm_area_struct +136 (vm_file)
>      4.53%   0.00%     struct rq
>         3.14%   0.00%     struct rq +0 (__lock.raw_lock.val)
>         0.83%   0.00%     struct rq +3216 (avg_irq.runnable_sum)
>         0.24%   0.00%     struct rq +4 (nr_running)
>         0.14%   0.00%     struct rq +12 (nr_preferred_running)
>         0.12%   0.00%     struct rq +2760 (sd)
>         0.06%   0.00%     struct rq +3368 (prev_steal_time_rq)
>         0.01%   0.00%     struct rq +2592 (curr)
>      3.53%   0.00%     struct rb_node
>         3.53%   0.00%     struct rb_node +0 (__rb_parent_color)
>      3.43%   0.00%     struct slab
>         3.43%   0.00%     struct slab +32 (freelist)
>      3.30%   0.00%     unsigned int
>         3.30%   0.00%     unsigned int +0 (no field)
>      3.22%   0.00%     struct vm_fault
>         3.22%   0.00%     struct vm_fault +48 (pmd)
>      2.55%   0.00%     unsigned char
>         2.55%   0.00%     unsigned char +0 (no field)
>      1.06%   0.00%     struct task_struct
>         1.06%   0.00%     struct task_struct +4 (thread_info.cpu)
>      0.92%   0.00%     void*
>         0.92%   0.00%     void* +0 (no field)
>      0.74%   0.00%     __int128 unsigned
>         0.74%   0.00%     __int128 unsigned +8 (no field)
>      0.59%   0.00%     struct perf_event
>         0.54%   0.00%     struct perf_event +552 (ctx)
>         0.04%   0.00%     struct perf_event +152 (pmu)
>      0.20%   0.00%     struct sched_entity
>         0.20%   0.00%     struct sched_entity +0 (load.weight)
>      0.18%   0.00%     struct cfs_rq
>         0.18%   0.00%     struct cfs_rq +96 (curr)

Cool!  I'm happy to see it works well on powerpc too.

Lots of codes are still assuming x86 so you may need to
add separate logics like parsing the instruction location.

And instruction tracking is also a great concern.
But we may have something in the clang/LLVM to produce
more debug information and hopefully we can remove the
instruction tracking at all.

https://github.com/llvm/llvm-project/pull/81545

Anyway I'm really looking forward to seeing v2 soon.

Thanks,
Namhyung

>
> Athira Rajeev (3):
>   tools/perf/arch/powerpc: Add load/store in powerpc annotate
>     instructions for data type profling
>   tools/erf/util/annotate: Set register_char and memory_ref_char for
>     powerpc
>   tools/perf/arch/powerc: Add get_arch_regnum for powerpc
>
>  .../perf/arch/powerpc/annotate/instructions.c | 66 +++++++++++++++++++
>  tools/perf/arch/powerpc/util/dwarf-regs.c     | 29 ++++++++
>  tools/perf/util/annotate.c                    |  5 ++
>  3 files changed, 100 insertions(+)
>
> --
> 2.43.0
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 2/3] tools/erf/util/annotate: Set register_char and memory_ref_char for powerpc
  2024-03-09  5:51 Athira Rajeev
@ 2024-03-09  5:51 ` Athira Rajeev
  0 siblings, 0 replies; 14+ messages in thread
From: Athira Rajeev @ 2024-03-09  5:51 UTC (permalink / raw)
  To: acme, jolsa, adrian.hunter, irogers, namhyung
  Cc: atrajeev, kjain, linux-perf-users, maddy, disgoel, linuxppc-dev

To identify if the instruction has any memory reference,
"memory_ref_char" field needs to be set for specific architecture.
Example memory instruction:
lwz     r10,0(r9)

Here "(" is the memory_ref_char. Set this as part of arch->objdump

To get register number and access offset from the given instruction,
arch->objdump.register_char is used. In case of powerpc, the register
char is "r" (since reg names are r0 to r31). Hence set register_char
as "r".

Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
---
 tools/perf/util/annotate.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index ac002d907d81..d69bd6edafcb 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -216,6 +216,11 @@ static struct arch architectures[] = {
 	{
 		.name = "powerpc",
 		.init = powerpc__annotate_init,
+		.objdump =  {
+			.comment_char = '#',
+			.register_char = 'r',
+			.memory_ref_char = '(',
+		},
 	},
 	{
 		.name = "riscv64",
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2024-04-01 21:58 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-09  7:25 [PATCH 0/3] Add data type profiling support for powerpc Athira Rajeev
2024-03-09  7:25 ` [PATCH 1/3] tools/perf/arch/powerpc: Add load/store in powerpc annotate instructions for data type profling Athira Rajeev
2024-03-09  9:48   ` Christophe Leroy
2024-03-18 11:01     ` Athira Rajeev
2024-03-09  7:25 ` [PATCH 2/3] tools/erf/util/annotate: Set register_char and memory_ref_char for powerpc Athira Rajeev
2024-03-09 17:43   ` Segher Boessenkool
2024-03-18 11:33     ` Athira Rajeev
2024-03-09  7:25 ` [PATCH 3/3] tools/perf/arch/powerc: Add get_arch_regnum " Athira Rajeev
2024-03-09  9:54   ` Christophe Leroy
2024-03-18 11:00     ` Athira Rajeev
2024-03-26  9:35   ` Tiezhu Yang
2024-04-01 21:46     ` Namhyung Kim
2024-04-01 21:57 ` [PATCH 0/3] Add data type profiling support " Namhyung Kim
  -- strict thread matches above, loose matches on Subject: below --
2024-03-09  5:51 Athira Rajeev
2024-03-09  5:51 ` [PATCH 2/3] tools/erf/util/annotate: Set register_char and memory_ref_char " Athira Rajeev

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).