From: "Paul E. McKenney" <paulmck@linux.ibm.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: kbuild test robot <lkp@intel.com>,
Suren Baghdasaryan <surenb@google.com>,
kbuild-all@01.org, Johannes Weiner <hannes@cmpxchg.org>,
Linux Memory Management List <linux-mm@kvack.org>
Subject: Re: [linux-next:master 6618/6917] kernel/sched/psi.c:1230:13: sparse: error: incompatible types in comparison expression (different address spaces)
Date: Fri, 8 Feb 2019 23:44:07 -0800 [thread overview]
Message-ID: <20190209074407.GE4240@linux.ibm.com> (raw)
In-Reply-To: <20190208151441.4048e6968579dd178b259609@linux-foundation.org>
On Fri, Feb 08, 2019 at 03:14:41PM -0800, Andrew Morton wrote:
> On Fri, 8 Feb 2019 02:29:33 +0800 kbuild test robot <lkp@intel.com> wrote:
>
> > tree: https://urldefense.proofpoint.com/v2/url?u=https-3A__git.kernel.org_pub_scm_linux_kernel_git_next_linux-2Dnext.git&d=DwICAg&c=jf_iaSHvJObTbx-siA1ZOg&r=q4hkQkeaNH3IlTsPvEwkaUALMqf7y6jCMwT5b6lVQbQ&m=myIJaLgovNwHx7SqCW_p1sQx2YvRlmVbShFnuZEFqxY&s=0Y32d-tVCGOq6Vu_VAGgVgbEplhfvOSJ5evHbXTtyBI&e= master
> > head: 1bd831d68d5521c01d783af0275439ac645f5027
> > commit: e7acbba0d6f7a24c8d24280089030eb9a0eb7522 [6618/6917] psi: introduce psi monitor
> > reproduce:
> > # apt-get install sparse
> > git checkout e7acbba0d6f7a24c8d24280089030eb9a0eb7522
> > make ARCH=x86_64 allmodconfig
> > make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'
> >
> > All errors (new ones prefixed by >>):
> >
> > kernel/sched/psi.c:151:6: sparse: warning: symbol 'psi_enable' was not declared. Should it be static?
> > >> kernel/sched/psi.c:1230:13: sparse: error: incompatible types in comparison expression (different address spaces)
> > kernel/sched/psi.c:774:30: sparse: warning: dereference of noderef expression
> >
> > vim +1230 kernel/sched/psi.c
> >
> > 1222
> > 1223 static __poll_t psi_fop_poll(struct file *file, poll_table *wait)
> > 1224 {
> > 1225 struct seq_file *seq = file->private_data;
> > 1226 struct psi_trigger *t;
> > 1227 __poll_t ret;
> > 1228
> > 1229 rcu_read_lock();
> > > 1230 t = rcu_dereference(seq->private);
> > 1231 if (t)
> > 1232 ret = psi_trigger_poll(t, file, wait);
> > 1233 else
> > 1234 ret = DEFAULT_POLLMASK | EPOLLERR | EPOLLPRI;
> > 1235 rcu_read_unlock();
> > 1236
> > 1237 return ret;
> > 1238
>
> Well a bit of googling led me to this fix:
>
> --- a/kernel/sched/psi.c~psi-introduce-psi-monitor-fix-fix
> +++ a/kernel/sched/psi.c
> @@ -1227,7 +1227,7 @@ static __poll_t psi_fop_poll(struct file
> __poll_t ret;
>
> rcu_read_lock();
> - t = rcu_dereference(seq->private);
> + t = rcu_dereference_raw(seq->private);
> if (t)
> ret = psi_trigger_poll(t, file, wait);
> else
>
> But I have no idea why this works, nor what's going on in there.
> rcu_dereference_raw() documentation is scant.
>
> Paul, can you please shed light?
First, please avoid using rcu_dereference_raw() where possible. It is
intended for situations where the developer cannot easily state what
is to be protecting access to an RCU-protected data structure. So...
1. If the access needs to be within an RCU read-side critical
section, use rcu_dereference(). With the new consolidated
RCU flavors, an RCU read-side critical section is entered
using rcu_read_lock(), anything that disables bottom halves,
anything that disables interrupts, or anything that disables
preemption.
2. If the access might be within an RCU read-side critical section
on the one hand, or protected by (say) my_lock on the other,
use rcu_dereference_check(), for example:
p1 = rcu_dereference_check(p->rcu_protected_pointer,
lockdep_is_held(&my_lock));
3. If the access might be within an RCU read-side critical section
on the one hand, or protected by either my_lock or your_lock on
the other, again use rcu_dereference_check(), for example:
p1 = rcu_dereference_check(p->rcu_protected_pointer,
lockdep_is_held(&my_lock) ||
lockdep_is_held(&your_lock));
4. If the access is on the update side, so that it is always protected
by my_lock, use rcu_dereference_protected():
p1 = rcu_dereference_protected(p->rcu_protected_pointer,
lockdep_is_held(&my_lock));
This can be extended to handle multiple locks as in #3 above,
and both can be extended to check other conditions as well.
5. If the protection is supplied by the caller, and is thus unknown
to this code, that is when you use rcu_dereference_raw(). Or
I suppose you could use it when the lockdep expression would be
excessively complex, except that a better approach in that case
might be to take a long hard look at your synchronization design.
Still, there are data-locking cases where any one of a very
large number of locks or reference counters suffices to protect the
pointer, so rcu_derefernce_raw() does have its place.
However, its place is probably quite a bit smaller than one
might expect given the number of uses in the current kernel.
Ditto for its synonym, rcu_dereference_protected( ... , 1). :-/
Now on to this sparse checking and what the point of it is. This sparse
checking is opt-in. Its purpose is to catch cases where someone
mistakenly does something like:
p = q->rcu_protected_pointer;
When they should have done this instead:
p = rcu_dereference(q->rcu_protected_pointer);
If you wish to opt into this checking, you need to mark the pointer
definitions (in this case ->private) with __rcu. It may also
be necessary to mark function parameters as well, as is done for
radix_tree_iter_resume(). If you do not wish to use this checking,
you should ignore these sparse warnings.
Unfortunately, I don't know of a way to inform 0-day test robot of
the various maintainers' opt-in/out choices.
Thanx, Paul
next prev parent reply other threads:[~2019-02-09 7:44 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-02-07 18:29 [linux-next:master 6618/6917] kernel/sched/psi.c:1230:13: sparse: error: incompatible types in comparison expression (different address spaces) kbuild test robot
2019-02-08 23:14 ` Andrew Morton
2019-02-09 7:44 ` Paul E. McKenney [this message]
2019-02-12 1:00 ` Andrew Morton
2019-02-12 15:54 ` Paul E. McKenney
2019-02-12 1:36 ` Matthew Wilcox
2019-02-12 15:56 ` Paul E. McKenney
2019-02-12 16:25 ` Matthew Wilcox
2019-02-12 16:31 ` Paul E. McKenney
2019-02-12 16:31 ` Johannes Weiner
2019-02-12 16:35 ` Matthew Wilcox
2019-02-14 1:50 ` Suren Baghdasaryan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190209074407.GE4240@linux.ibm.com \
--to=paulmck@linux.ibm.com \
--cc=akpm@linux-foundation.org \
--cc=hannes@cmpxchg.org \
--cc=kbuild-all@01.org \
--cc=linux-mm@kvack.org \
--cc=lkp@intel.com \
--cc=surenb@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).