From: "Paul E. McKenney" <paulmck@kernel.org>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Guenter Roeck <linux@roeck-us.net>,
Peter Zijlstra <peterz@infradead.org>,
Roy Hopkins <rhopkins@suse.de>,
Joel Fernandes <joel@joelfernandes.org>,
Pavel Machek <pavel@denx.de>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, patches@lists.linux.dev,
linux-kernel@vger.kernel.org, akpm@linux-foundation.org,
shuah@kernel.org, patches@kernelci.org,
lkft-triage@lists.linaro.org, jonathanh@nvidia.com,
f.fainelli@gmail.com, sudipm.mukherjee@gmail.com,
srw@sladewatkins.net, rwarsow@gmx.de, conor@kernel.org,
rcu@vger.kernel.org, Ingo Molnar <mingo@kernel.org>
Subject: Re: scheduler problems in -next (was: Re: [PATCH 6.4 000/227] 6.4.7-rc1 review)
Date: Wed, 2 Aug 2023 10:48:53 -0700 [thread overview]
Message-ID: <8ab3ca72-e20c-4b18-803f-bf6937c2cd70@paulmck-laptop> (raw)
In-Reply-To: <CAHk-=wj5iESP-=gJSHe0Mfi=Xh2HdSsy+nm8NSr7DbXB9aBDGQ@mail.gmail.com>
On Wed, Aug 02, 2023 at 10:14:51AM -0700, Linus Torvalds wrote:
> Two quick comments, both of them "this code is a bit odd" rather than
> anything else.
Good to get eyes on this code, so thank you very much!!!
> On Tue, 1 Aug 2023 at 12:11, Paul E. McKenney <paulmck@kernel.org> wrote:
> >
> > diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h
>
> Why is this file called "tasks.h"?
>
> It's not a header file. It makes no sense. It's full of C code. It's
> included in only one place. It's just _weird_.
You are right, it is weird.
This is a holdover from when I was much more concerned about being
criticized for having #ifdef in a .c file, and pretty much every
line in this file is under some combination or another of #ifdefs.
This concern led to kernel/rcu/tree_plugin.h being set up in this way
back when preemptible RCU was introduced, and for good or for bad I just
kept following that pattern.
We could convert this to a .c file, keep the #ifdefs, drop some instances
of "static", add a bunch of declarations, and maybe (or maybe not) push a
function or two into some .h file for performance/inlining reasons. Me, I
would prefer to leave it alone, but we can certainly change it.
> However, more relevantly:
>
> > + mutex_unlock(&rtp->tasks_gp_mutex);
> > set_tasks_gp_state(rtp, RTGS_WAIT_CBS);
>
> Isn't the tasks_gp_mutex the thing that protects the gp state here?
> Shouldn't it be after setting?
Much of the gp state is protected by being accessed only by the gp
kthread. But there is a window in time where the gp might be driven
directly out of the synchronize_rcu_tasks() call. That window in time
does not have a definite end, so this ->tasks_gp_mutex does the needed
mutual exclusion during the transition of gp processing to the newly
created gp kthread.
> > rcuwait_wait_event(&rtp->cbs_wait,
> > (needgpcb = rcu_tasks_need_gpcb(rtp)),
> > TASK_IDLE);
>
> Also, looking at rcu_tasks_need_gpcb() that is now called outside the
> lock, it does something quite odd.
The state of each callback list is protected by the ->lock field of
the rcu_tasks_percpu structure. Yes, rcu_segcblist_n_cbs() is invoked
int rcu_tasks_need_gpcb() outside of the lock, but it is designed for
lockless use. If it is modified just after the check, then there will
be a later wakeup on the one hand or we will just uselessly acquire that
->lock this one time on the other.
Also, ncbs records the number of callbacks seen in that first loop,
then used later, where its value might be stale. This might result in
a collapse back to single-callback-queue operation and a later expansion
back up. Except that at this point we are still in single-CPU mode, so
there should not be any lock contention, which means that there should
still be but a single callback queue. The transition itself is protected
by ->cbs_gbl_lock.
> At the very top of the function does
>
> for (cpu = 0; cpu < smp_load_acquire(&rtp->percpu_dequeue_lim); cpu++) {
>
> and 'smp_load_acquire()' is all about saying "everything *after* this
> load is ordered,
>
> But the way it is done in that loop, it is indeed done at the
> beginning of the loop, but then it's done *after* the loop too, so the
> last smp_load_acquire seems a bit nonsensical.
>
> If you want to load a value and say "this value is now sensible for
> everything that follows", I think you should load it *first*. No?
>
> IOW, wouldn't the whole sequence make more sense as
>
> dequeue_limit = smp_load_acquire(&rtp->percpu_dequeue_lim);
> for (cpu = 0; cpu < dequeue_limit; cpu++) {
>
> and say that everything in rcu_tasks_need_gpcb() is ordered wrt the
> initial limit on entry?
>
> I dunno. That use of "smp_load_acquire()" just seems odd. Memory
> ordering is hard to understand to begin with, but then when you have
> things like loops that do the same ordered load multiple times, it
> goes from "hard to understand" to positively confusing.
Excellent point. I am queueing that change with your Suggested-by.
If testing goes well, it will be as shown below.
Thanx, Paul
------------------------------------------------------------------------
diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h
index 83049a893de5..94bb5abdbb37 100644
--- a/kernel/rcu/tasks.h
+++ b/kernel/rcu/tasks.h
@@ -432,6 +432,7 @@ static void rcu_barrier_tasks_generic(struct rcu_tasks *rtp)
static int rcu_tasks_need_gpcb(struct rcu_tasks *rtp)
{
int cpu;
+ int dequeue_limit;
unsigned long flags;
bool gpdone = poll_state_synchronize_rcu(rtp->percpu_dequeue_gpseq);
long n;
@@ -439,7 +440,8 @@ static int rcu_tasks_need_gpcb(struct rcu_tasks *rtp)
long ncbsnz = 0;
int needgpcb = 0;
- for (cpu = 0; cpu < smp_load_acquire(&rtp->percpu_dequeue_lim); cpu++) {
+ dequeue_limit = smp_load_acquire(&rtp->percpu_dequeue_lim);
+ for (cpu = 0; cpu < dequeue_limit; cpu++) {
struct rcu_tasks_percpu *rtpcp = per_cpu_ptr(rtp->rtpcpu, cpu);
/* Advance and accelerate any new callbacks. */
next prev parent reply other threads:[~2023-08-02 17:50 UTC|newest]
Thread overview: 52+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-25 10:42 [PATCH 6.4 000/227] 6.4.7-rc1 review Greg Kroah-Hartman
2023-07-25 16:27 ` Jon Hunter
2023-07-25 18:12 ` SeongJae Park
2023-07-25 20:14 ` Shuah Khan
2023-07-25 23:05 ` Florian Fainelli
2023-07-26 6:14 ` Bagas Sanjaya
2023-07-26 9:29 ` Conor Dooley
2023-07-26 9:34 ` Ron Economos
2023-07-26 10:11 ` Naresh Kamboju
2023-07-27 0:03 ` Guenter Roeck
2023-07-27 3:58 ` Joel Fernandes
2023-07-27 11:35 ` Pavel Machek
2023-07-27 13:26 ` Joel Fernandes
2023-07-27 14:06 ` Paul E. McKenney
2023-07-27 14:39 ` Guenter Roeck
2023-07-27 16:07 ` Paul E. McKenney
2023-07-27 17:39 ` Guenter Roeck
2023-07-27 20:33 ` Paul E. McKenney
2023-07-27 23:18 ` Joel Fernandes
[not found] ` <99B56FC7-9474-4968-B1DD-5862572FD0BA@joelfernandes.org>
2023-07-28 22:58 ` Paul E. McKenney
2023-07-29 1:25 ` Joel Fernandes
2023-07-29 5:50 ` Paul E. McKenney
2023-07-30 4:00 ` scheduler problems in -next (was: Re: [PATCH 6.4 000/227] 6.4.7-rc1 review) Guenter Roeck
2023-07-31 14:19 ` Peter Zijlstra
2023-07-31 14:35 ` Guenter Roeck
2023-07-31 14:47 ` Peter Zijlstra
2023-07-31 15:03 ` Guenter Roeck
2023-07-31 14:39 ` Peter Zijlstra
2023-07-31 14:48 ` Guenter Roeck
2023-07-31 14:52 ` Peter Zijlstra
2023-07-31 16:08 ` Roy Hopkins
2023-07-31 16:14 ` Peter Zijlstra
2023-07-31 16:30 ` Roy Hopkins
2023-07-31 16:34 ` Guenter Roeck
2023-07-31 21:15 ` Peter Zijlstra
2023-08-01 17:32 ` Guenter Roeck
2023-08-01 19:08 ` Peter Zijlstra
2023-08-01 21:32 ` Paul E. McKenney
2023-08-01 19:11 ` Paul E. McKenney
2023-08-01 19:14 ` Paul E. McKenney
2023-08-02 13:57 ` Roy Hopkins
2023-08-02 15:05 ` Paul E. McKenney
2023-08-02 15:31 ` Roy Hopkins
2023-08-02 16:51 ` Paul E. McKenney
2023-08-02 15:45 ` Guenter Roeck
2023-08-02 17:20 ` Paul E. McKenney
2023-08-02 17:14 ` Linus Torvalds
2023-08-02 17:48 ` Paul E. McKenney [this message]
2023-07-28 4:22 ` [PATCH 6.4 000/227] 6.4.7-rc1 review Guenter Roeck
2023-07-31 3:54 ` Paul E. McKenney
2023-07-31 3:56 ` Paul E. McKenney
2023-07-31 4:16 ` Guenter Roeck
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=8ab3ca72-e20c-4b18-803f-bf6937c2cd70@paulmck-laptop \
--to=paulmck@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=conor@kernel.org \
--cc=f.fainelli@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=joel@joelfernandes.org \
--cc=jonathanh@nvidia.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@roeck-us.net \
--cc=lkft-triage@lists.linaro.org \
--cc=mingo@kernel.org \
--cc=patches@kernelci.org \
--cc=patches@lists.linux.dev \
--cc=pavel@denx.de \
--cc=peterz@infradead.org \
--cc=rcu@vger.kernel.org \
--cc=rhopkins@suse.de \
--cc=rwarsow@gmx.de \
--cc=shuah@kernel.org \
--cc=srw@sladewatkins.net \
--cc=stable@vger.kernel.org \
--cc=sudipm.mukherjee@gmail.com \
--cc=torvalds@linux-foundation.org \
/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
all inboxes | Powered by JetHome®