From: Steven Rostedt <rostedt@goodmis.org>
To: John Hubbard <jhubbard@nvidia.com>
Cc: Vlastimil Babka <vbabka@suse.cz>,
LKML <linux-kernel@vger.kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
akpm@linux-foundation.org, linux-mm@kvack.org,
Cong Wang <xiyou.wangcong@gmail.com>,
Dave Hansen <dave.hansen@intel.com>,
Johannes Weiner <hannes@cmpxchg.org>,
Mel Gorman <mgorman@suse.de>, Michal Hocko <mhocko@kernel.org>,
Petr Mladek <pmladek@suse.com>,
Sergey Senozhatsky <sergey.senozhatsky@gmail.com>,
"yuwang.yuwang" <yuwang.yuwang@alibaba-inc.com>,
Linus Torvalds <torvalds@linux-foundation.org>,
Jan Kara <jack@suse.cz>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Subject: Re: [PATCH v3] printk: Add console owner and waiter logic to load balance console writes
Date: Fri, 3 Nov 2017 07:54:04 -0400 [thread overview]
Message-ID: <20171103075404.14f9058a@vmware.local.home> (raw)
In-Reply-To: <20171103072121.3c2fd5ab@vmware.local.home>
On Fri, 3 Nov 2017 07:21:21 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:
> On Thu, 2 Nov 2017 21:09:32 -0700
> John Hubbard <jhubbard@nvidia.com> wrote:
>
>
> > For example, if there are 3 or more threads, you can do the following:
> >
> > thread A: holds the console lock, is printing, then moves into the console_unlock
> > phase
> >
> > thread B: goes into the waiter spin loop above, and (once the polarity is corrected)
> > waits for console_waiter to become 0
> >
> > thread A: finishing up, sets console_waiter --> 0
> >
> > thread C: before thread B notices, thread C goes into the "else" section, sees that
> > console_waiter == 0, and sets console_waiter --> 1. So thread C now
> > becomes the waiter
>
> But console_waiter only gets set to 1 if console_waiter is 0 *and*
> console_owner is not NULL and is not current. console_owner is only
> updated under a spin lock and console_waiter is only set under a spin
> lock when console_owner is not NULL.
>
> This means this scenario can not happen.
>
>
> >
> > thread B: gets *very* unlucky and never sees the 1 --> 0 --> 1 transition of
> > console_waiter, so it continues waiting. And now we have both B
> > and C in the same spin loop, and this is now broken.
> >
> > At the root, this is really due to the absence of a pre-existing "hand-off this lock"
> > mechanism. And this one here is not quite correct.
> >
> > Solution ideas: for a true hand-off, there needs to be a bit more information
> > exchanged. Conceptually, a (lock-protected) list of waiters (which would
> > only ever have zero or one entries) is a good way to start thinking about it.
>
> As stated above, the console owner check will prevent this issue.
>
I'll condense the patch to show what I mean:
To become a waiter, a task must do the following:
+ printk_safe_enter_irqsave(flags);
+
+ raw_spin_lock(&console_owner_lock);
+ owner = READ_ONCE(console_owner);
+ waiter = READ_ONCE(console_waiter);
+ if (!waiter && owner && owner != current) {
+ WRITE_ONCE(console_waiter, true);
+ spin = true;
+ }
+ raw_spin_unlock(&console_owner_lock);
The new waiter gets set only if there isn't already a waiter *and*
there is an owner that is not current (and with the printk_safe_enter I
don't think that is even needed).
+ while (!READ_ONCE(console_waiter))
+ cpu_relax();
The spin is outside the spin lock. But only the owner can clear it.
Now the owner is doing a loop of this (with interrupts disabled)
+ raw_spin_lock(&console_owner_lock);
+ console_owner = current;
+ raw_spin_unlock(&console_owner_lock);
Write to consoles.
+ raw_spin_lock(&console_owner_lock);
+ waiter = READ_ONCE(console_waiter);
+ console_owner = NULL;
+ raw_spin_unlock(&console_owner_lock);
+ if (waiter)
+ break;
At this moment console_owner is NULL, and no new waiters can happen.
The next owner will be the waiter that is spinning.
+ if (waiter) {
+ WRITE_ONCE(console_waiter, false);
There is no possibility of another task sneaking in and becoming a
waiter at this moment. The console_owner was cleared under spin lock,
and a waiter is only set under the same spin lock if owner is set.
There will be no new owner sneaking in because to become the owner, you
must have the console lock. Since it is never released between the time
the owner clears console_waiter and the waiter takes the console lock,
there is no race.
-- Steve
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2017-11-03 11:54 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-02 17:45 [PATCH v3] printk: Add console owner and waiter logic to load balance console writes Steven Rostedt
2017-11-02 22:16 ` Vlastimil Babka
2017-11-03 3:15 ` Steven Rostedt
2017-11-04 3:13 ` Sergey Senozhatsky
2017-11-03 4:09 ` John Hubbard
2017-11-03 11:21 ` Steven Rostedt
2017-11-03 11:54 ` Steven Rostedt [this message]
2017-11-03 11:54 ` Steven Rostedt
2017-11-03 21:46 ` John Hubbard
2017-11-04 3:34 ` John Hubbard
2017-11-04 8:32 ` [PATCH v3] printk: Add console owner and waiter logic to loadbalance " Tetsuo Handa
2017-11-04 8:43 ` Tetsuo Handa
2017-11-06 12:06 ` [PATCH v3] printk: Add console owner and waiter logic to load balance " Tetsuo Handa
2017-11-07 1:40 ` Sergey Senozhatsky
2017-11-07 11:05 ` [PATCH v3] printk: Add console owner and waiter logic to loadbalance " Tetsuo Handa
2017-11-08 5:19 ` [PATCH v3] printk: Add console owner and waiter logic to load balance " Sergey Senozhatsky
2017-11-08 14:29 ` Steven Rostedt
2017-11-09 0:56 ` Sergey Senozhatsky
2017-11-09 3:29 ` Steven Rostedt
2017-11-09 4:45 ` Sergey Senozhatsky
2017-11-09 5:06 ` Steven Rostedt
2017-11-09 5:33 ` Sergey Senozhatsky
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=20171103075404.14f9058a@vmware.local.home \
--to=rostedt@goodmis.org \
--cc=akpm@linux-foundation.org \
--cc=dave.hansen@intel.com \
--cc=hannes@cmpxchg.org \
--cc=jack@suse.cz \
--cc=jhubbard@nvidia.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=mgorman@suse.de \
--cc=mhocko@kernel.org \
--cc=penguin-kernel@I-love.SAKURA.ne.jp \
--cc=peterz@infradead.org \
--cc=pmladek@suse.com \
--cc=sergey.senozhatsky@gmail.com \
--cc=torvalds@linux-foundation.org \
--cc=vbabka@suse.cz \
--cc=xiyou.wangcong@gmail.com \
--cc=yuwang.yuwang@alibaba-inc.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).