2020-01-29 16:15:10

by Amol Grover

[permalink] [raw]
Subject: [PATCH 1/2] events: callchain: Annotate RCU pointer with __rcu

Fixes following instances of sparse error
error: incompatible types in comparison expression
(different address spaces)
kernel/events/callchain.c:66:9: error: incompatible types in comparison
kernel/events/callchain.c:96:9: error: incompatible types in comparison
kernel/events/callchain.c:161:19: error: incompatible types in comparison

This introduces the following warning
kernel/events/callchain.c:65:17: warning: incorrect type in assignment

Signed-off-by: Amol Grover <[email protected]>
---
kernel/events/callchain.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/events/callchain.c b/kernel/events/callchain.c
index c2b41a263166..f91e1f41d25d 100644
--- a/kernel/events/callchain.c
+++ b/kernel/events/callchain.c
@@ -32,7 +32,7 @@ static inline size_t perf_callchain_entry__sizeof(void)
static DEFINE_PER_CPU(int, callchain_recursion[PERF_NR_CONTEXTS]);
static atomic_t nr_callchain_events;
static DEFINE_MUTEX(callchain_mutex);
-static struct callchain_cpus_entries *callchain_cpus_entries;
+static struct callchain_cpus_entries __rcu *callchain_cpus_entries;


__weak void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
--
2.24.1


2020-01-29 16:30:11

by Amol Grover

[permalink] [raw]
Subject: [PATCH 2/2] events: callchain: Use RCU API to access RCU pointer

callchain_cpus_entries is annotated as an RCU pointer.
Hence rcu_dereference_protected or similar RCU API is
required to dereference the pointer.

This fixes the following sparse warning
kernel/events/callchain.c:65:17: warning: incorrect type in assignment

Signed-off-by: Amol Grover <[email protected]>
---
kernel/events/callchain.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/kernel/events/callchain.c b/kernel/events/callchain.c
index f91e1f41d25d..a672d02a1b3a 100644
--- a/kernel/events/callchain.c
+++ b/kernel/events/callchain.c
@@ -62,7 +62,8 @@ static void release_callchain_buffers(void)
{
struct callchain_cpus_entries *entries;

- entries = callchain_cpus_entries;
+ entries = rcu_dereference_protected(callchain_cpus_entries,
+ lockdep_is_held(&callchain_mutex));
RCU_INIT_POINTER(callchain_cpus_entries, NULL);
call_rcu(&entries->rcu_head, release_callchain_buffers_rcu);
}
--
2.24.1

2020-01-29 22:21:20

by Joel Fernandes

[permalink] [raw]
Subject: Re: [PATCH 2/2] events: callchain: Use RCU API to access RCU pointer

On Wed, Jan 29, 2020 at 09:38:13PM +0530, Amol Grover wrote:
> callchain_cpus_entries is annotated as an RCU pointer.
> Hence rcu_dereference_protected or similar RCU API is
> required to dereference the pointer.
>
> This fixes the following sparse warning
> kernel/events/callchain.c:65:17: warning: incorrect type in assignment
>
> Signed-off-by: Amol Grover <[email protected]>
> ---
> kernel/events/callchain.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/events/callchain.c b/kernel/events/callchain.c
> index f91e1f41d25d..a672d02a1b3a 100644
> --- a/kernel/events/callchain.c
> +++ b/kernel/events/callchain.c
> @@ -62,7 +62,8 @@ static void release_callchain_buffers(void)
> {
> struct callchain_cpus_entries *entries;
>
> - entries = callchain_cpus_entries;
> + entries = rcu_dereference_protected(callchain_cpus_entries,
> + lockdep_is_held(&callchain_mutex));


Reviewed-by: Joel Fernandes (Google) <[email protected]>

thanks,

- Joel


> RCU_INIT_POINTER(callchain_cpus_entries, NULL);
> call_rcu(&entries->rcu_head, release_callchain_buffers_rcu);
> }
> --
> 2.24.1
>

2020-01-29 22:22:03

by Joel Fernandes

[permalink] [raw]
Subject: Re: [PATCH 1/2] events: callchain: Annotate RCU pointer with __rcu

On Wed, Jan 29, 2020 at 09:38:12PM +0530, Amol Grover wrote:
> Fixes following instances of sparse error
> error: incompatible types in comparison expression
> (different address spaces)
> kernel/events/callchain.c:66:9: error: incompatible types in comparison
> kernel/events/callchain.c:96:9: error: incompatible types in comparison
> kernel/events/callchain.c:161:19: error: incompatible types in comparison
>
> This introduces the following warning
> kernel/events/callchain.c:65:17: warning: incorrect type in assignment

Would have been nice if you mentioned the warning is fixed in your second
patch. But I think its ok.

Reviewed-by: Joel Fernandes (Google) <[email protected]>

thanks,

- Joel

>
> Signed-off-by: Amol Grover <[email protected]>
> ---
> kernel/events/callchain.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/kernel/events/callchain.c b/kernel/events/callchain.c
> index c2b41a263166..f91e1f41d25d 100644
> --- a/kernel/events/callchain.c
> +++ b/kernel/events/callchain.c
> @@ -32,7 +32,7 @@ static inline size_t perf_callchain_entry__sizeof(void)
> static DEFINE_PER_CPU(int, callchain_recursion[PERF_NR_CONTEXTS]);
> static atomic_t nr_callchain_events;
> static DEFINE_MUTEX(callchain_mutex);
> -static struct callchain_cpus_entries *callchain_cpus_entries;
> +static struct callchain_cpus_entries __rcu *callchain_cpus_entries;
>
>
> __weak void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
> --
> 2.24.1
>

2020-01-30 08:24:53

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCH 2/2] events: callchain: Use RCU API to access RCU pointer

On Wed, Jan 29, 2020 at 05:19:09PM -0500, Joel Fernandes wrote:
> On Wed, Jan 29, 2020 at 09:38:13PM +0530, Amol Grover wrote:
> > callchain_cpus_entries is annotated as an RCU pointer.
> > Hence rcu_dereference_protected or similar RCU API is
> > required to dereference the pointer.
> >
> > This fixes the following sparse warning
> > kernel/events/callchain.c:65:17: warning: incorrect type in assignment

Seems silly to have this two patches; the first introduces the second
issue, might as well fix it all in one go.

Also look at the output of:

git log --oneline kernel/events/

and then at your $subject.

> > Signed-off-by: Amol Grover <[email protected]>
> > ---
> > kernel/events/callchain.c | 3 ++-
> > 1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/kernel/events/callchain.c b/kernel/events/callchain.c
> > index f91e1f41d25d..a672d02a1b3a 100644
> > --- a/kernel/events/callchain.c
> > +++ b/kernel/events/callchain.c
> > @@ -62,7 +62,8 @@ static void release_callchain_buffers(void)
> > {
> > struct callchain_cpus_entries *entries;
> >
> > - entries = callchain_cpus_entries;
> > + entries = rcu_dereference_protected(callchain_cpus_entries,
> > + lockdep_is_held(&callchain_mutex));
>
>
> Reviewed-by: Joel Fernandes (Google) <[email protected]>

Do we really need that smp_read_barrier_depends() here? Then again, I
don't suppose this is a fast path.

IIRC even Alpha got the dependent write ordering right.

> > RCU_INIT_POINTER(callchain_cpus_entries, NULL);
> > call_rcu(&entries->rcu_head, release_callchain_buffers_rcu);
> > }
> > --
> > 2.24.1
> >

2020-01-30 10:17:19

by Amol Grover

[permalink] [raw]
Subject: Re: [PATCH 2/2] events: callchain: Use RCU API to access RCU pointer

On Thu, Jan 30, 2020 at 09:23:21AM +0100, Peter Zijlstra wrote:
> On Wed, Jan 29, 2020 at 05:19:09PM -0500, Joel Fernandes wrote:
> > On Wed, Jan 29, 2020 at 09:38:13PM +0530, Amol Grover wrote:
> > > callchain_cpus_entries is annotated as an RCU pointer.
> > > Hence rcu_dereference_protected or similar RCU API is
> > > required to dereference the pointer.
> > >
> > > This fixes the following sparse warning
> > > kernel/events/callchain.c:65:17: warning: incorrect type in assignment
>
> Seems silly to have this two patches; the first introduces the second
> issue, might as well fix it all in one go.
>

Got it. I'll combine them into a single patch and re-send.

> Also look at the output of:
>
> git log --oneline kernel/events/
>
> and then at your $subject.
>
> > > Signed-off-by: Amol Grover <[email protected]>
> > > ---
> > > kernel/events/callchain.c | 3 ++-
> > > 1 file changed, 2 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/kernel/events/callchain.c b/kernel/events/callchain.c
> > > index f91e1f41d25d..a672d02a1b3a 100644
> > > --- a/kernel/events/callchain.c
> > > +++ b/kernel/events/callchain.c
> > > @@ -62,7 +62,8 @@ static void release_callchain_buffers(void)
> > > {
> > > struct callchain_cpus_entries *entries;
> > >
> > > - entries = callchain_cpus_entries;
> > > + entries = rcu_dereference_protected(callchain_cpus_entries,
> > > + lockdep_is_held(&callchain_mutex));
> >
> >
> > Reviewed-by: Joel Fernandes (Google) <[email protected]>
>
> Do we really need that smp_read_barrier_depends() here? Then again, I
> don't suppose this is a fast path.
>

rcu_dereference_protected is actually a lightweight API and IIRC it
omits the READ_ONCE() and hence the memory barriers.

Thanks
Amol

> IIRC even Alpha got the dependent write ordering right.
>
> > > RCU_INIT_POINTER(callchain_cpus_entries, NULL);
> > > call_rcu(&entries->rcu_head, release_callchain_buffers_rcu);
> > > }
> > > --
> > > 2.24.1
> > >

2020-01-30 13:34:59

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCH 2/2] events: callchain: Use RCU API to access RCU pointer

On Thu, Jan 30, 2020 at 03:44:51PM +0530, Amol Grover wrote:
> > > > diff --git a/kernel/events/callchain.c b/kernel/events/callchain.c
> > > > index f91e1f41d25d..a672d02a1b3a 100644
> > > > --- a/kernel/events/callchain.c
> > > > +++ b/kernel/events/callchain.c
> > > > @@ -62,7 +62,8 @@ static void release_callchain_buffers(void)
> > > > {
> > > > struct callchain_cpus_entries *entries;
> > > >
> > > > - entries = callchain_cpus_entries;
> > > > + entries = rcu_dereference_protected(callchain_cpus_entries,
> > > > + lockdep_is_held(&callchain_mutex));
> > >
> > >
> > > Reviewed-by: Joel Fernandes (Google) <[email protected]>
> >
> > Do we really need that smp_read_barrier_depends() here? Then again, I
> > don't suppose this is a fast path.
> >
>
> rcu_dereference_protected is actually a lightweight API and IIRC it
> omits the READ_ONCE() and hence the memory barriers.

Oh argh, indeed. I suppose I should've had more tea this morning.