diff mbox series

perf tools: Allocate id array in perf_event__synthesize_event_update_cpus

Message ID 20181003113643.GA31725@krava (mailing list archive)
State New, archived
Headers show
Series perf tools: Allocate id array in perf_event__synthesize_event_update_cpus | expand

Commit Message

Jiri Olsa Oct. 3, 2018, 11:36 a.m. UTC
On Tue, Oct 02, 2018 at 01:16:21PM +0200, Jiri Olsa wrote:
> On Tue, Oct 02, 2018 at 11:41:36AM +0100, John Garry wrote:
> 
> SNIP
> 
> > > 
> > > 
> > > ---
> > > diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
> > > index 1ec1d9bc2d63..fb2a0dab3978 100644
> > > --- a/tools/perf/util/header.c
> > > +++ b/tools/perf/util/header.c
> > > @@ -29,6 +29,7 @@
> > >  #include "symbol.h"
> > >  #include "debug.h"
> > >  #include "cpumap.h"
> > > +#include "thread_map.h"
> > >  #include "pmu.h"
> > >  #include "vdso.h"
> > >  #include "strbuf.h"
> > > @@ -3579,6 +3580,11 @@ perf_event__synthesize_event_update_cpus(struct perf_tool *tool,
> > > 	if (!evsel->own_cpus)
> > > 		return 0;
> > > 
> > > +	if (!evsel->id ||
> > 
> > for my test, evsel->id is NULL
> > 
> > > +	    perf_evsel__alloc_id(evsel, cpu_map__nr(evsel->cpus),
> > > +				 thread_map__nr(evsel->threads)))
> > 
> > and then this function is not called as we return immediately. So did you
> > really want this:
> > 
> > if (!evsel->id && perf_evsel__alloc_id(...))
> > 	return -ENOMEM;
> 
> ugh.. yes ;-) thanks for the fix.. I'll double
> check the logic and post the patch this week

actualy, we also need to populate those ids ;-)
so calling perf_evsel__store_ids instead..
attaching the full patch

thanks,
jirka


---
John reported crash when recording on an event under
pmu with cpumask defined:

  root@localhost:~# ./perf_debug_ record -e armv8_pmuv3_0/br_mis_pred/ sleep 1
  perf: Segmentation fault
  Obtained 9 stack frames.
  ./perf_debug_() [0x4c5ef8]
  [0xffff82ba267c]
  ./perf_debug_() [0x4bc5a8]
  ./perf_debug_() [0x419550]
  ./perf_debug_() [0x41a928]
  ./perf_debug_() [0x472f58]
  ./perf_debug_() [0x473210]
  ./perf_debug_() [0x4070f4]
  /lib/aarch64-linux-gnu/libc.so.6(__libc_start_main+0xe0) [0xffff8294c8a0]
  Segmentation fault (core dumped)

We synthesize an update event that needs to touch the evsel
id array, which is not defined at that time. Fixing this
by allocating the array and getting IDs before it's used.

Reported-by: John Garry <john.garry@huawei.com>
Link: http://lkml.kernel.org/n/tip-8x4n7o34yheigoxm1jibflm6@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/header.c | 4 ++++
 1 file changed, 4 insertions(+)

Comments

John Garry Oct. 3, 2018, 2:08 p.m. UTC | #1
On 03/10/2018 12:36, Jiri Olsa wrote:
> On Tue, Oct 02, 2018 at 01:16:21PM +0200, Jiri Olsa wrote:
>> On Tue, Oct 02, 2018 at 11:41:36AM +0100, John Garry wrote:
>>
>> SNIP
>>
>>>>
>>>>
>>>> ---
>>>> diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
>>>> index 1ec1d9bc2d63..fb2a0dab3978 100644
>>>> --- a/tools/perf/util/header.c
>>>> +++ b/tools/perf/util/header.c
>>>> @@ -29,6 +29,7 @@
>>>>  #include "symbol.h"
>>>>  #include "debug.h"
>>>>  #include "cpumap.h"
>>>> +#include "thread_map.h"
>>>>  #include "pmu.h"
>>>>  #include "vdso.h"
>>>>  #include "strbuf.h"
>>>> @@ -3579,6 +3580,11 @@ perf_event__synthesize_event_update_cpus(struct perf_tool *tool,
>>>> 	if (!evsel->own_cpus)
>>>> 		return 0;
>>>>
>>>> +	if (!evsel->id ||
>>>
>>> for my test, evsel->id is NULL
>>>
>>>> +	    perf_evsel__alloc_id(evsel, cpu_map__nr(evsel->cpus),
>>>> +				 thread_map__nr(evsel->threads)))
>>>
>>> and then this function is not called as we return immediately. So did you
>>> really want this:
>>>
>>> if (!evsel->id && perf_evsel__alloc_id(...))
>>> 	return -ENOMEM;
>>
>> ugh.. yes ;-) thanks for the fix.. I'll double
>> check the logic and post the patch this week
>
> actualy, we also need to populate those ids ;-)
> so calling perf_evsel__store_ids instead..
> attaching the full patch
>
> thanks,
> jirka
>

Hi Jirka,

Can you please double-check your new patch, as I'm getting this now:
root@localhost:~# ./perf_debug record -e armv8_pmuv3_0/br_mis_pred/ sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.001 MB perf.data (6 samples) ]
root@localhost:~# ./perf_debug report
0xe8 [0]: failed to process type: 461
Error:
failed to process sample
# To display the perf.data header info, please use 
--header/--header-only option
#
root@localhost:~#

Thanks,
John

>
> ---
> John reported crash when recording on an event under
> pmu with cpumask defined:
>
>   root@localhost:~# ./perf_debug_ record -e armv8_pmuv3_0/br_mis_pred/ sleep 1
>   perf: Segmentation fault
>   Obtained 9 stack frames.
>   ./perf_debug_() [0x4c5ef8]
>   [0xffff82ba267c]
>   ./perf_debug_() [0x4bc5a8]
>   ./perf_debug_() [0x419550]
>   ./perf_debug_() [0x41a928]
>   ./perf_debug_() [0x472f58]
>   ./perf_debug_() [0x473210]
>   ./perf_debug_() [0x4070f4]
>   /lib/aarch64-linux-gnu/libc.so.6(__libc_start_main+0xe0) [0xffff8294c8a0]
>   Segmentation fault (core dumped)
>
> We synthesize an update event that needs to touch the evsel
> id array, which is not defined at that time. Fixing this
> by allocating the array and getting IDs before it's used.
>
> Reported-by: John Garry <john.garry@huawei.com>
> Link: http://lkml.kernel.org/n/tip-8x4n7o34yheigoxm1jibflm6@git.kernel.org
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  tools/perf/util/header.c | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
> index 1ec1d9bc2d63..14ca27f79d4a 100644
> --- a/tools/perf/util/header.c
> +++ b/tools/perf/util/header.c
> @@ -29,6 +29,7 @@
>  #include "symbol.h"
>  #include "debug.h"
>  #include "cpumap.h"
> +#include "thread_map.h"
>  #include "pmu.h"
>  #include "vdso.h"
>  #include "strbuf.h"
> @@ -3579,6 +3580,9 @@ perf_event__synthesize_event_update_cpus(struct perf_tool *tool,
>  	if (!evsel->own_cpus)
>  		return 0;
>
> +	if (!evsel->id && perf_evsel__store_ids(evsel, evsel->evlist))
> +		return -ENOMEM;
> +
>  	ev = cpu_map_data__alloc(evsel->own_cpus, &size, &type, &max);
>  	if (!ev)
>  		return -ENOMEM;
>
Jiri Olsa Oct. 3, 2018, 2:16 p.m. UTC | #2
On Wed, Oct 03, 2018 at 03:08:10PM +0100, John Garry wrote:
> On 03/10/2018 12:36, Jiri Olsa wrote:
> > On Tue, Oct 02, 2018 at 01:16:21PM +0200, Jiri Olsa wrote:
> > > On Tue, Oct 02, 2018 at 11:41:36AM +0100, John Garry wrote:
> > > 
> > > SNIP
> > > 
> > > > > 
> > > > > 
> > > > > ---
> > > > > diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
> > > > > index 1ec1d9bc2d63..fb2a0dab3978 100644
> > > > > --- a/tools/perf/util/header.c
> > > > > +++ b/tools/perf/util/header.c
> > > > > @@ -29,6 +29,7 @@
> > > > >  #include "symbol.h"
> > > > >  #include "debug.h"
> > > > >  #include "cpumap.h"
> > > > > +#include "thread_map.h"
> > > > >  #include "pmu.h"
> > > > >  #include "vdso.h"
> > > > >  #include "strbuf.h"
> > > > > @@ -3579,6 +3580,11 @@ perf_event__synthesize_event_update_cpus(struct perf_tool *tool,
> > > > > 	if (!evsel->own_cpus)
> > > > > 		return 0;
> > > > > 
> > > > > +	if (!evsel->id ||
> > > > 
> > > > for my test, evsel->id is NULL
> > > > 
> > > > > +	    perf_evsel__alloc_id(evsel, cpu_map__nr(evsel->cpus),
> > > > > +				 thread_map__nr(evsel->threads)))
> > > > 
> > > > and then this function is not called as we return immediately. So did you
> > > > really want this:
> > > > 
> > > > if (!evsel->id && perf_evsel__alloc_id(...))
> > > > 	return -ENOMEM;
> > > 
> > > ugh.. yes ;-) thanks for the fix.. I'll double
> > > check the logic and post the patch this week
> > 
> > actualy, we also need to populate those ids ;-)
> > so calling perf_evsel__store_ids instead..
> > attaching the full patch
> > 
> > thanks,
> > jirka
> > 
> 
> Hi Jirka,
> 
> Can you please double-check your new patch, as I'm getting this now:
> root@localhost:~# ./perf_debug record -e armv8_pmuv3_0/br_mis_pred/ sleep 1
> [ perf record: Woken up 1 times to write data ]
> [ perf record: Captured and wrote 0.001 MB perf.data (6 samples) ]
> root@localhost:~# ./perf_debug report
> 0xe8 [0]: failed to process type: 461
> Error:
> failed to process sample
> # To display the perf.data header info, please use --header/--header-only
> option
> #
> root@localhost:~#

ok, I need to get a machine to test this.. but it looks like
any sample-able events with cpumask are in arm :-\ will try
to get some..

jirka
diff mbox series

Patch

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 1ec1d9bc2d63..14ca27f79d4a 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -29,6 +29,7 @@ 
 #include "symbol.h"
 #include "debug.h"
 #include "cpumap.h"
+#include "thread_map.h"
 #include "pmu.h"
 #include "vdso.h"
 #include "strbuf.h"
@@ -3579,6 +3580,9 @@  perf_event__synthesize_event_update_cpus(struct perf_tool *tool,
 	if (!evsel->own_cpus)
 		return 0;
 
+	if (!evsel->id && perf_evsel__store_ids(evsel, evsel->evlist))
+		return -ENOMEM;
+
 	ev = cpu_map_data__alloc(evsel->own_cpus, &size, &type, &max);
 	if (!ev)
 		return -ENOMEM;