linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] Convert timekeeping core to use printk_deferred (v3)
@ 2014-05-05 20:47 John Stultz
  2014-05-05 20:47 ` [PATCH 1/4] printk: Disable preemption for printk_sched John Stultz
                   ` (3 more replies)
  0 siblings, 4 replies; 18+ messages in thread
From: John Stultz @ 2014-05-05 20:47 UTC (permalink / raw)
  To: LKML
  Cc: John Stultz, Jan Kara, Peter Zijlstra, Jiri Bohac,
	Thomas Gleixner, Ingo Molnar, Andrew Morton, Steven Rostedt

Recently, Jiri pointed out a potential deadlock when calling printk
while holding the timekeeping seqlock.

Annoyingly, the seqlock lockdep enablement doesn't catch this, as
printk disables lockdep.

When looking for possible solutions, one idea was to use a local buffer
and defer the printk to later. Ends up there is already similar
functionality in printk_sched() to avoid similar style deadlocks w/
the scheduler.

Thus this patchset (based on next/akpm) renames printk_sched to
printk_deferred and then moves the affected timekeeping printks to make
use of it.

There were some points in the discussion between Jan and Peter that
made it seem that there may still be problems lurking in the console
layer, and I'm not sure I fully understand their point, so this solution
may be incomplete.

Additionally, the same issue likely affects any WARN_ONs as well, but
I wanted to get some thoughts on this approach before trying to remove
or convert affected WARN_ONS.

Your thoughts and feedback are greatly appreciated!

thanks
-john

Changes since v2:
* Renamed printk_once_deferred() to printk_deferred_once(), per
  Andrew's suggestion
* Changed adding irqsave/restore to preempt_disable/enable, per
  Jan's suggestion

Changes since v1:
* Rebased on next/akpm, since there are queued prink patches there
* Re-added irqsave/restore per irc discussion w/ PeterZ 


Cc: Jan Kara <jack@suse.cz>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Jiri Bohac <jbohac@suse.cz>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Steven Rostedt <rostedt@goodmis.org>


John Stultz (4):
  printk: Disable preemption for printk_sched
  printk: Rename printk_sched to printk_deferred
  printk: Add printk_deferred_once
  timekeeping: Use printk_deferred when holding timekeeping seqlock

 include/linux/printk.h    | 17 ++++++++++++++---
 kernel/printk/printk.c    |  4 +++-
 kernel/sched/core.c       |  2 +-
 kernel/sched/deadline.c   |  7 +------
 kernel/sched/rt.c         |  8 +-------
 kernel/time/ntp.c         | 15 +++++++++------
 kernel/time/timekeeping.c |  7 ++++---
 7 files changed, 33 insertions(+), 27 deletions(-)

-- 
1.9.1


^ permalink raw reply	[flat|nested] 18+ messages in thread
* Re: [PATCH 4/4] timekeeping: Use printk_deferred when holding timekeeping seqlock
@ 2014-05-06 21:33 George Spelvin
  2014-05-12 17:49 ` John Stultz
  0 siblings, 1 reply; 18+ messages in thread
From: George Spelvin @ 2014-05-06 21:33 UTC (permalink / raw)
  To: john.stultz; +Cc: linux, linux-kernel

One misfeature in the timekeeping seqlock code I noticed is that
read_seqcount_begin returns "unsigned int", not "unsigned long".

Casting to a larger type is harmless, but inefficient.

> This is due to printk() triggering console sem wakeup, which can
> cause scheduling code to trigger hrtimers which may try to read
> the time.

An alternative solution, which avoids the need for this entire patch
series, is to make ktime_get completely nonblocking.

To do that, use a seqlock variant wherein you mintain an array of "struct
timekeeper" structures so that reading is always non-blocking if there
is no writer progress.  (I.e. livelock is remotely possible, but deadlock
is not.)

In the basic version, there are two.  (You can add more to further
reduce the chance of livelock.)  The currently stable one is indicated
by (timekeeper_seq->sequence & 2).  Writers update the appropriate
one ping-pong.  The low two bits indicate four phases:

0: Both timekeepers stable, [0] preferred for reading
1: Timekeeper[1] is being written; read timekeeper[0] only
2: Both timekeepers stable, [1] preferred for reading
3: Timekeeper[0] is being written; read timekeeper[1] only

The actual writer locking code is exactly the current write_seqcount_begin
and write_seqcount_end code.

A reader needs to retry only if end_seq > (start_seq & ~1u) + 2.
Accounting for wraparound, the read sequence is:

unsigned raw_read_FOO_begin(seqcount_t const *s)
{
	unsigned ret = ACCESS_ONCE(s->sequence);
	smp_rmb();
	return ret;
}

unsigned raw_read_FOO_retry(seqcount_t const *s, unsigned start)
{
	smp_rmb();
	start &= ~1u;
	return unlikely(s->seqence - start > 2);
}


A reader does:

        unsigned seq;

        do {
		struct timekeeper const *tk;
                seq = read_FOO_begin(&timekeeper_seq);
 		tk = timekeeper + (seq >> 1 & 1);
		frobnicate(tk);
        } while (read_FOO_retry(&timekeeper_seq, seq));

I haven't yet thought of a good name (to replace FOO) for this.
"seqnonblock"?


If you have more frequent updates, there's another variant that does
away with lsbit of the sequence number, so the writer only increments it
once, after update.  This reduces coherency traffic.  It does, however,
cause more readers to retry unless you go to an array of 4 structures.

^ permalink raw reply	[flat|nested] 18+ messages in thread
* [PATCH 0/4] Convert timekeeping core to use printk_deferred (v2)
@ 2014-05-02 22:09 John Stultz
  2014-05-02 22:09 ` [PATCH 4/4] timekeeping: Use printk_deferred when holding timekeeping seqlock John Stultz
  0 siblings, 1 reply; 18+ messages in thread
From: John Stultz @ 2014-05-02 22:09 UTC (permalink / raw)
  To: LKML
  Cc: John Stultz, Jan Kara, Peter Zijlstra, Jiri Bohac,
	Thomas Gleixner, Ingo Molnar, Andrew Morton, Steven Rostedt

Recently, Jiri pointed out a potential deadlock when calling printk
while holding the timekeeping seqlock.

Annoyingly, the seqlock lockdep enablement doesn't catch this, as
printk disables lockdep.

When looking for possible solutions, one idea was to use a local buffer
and defer the printk to later. Ends up there is already similar
functionality in printk_sched() to avoid similar style deadlocks w/
the scheduler.

Thus this patchset (based on next/akpm) renames printk_sched to
printk_deferred and then moves the affected timekeeping printks to make
use of it.

There were some points in the discussion between Jan and Peter that
made it seem that there may still be problems lurking in the console
layer, and I'm not sure I fully understand their point, so this solution
may be incomplete.

Additionally, the same issue likely affects any WARN_ONs as well, but
I wanted to get some thoughts on this approach before trying to remove
or convert affected WARN_ONS.

Your thoughts and feedback are greatly appreciated!

thanks
-john

Changes since v1:
* Rebased on next/akpm, since there are queued prink patches there
* Re-added irqsave/restore per irc discussion w/ PeterZ 

Cc: Jan Kara <jack@suse.cz>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Jiri Bohac <jbohac@suse.cz>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Steven Rostedt <rostedt@goodmis.org>

John Stultz (4):
  printk: Re-add irqsave/restore in printk_sched
  printk: Rename printk_sched to printk_deferred
  printk: Add printk_once_deferred
  timekeeping: Use printk_deferred when holding timekeeping seqlock

 include/linux/printk.h    | 17 ++++++++++++++---
 kernel/printk/printk.c    |  5 ++++-
 kernel/sched/core.c       |  2 +-
 kernel/sched/deadline.c   |  7 +------
 kernel/sched/rt.c         |  8 +-------
 kernel/time/ntp.c         | 15 +++++++++------
 kernel/time/timekeeping.c |  7 ++++---
 7 files changed, 34 insertions(+), 27 deletions(-)

-- 
1.9.1


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

end of thread, other threads:[~2014-05-13 16:18 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-05 20:47 [PATCH 0/4] Convert timekeeping core to use printk_deferred (v3) John Stultz
2014-05-05 20:47 ` [PATCH 1/4] printk: Disable preemption for printk_sched John Stultz
2014-05-06 10:10   ` Jan Kara
2014-05-05 20:47 ` [PATCH 2/4] printk: Rename printk_sched to printk_deferred John Stultz
2014-05-06 10:11   ` Jan Kara
2014-05-05 20:47 ` [PATCH 3/4] printk: Add printk_deferred_once John Stultz
2014-05-06 11:26   ` Jan Kara
2014-05-05 20:47 ` [PATCH 4/4] timekeeping: Use printk_deferred when holding timekeeping seqlock John Stultz
  -- strict thread matches above, loose matches on Subject: below --
2014-05-06 21:33 George Spelvin
2014-05-12 17:49 ` John Stultz
2014-05-13  2:44   ` George Spelvin
2014-05-13  3:39     ` John Stultz
2014-05-13  5:13       ` George Spelvin
2014-05-13 12:07         ` Mathieu Desnoyers
2014-05-13 13:29           ` George Spelvin
2014-05-13 13:39             ` Mathieu Desnoyers
2014-05-13 16:18               ` George Spelvin
2014-05-02 22:09 [PATCH 0/4] Convert timekeeping core to use printk_deferred (v2) John Stultz
2014-05-02 22:09 ` [PATCH 4/4] timekeeping: Use printk_deferred when holding timekeeping seqlock John Stultz

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).