From: Petr Mladek <pmladek@suse.com>
To: John Ogness <john.ogness@linutronix.de>
Cc: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>,
Peter Zijlstra <peterz@infradead.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
kexec@lists.infradead.org,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
Steven Rostedt <rostedt@goodmis.org>,
Sergey Senozhatsky <sergey.senozhatsky@gmail.com>,
Thomas Gleixner <tglx@linutronix.de>,
Linus Torvalds <torvalds@linux-foundation.org>
Subject: POC: Alternative solution: Re: [PATCH 0/4] printk: reimplement LOG_CONT handling
Date: Wed, 12 Aug 2020 18:39:08 +0200 [thread overview]
Message-ID: <20200812163908.GH12903@alley> (raw)
In-Reply-To: <20200811160551.GC12903@alley>
On Tue 2020-08-11 18:05:51, Petr Mladek wrote:
> On Sat 2020-07-18 16:48:55, John Ogness wrote:
> > On 2020-07-17, Linus Torvalds <torvalds@linux-foundation.org> wrote:
> > > Make sure you test the case of "fast concurrent readers". The last
> > > time we did things like this, it was a disaster, because a concurrent
> > > reader would see and return the _incomplete_ line, and the next entry
> > > was still being generated on another CPU.
> > >
> > > The reader would then decide to return that incomplete line, because
> > > it had something.
> > >
> > > And while in theory this could then be handled properly in user space,
> > > in practice it wasn't. So you'd see a lot of logging tools that would
> > > then report all those continuations as separate log events.
> > >
> > > Which is the whole point of LOG_CONT - for that *not* to happen.
> >
> > I expect this is handled correctly since the reader is not given any
> > parts until a full line is ready, but I will put more focus on testing
> > this to make sure. Thanks for the regression and testing tips.
>
> Hmm, the current patchset has different problem. The continuation
> pieces are correctly passed as a single lines. But empty line is
> printed for each unused sequence number to avoid warnings about
> missed messages in journactl. It looks like:
>
> I am afraid that the only working solution is to store all pieces
> in a single lockless transaction. I think that John already
> proposed using 2nd small lockless buffer for this. The problem
> might be how to synchronize flushing the pieces into the final
> buffer.
Do not panic! It might look scary. But I am less scared
after I wrote some pieces of the pseudo code.
So, I have one crazy idea to add one more state bit so that we
could have:
+ committed: set when the data are written into the data ring.
+ final: set when the data block could not longer get reopened
+ reuse: set when the desctiptor/data block could get reused
"final" bit will define when the descriptor could not longer
get reopened (cleared committed bit) and the data block could
not get extended.
The logic would be the following:
bool prb_reserve() {
desc = try_reopen_desc(seq);
if (desc) {
text_buf = data_alloc_continuous();
if (text_buf)
goto success;
else
/* commit the reopened desc back again */
prb_commit(desc);
}
/* Otherwise, do as before */
desc = desc_reserve();
if (!desc)
goto fail;
text_buf = data_alloc();
...
where:
static struct prb_desc *try_reopen_desc(seq)
{
struct prb_desc *desc;
enum desc_state d_state;
struct prb_desc desc;
d_state = desc_read(desc_ring, seq, &desc);
if (d_state != committed_and_not_finalized)
return NULL;
if (!is_same_context(desc))
return NULL;
/* try to reopen only when the state is still the same */
if(!atomic_long_cmpxchg_relaxed(state_var,
val_committed_and_not_finished,
val_reserved))
return NULL;
return desc;
}
static char *data_alloc_continuous()
{
/*
* Same as data_alloc() with one added parameter:
* unsigned long requested_begin_lpos;
*/
begin_lpos = atomic_long_read(&data_ring->head_lpos);
do {
if (begin_lpos != requested_begin_lpos)
return NULL;
... same as before
} while (!atomic_long_try_cmpxchg(&data_ring->head_lpos, &begin_lpos,
next_lpos)); /* LMM(data_alloc:A) */
if (requested_begin_lpos) {
/* only update tail lpos */
blk_lpos->next = next_lpos;
/* return pointer to the new data space */
return &blk->data[0];
}
/* For completely new block do everything as before */
blk = to_block(data_ring, begin_lpos);
blk->id = id; /* LMM(data_alloc:B) */
...
}
void prb_commit_and_finalize()
{
/* Same as prb_commit() + it will set also 'final' bit */
}
Addintional changes in the code:
+ desc_resrved() will also set 'final' bit in the previous
descriptor so that the descriptor could not longer get reopended
once committed.
+ prb_commit_and_finalize() will be called instead of prb_commit()
when the message ends with '\n'.
+ prb_read() will allow to read the data only when
the state is "committed_and_finalized".
+ desc_make_reusable() can be called only when the desciptor
is in "commited_and_finalized" state.
I am not sure if it is everything. Also it might need some code
refactoring.
But it looks like it might work. And it should not require new barriers.
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
next prev parent reply other threads:[~2020-08-12 16:39 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-17 23:48 [PATCH 0/4] printk: reimplement LOG_CONT handling John Ogness
2020-07-17 23:48 ` [PATCH 1/4] printk: ringbuffer: support dataless records John Ogness
2020-07-20 14:49 ` John Ogness
2020-07-17 23:48 ` [PATCH 2/4] printk: store instead of processing cont parts John Ogness
2020-07-19 14:35 ` Sergey Senozhatsky
2020-07-19 18:27 ` Linus Torvalds
2020-07-20 1:50 ` Sergey Senozhatsky
2020-07-20 18:30 ` Linus Torvalds
2020-07-21 3:53 ` Joe Perches
2020-07-21 14:42 ` Sergey Senozhatsky
2020-07-21 14:57 ` John Ogness
2020-07-29 2:03 ` Sergey Senozhatsky
2020-07-21 15:40 ` Linus Torvalds
2020-07-28 2:22 ` Sergey Senozhatsky
2020-07-17 23:48 ` [PATCH 3/4] printk: process cont records during reading John Ogness
2020-07-17 23:48 ` [PATCH 4/4] ipconfig: cleanup printk usage John Ogness
2020-07-18 0:00 ` [PATCH 0/4] printk: reimplement LOG_CONT handling Linus Torvalds
2020-07-18 14:42 ` John Ogness
2020-07-18 17:42 ` Linus Torvalds
2020-08-11 16:05 ` Petr Mladek
2020-08-12 16:39 ` Petr Mladek [this message]
2020-08-13 0:24 ` POC: Alternative solution: " John Ogness
2020-08-13 5:18 ` Sergey Senozhatsky
2020-08-13 7:44 ` John Ogness
2020-08-13 8:41 ` Petr Mladek
2020-08-13 10:29 ` John Ogness
2020-08-13 11:30 ` Petr Mladek
2020-08-14 3:34 ` Sergey Senozhatsky
2020-08-14 8:16 ` John Ogness
2020-08-14 9:12 ` Petr Mladek
2020-08-13 11:54 ` Sergey Senozhatsky
2020-08-14 9:04 ` Petr Mladek
2020-08-14 22:46 ` Linus Torvalds
2020-08-14 23:52 ` Joe Perches
2020-08-15 2:33 ` Linus Torvalds
2020-08-15 3:08 ` Joe Perches
2020-08-15 9:25 ` David Laight
2020-08-15 5:41 ` Sergey Senozhatsky
2020-08-13 7:51 ` Petr Mladek
2020-08-13 7:31 ` Petr Mladek
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=20200812163908.GH12903@alley \
--to=pmladek@suse.com \
--cc=gregkh@linuxfoundation.org \
--cc=john.ogness@linutronix.de \
--cc=kexec@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=sergey.senozhatsky.work@gmail.com \
--cc=sergey.senozhatsky@gmail.com \
--cc=tglx@linutronix.de \
--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