mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] perf/x86: Fix lockdep warning in for_each_sibling_event() on SPR
@ 2023-07-04 18:15 Namhyung Kim
  2023-07-05  8:38 ` Peter Zijlstra
  2023-07-10  8:13 ` [tip: perf/urgent] " tip-bot2 for Namhyung Kim
  0 siblings, 2 replies; 6+ messages in thread
From: Namhyung Kim @ 2023-07-04 18:15 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar
  Cc: Mark Rutland, Alexander Shishkin, Arnaldo Carvalho de Melo, LKML,
	Kan Liang, Stephane Eranian, Greg Thelen, stable

On SPR, the load latency event needs an auxiliary event in the same
group to work properly.  There's a check in intel_pmu_hw_config()
for this to iterate sibling events and find a mem-loads-aux event.

The for_each_sibling_event() has a lockdep assert to make sure if it
disabled hardirq or hold leader->ctx->mutex.  This works well if the
given event has a separate leader event since perf_try_init_event()
grabs the leader->ctx->mutex to protect the sibling list.  But it can
cause a problem when the event itself is a leader since the event is
not initialized yet and there's no ctx for the event.

Actually I got a lockdep warning when I run the below command on SPR,
but I guess it could be a NULL pointer dereference.

  $ perf record -d -e cpu/mem-loads/uP true

The code path to the warning is:

  sys_perf_event_open()
    perf_event_alloc()
      perf_init_event()
        perf_try_init_event()
          x86_pmu_event_init()
            hsw_hw_config()
              intel_pmu_hw_config()
                for_each_sibling_event()
                  lockdep_assert_event_ctx()

We don't need for_each_sibling_event() when it's a standalone event.
Let's return the error code directly.

Fixes: f3c0eba28704 ("perf: Add a few assertions")
Reported-by: Greg Thelen <gthelen@google.com>
Cc: stable@vger.kernel.org
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 arch/x86/events/intel/core.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 0d09245aa8df..933fe4894c32 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -3983,6 +3983,14 @@ static int intel_pmu_hw_config(struct perf_event *event)
 		struct perf_event *leader = event->group_leader;
 		struct perf_event *sibling = NULL;
 
+		/*
+		 * The event is not fully initialized yet and no ctx is set
+		 * for the event.  Avoid for_each_sibling_event() since it
+		 * has a lockdep assert with leader->ctx->mutex.
+		 */
+		if (leader == event)
+			return -ENODATA;
+
 		if (!is_mem_loads_aux_event(leader)) {
 			for_each_sibling_event(sibling, leader) {
 				if (is_mem_loads_aux_event(sibling))
-- 
2.41.0.255.g8b1d071c50-goog


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

* Re: [PATCH] perf/x86: Fix lockdep warning in for_each_sibling_event() on SPR
  2023-07-04 18:15 [PATCH] perf/x86: Fix lockdep warning in for_each_sibling_event() on SPR Namhyung Kim
@ 2023-07-05  8:38 ` Peter Zijlstra
  2023-07-05 15:11   ` Namhyung Kim
  2023-07-10  8:13 ` [tip: perf/urgent] " tip-bot2 for Namhyung Kim
  1 sibling, 1 reply; 6+ messages in thread
From: Peter Zijlstra @ 2023-07-05  8:38 UTC (permalink / raw)
  To: Namhyung Kim
  Cc: Ingo Molnar, Mark Rutland, Alexander Shishkin,
	Arnaldo Carvalho de Melo, LKML, Kan Liang, Stephane Eranian,
	Greg Thelen, stable

On Tue, Jul 04, 2023 at 11:15:15AM -0700, Namhyung Kim wrote:
> On SPR, the load latency event needs an auxiliary event in the same
> group to work properly.  There's a check in intel_pmu_hw_config()
> for this to iterate sibling events and find a mem-loads-aux event.
> 
> The for_each_sibling_event() has a lockdep assert to make sure if it
> disabled hardirq or hold leader->ctx->mutex.  This works well if the
> given event has a separate leader event since perf_try_init_event()
> grabs the leader->ctx->mutex to protect the sibling list.  But it can
> cause a problem when the event itself is a leader since the event is
> not initialized yet and there's no ctx for the event.
> 
> Actually I got a lockdep warning when I run the below command on SPR,
> but I guess it could be a NULL pointer dereference.
> 
>   $ perf record -d -e cpu/mem-loads/uP true
> 
> The code path to the warning is:
> 
>   sys_perf_event_open()
>     perf_event_alloc()
>       perf_init_event()
>         perf_try_init_event()
>           x86_pmu_event_init()
>             hsw_hw_config()
>               intel_pmu_hw_config()
>                 for_each_sibling_event()
>                   lockdep_assert_event_ctx()
> 
> We don't need for_each_sibling_event() when it's a standalone event.
> Let's return the error code directly.
> 
> Fixes: f3c0eba28704 ("perf: Add a few assertions")
> Reported-by: Greg Thelen <gthelen@google.com>
> Cc: stable@vger.kernel.org
> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
> ---
>  arch/x86/events/intel/core.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
> index 0d09245aa8df..933fe4894c32 100644
> --- a/arch/x86/events/intel/core.c
> +++ b/arch/x86/events/intel/core.c
> @@ -3983,6 +3983,14 @@ static int intel_pmu_hw_config(struct perf_event *event)
>  		struct perf_event *leader = event->group_leader;
>  		struct perf_event *sibling = NULL;
>  
> +		/*
> +		 * The event is not fully initialized yet and no ctx is set
> +		 * for the event.  Avoid for_each_sibling_event() since it
> +		 * has a lockdep assert with leader->ctx->mutex.
> +		 */

If I understand things correctly, your patch is indeed correct, however
I don't much like this comment, does something like:

		/*
		 * When this memload event is also the first event (no
		 * group exists yet), then there is no aux event before
		 * it.
		 */

work for you?

> +		if (leader == event)
> +			return -ENODATA;
> +
>  		if (!is_mem_loads_aux_event(leader)) {
>  			for_each_sibling_event(sibling, leader) {
>  				if (is_mem_loads_aux_event(sibling))
> -- 
> 2.41.0.255.g8b1d071c50-goog
> 

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

* Re: [PATCH] perf/x86: Fix lockdep warning in for_each_sibling_event() on SPR
  2023-07-05  8:38 ` Peter Zijlstra
@ 2023-07-05 15:11   ` Namhyung Kim
  2023-07-06  7:29     ` Peter Zijlstra
  0 siblings, 1 reply; 6+ messages in thread
From: Namhyung Kim @ 2023-07-05 15:11 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Mark Rutland, Alexander Shishkin,
	Arnaldo Carvalho de Melo, LKML, Kan Liang, Stephane Eranian,
	Greg Thelen, stable

Hi Peter,

On Wed, Jul 5, 2023 at 1:38 AM Peter Zijlstra <peterz@infradead.org> wrote:
>
> On Tue, Jul 04, 2023 at 11:15:15AM -0700, Namhyung Kim wrote:
> > On SPR, the load latency event needs an auxiliary event in the same
> > group to work properly.  There's a check in intel_pmu_hw_config()
> > for this to iterate sibling events and find a mem-loads-aux event.
> >
> > The for_each_sibling_event() has a lockdep assert to make sure if it
> > disabled hardirq or hold leader->ctx->mutex.  This works well if the
> > given event has a separate leader event since perf_try_init_event()
> > grabs the leader->ctx->mutex to protect the sibling list.  But it can
> > cause a problem when the event itself is a leader since the event is
> > not initialized yet and there's no ctx for the event.
> >
> > Actually I got a lockdep warning when I run the below command on SPR,
> > but I guess it could be a NULL pointer dereference.
> >
> >   $ perf record -d -e cpu/mem-loads/uP true
> >
> > The code path to the warning is:
> >
> >   sys_perf_event_open()
> >     perf_event_alloc()
> >       perf_init_event()
> >         perf_try_init_event()
> >           x86_pmu_event_init()
> >             hsw_hw_config()
> >               intel_pmu_hw_config()
> >                 for_each_sibling_event()
> >                   lockdep_assert_event_ctx()
> >
> > We don't need for_each_sibling_event() when it's a standalone event.
> > Let's return the error code directly.
> >
> > Fixes: f3c0eba28704 ("perf: Add a few assertions")
> > Reported-by: Greg Thelen <gthelen@google.com>
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Namhyung Kim <namhyung@kernel.org>
> > ---
> >  arch/x86/events/intel/core.c | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> >
> > diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
> > index 0d09245aa8df..933fe4894c32 100644
> > --- a/arch/x86/events/intel/core.c
> > +++ b/arch/x86/events/intel/core.c
> > @@ -3983,6 +3983,14 @@ static int intel_pmu_hw_config(struct perf_event *event)
> >               struct perf_event *leader = event->group_leader;
> >               struct perf_event *sibling = NULL;
> >
> > +             /*
> > +              * The event is not fully initialized yet and no ctx is set
> > +              * for the event.  Avoid for_each_sibling_event() since it
> > +              * has a lockdep assert with leader->ctx->mutex.
> > +              */
>
> If I understand things correctly, your patch is indeed correct, however
> I don't much like this comment, does something like:
>
>                 /*
>                  * When this memload event is also the first event (no
>                  * group exists yet), then there is no aux event before
>                  * it.
>                  */
>
> work for you?

Yep, looks good.  Do you want me to resend?

Thanks,
Namhyung


>
> > +             if (leader == event)
> > +                     return -ENODATA;
> > +
> >               if (!is_mem_loads_aux_event(leader)) {
> >                       for_each_sibling_event(sibling, leader) {
> >                               if (is_mem_loads_aux_event(sibling))
> > --
> > 2.41.0.255.g8b1d071c50-goog
> >

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

* Re: [PATCH] perf/x86: Fix lockdep warning in for_each_sibling_event() on SPR
  2023-07-05 15:11   ` Namhyung Kim
@ 2023-07-06  7:29     ` Peter Zijlstra
  2023-07-07 20:35       ` Namhyung Kim
  0 siblings, 1 reply; 6+ messages in thread
From: Peter Zijlstra @ 2023-07-06  7:29 UTC (permalink / raw)
  To: Namhyung Kim
  Cc: Ingo Molnar, Mark Rutland, Alexander Shishkin,
	Arnaldo Carvalho de Melo, LKML, Kan Liang, Stephane Eranian,
	Greg Thelen, stable

On Wed, Jul 05, 2023 at 08:11:53AM -0700, Namhyung Kim wrote:
> Yep, looks good.  Do you want me to resend?

Nah, I've got it. Thanks!

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

* Re: [PATCH] perf/x86: Fix lockdep warning in for_each_sibling_event() on SPR
  2023-07-06  7:29     ` Peter Zijlstra
@ 2023-07-07 20:35       ` Namhyung Kim
  0 siblings, 0 replies; 6+ messages in thread
From: Namhyung Kim @ 2023-07-07 20:35 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Mark Rutland, Alexander Shishkin,
	Arnaldo Carvalho de Melo, LKML, Kan Liang, Stephane Eranian,
	Greg Thelen, stable

On Thu, Jul 6, 2023 at 12:29 AM Peter Zijlstra <peterz@infradead.org> wrote:
>
> On Wed, Jul 05, 2023 at 08:11:53AM -0700, Namhyung Kim wrote:
> > Yep, looks good.  Do you want me to resend?
>
> Nah, I've got it. Thanks!

Thanks Peter!

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

* [tip: perf/urgent] perf/x86: Fix lockdep warning in for_each_sibling_event() on SPR
  2023-07-04 18:15 [PATCH] perf/x86: Fix lockdep warning in for_each_sibling_event() on SPR Namhyung Kim
  2023-07-05  8:38 ` Peter Zijlstra
@ 2023-07-10  8:13 ` tip-bot2 for Namhyung Kim
  1 sibling, 0 replies; 6+ messages in thread
From: tip-bot2 for Namhyung Kim @ 2023-07-10  8:13 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Greg Thelen, Namhyung Kim, Peter Zijlstra (Intel),
	stable, x86, linux-kernel

The following commit has been merged into the perf/urgent branch of tip:

Commit-ID:     27c68c216ee1f1b086e789a64486e6511e380b8a
Gitweb:        https://git.kernel.org/tip/27c68c216ee1f1b086e789a64486e6511e380b8a
Author:        Namhyung Kim <namhyung@kernel.org>
AuthorDate:    Tue, 04 Jul 2023 11:15:15 -07:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Mon, 10 Jul 2023 09:52:20 +02:00

perf/x86: Fix lockdep warning in for_each_sibling_event() on SPR

On SPR, the load latency event needs an auxiliary event in the same
group to work properly.  There's a check in intel_pmu_hw_config()
for this to iterate sibling events and find a mem-loads-aux event.

The for_each_sibling_event() has a lockdep assert to make sure if it
disabled hardirq or hold leader->ctx->mutex.  This works well if the
given event has a separate leader event since perf_try_init_event()
grabs the leader->ctx->mutex to protect the sibling list.  But it can
cause a problem when the event itself is a leader since the event is
not initialized yet and there's no ctx for the event.

Actually I got a lockdep warning when I run the below command on SPR,
but I guess it could be a NULL pointer dereference.

  $ perf record -d -e cpu/mem-loads/uP true

The code path to the warning is:

  sys_perf_event_open()
    perf_event_alloc()
      perf_init_event()
        perf_try_init_event()
          x86_pmu_event_init()
            hsw_hw_config()
              intel_pmu_hw_config()
                for_each_sibling_event()
                  lockdep_assert_event_ctx()

We don't need for_each_sibling_event() when it's a standalone event.
Let's return the error code directly.

Fixes: f3c0eba28704 ("perf: Add a few assertions")
Reported-by: Greg Thelen <gthelen@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: stable@vger.kernel.org
Link: https://lkml.kernel.org/r/20230704181516.3293665-1-namhyung@kernel.org
---
 arch/x86/events/intel/core.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index a149faf..2a284ba 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -3993,6 +3993,13 @@ static int intel_pmu_hw_config(struct perf_event *event)
 		struct perf_event *leader = event->group_leader;
 		struct perf_event *sibling = NULL;
 
+		/*
+		 * When this memload event is also the first event (no group
+		 * exists yet), then there is no aux event before it.
+		 */
+		if (leader == event)
+			return -ENODATA;
+
 		if (!is_mem_loads_aux_event(leader)) {
 			for_each_sibling_event(sibling, leader) {
 				if (is_mem_loads_aux_event(sibling))

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

end of thread, other threads:[~2023-07-10  8:13 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-04 18:15 [PATCH] perf/x86: Fix lockdep warning in for_each_sibling_event() on SPR Namhyung Kim
2023-07-05  8:38 ` Peter Zijlstra
2023-07-05 15:11   ` Namhyung Kim
2023-07-06  7:29     ` Peter Zijlstra
2023-07-07 20:35       ` Namhyung Kim
2023-07-10  8:13 ` [tip: perf/urgent] " tip-bot2 for Namhyung Kim

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®