From: "George Spelvin" <linux@horizon.com>
To: john.stultz@linaro.org
Cc: linux@horizon.com, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 4/4] timekeeping: Use printk_deferred when holding timekeeping seqlock
Date: 6 May 2014 17:33:06 -0400 [thread overview]
Message-ID: <20140506213306.17674.qmail@ns.horizon.com> (raw)
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.
next reply other threads:[~2014-05-06 21:39 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-06 21:33 George Spelvin [this message]
2014-05-12 16:21 ` [rough draft PATCH] avoid stalls on the " George Spelvin
2014-05-12 18:23 ` John Stultz
2014-05-12 17:49 ` [PATCH 4/4] timekeeping: Use printk_deferred when holding " 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-13 2:45 ` [PATCH 1/2] timekeeping: Use unsigned int for seqlock sequence George Spelvin
2014-05-13 11:49 ` Mathieu Desnoyers
2014-05-13 2:48 ` [PATCH 2/2] timekeeping: Mark struct timekeeper * passed to notifiers as const George Spelvin
-- strict thread matches above, loose matches on Subject: below --
2014-05-05 20:47 [PATCH 0/4] Convert timekeeping core to use printk_deferred (v3) John Stultz
2014-05-05 20:47 ` [PATCH 4/4] timekeeping: Use printk_deferred when holding timekeeping seqlock John Stultz
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
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=20140506213306.17674.qmail@ns.horizon.com \
--to=linux@horizon.com \
--cc=john.stultz@linaro.org \
--cc=linux-kernel@vger.kernel.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®