From: Oleg Nesterov <oleg@redhat.com>
To: Henrik Rydberg <rydberg@bitmath.org>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>,
linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
Jiri Kosina <jkosina@suse.cz>,
Mika Kuoppala <mika.kuoppala@nokia.com>,
Benjamin Tissoires <tissoire@cena.fr>,
Rafi Rubin <rafi@seas.upenn.edu>
Subject: Re: [PATCH 1/4] input: Introduce buflock, a one-to-many circular buffer mechanism
Date: Fri, 4 Jun 2010 21:13:08 +0200 [thread overview]
Message-ID: <20100604191308.GA10942@redhat.com> (raw)
In-Reply-To: <4C08BCB5.7020201@bitmath.org>
On 06/04, Henrik Rydberg wrote:
>
> additional eyes would be very helpful
I am puzzled. I don't understand what this patch does at all ;)
Could you please provide a simple example or answer my questions?
> >> + * During normal operation, with adequate buffer size, this method will not
> >> + * block, regardless of the number of concurrent readers.
I don't understand this "regardless of the number of concurrent" comment.
buflock_read(br) modifies br.tail, it can't be used lockless.
Or, do you mean that every reader should use its own buflock_reader?
If yes. Afaics, we have one buflock_writer, and one buf "connected"
to this buflock_writer. In that case I don't understand why this
buf doesn't live in "struct buflock_writer", it can be char[].
This way both read/write macros do not need buf and size args.
typeof(item) could be used for read/write into this buf.
But still I can't understand how this all works.
> >> +#define buflock_read(br, bw, buf, size, item) \
> >> + do { \
> >> + unsigned int _h, _nh; \
> >> + do { \
> >> + _h = bw.head; \
> >> + smp_rmb(); \
> >> + item = buf[br.tail]; \
> >> + smp_rmb(); \
> >> + _nh = bw.next_head; \
> >> + smp_rmb(); \
> >> + } while (unlikely(br.tail - _h < _nh - _h)); \
> >> + br.tail = (br.tail + 1) & ((size) - 1); \
> >> + } while (0)
How can the reader know there is something new/valid in buf it
can read?
I guess it should call buflock_sync_reader() at least once, to
"attach" to the writer/buf, and then check buflock_reader_empty() ?
But. If the reader calls buflock_read() constantly, sooner or
later buflock_reader_empty() becomes T again.
Probably the reader should call buflock_sync_reader() + check
buflock_reader_empty() == F every time before buflock_read() ?
In this case I do not understand why do we have 2 separate
helpers, and why do we need buflock_reader->head.
Perhaps it is writer who calls buflock_sync_reader() and tells
the reader it has the new data? In this case I do not understand
the "feeding many readers" part.
And in any case I do not understand which guarantees this API
provides.
Whatever we do, buflock_read() can race with the writer and read
the invalid item.
Suppose that buflock_read(br, item) gets the preemption "inside" of
item = buf[br.tail] asignment.
The writer calls buflock_write() SIZE times.
The reader resumes, continues its memcpy() operation, and suceeds.
But the "item" it returns is not consistent, it is neither the old
value nor the new.
No?
Oleg.
next prev parent reply other threads:[~2010-06-04 19:15 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-03 8:00 [PATCH 0/4] input: evdev: Dynamic buffers (rev3) Henrik Rydberg
2010-06-03 8:00 ` [PATCH 1/4] input: Introduce buflock, a one-to-many circular buffer mechanism Henrik Rydberg
2010-06-03 8:01 ` [PATCH 2/4] input: evdev: Use multi-reader buffer to save space (rev3) Henrik Rydberg
2010-06-03 8:01 ` [PATCH 3/4] input: evdev: Convert to dynamic event buffer (rev3) Henrik Rydberg
2010-06-03 8:01 ` [PATCH 4/4] input: Use driver hint to compute the evdev buffer size Henrik Rydberg
2010-06-04 6:34 ` Dmitry Torokhov
2010-06-04 6:37 ` [PATCH 3/4] input: evdev: Convert to dynamic event buffer (rev3) Dmitry Torokhov
2010-06-04 6:56 ` [PATCH 1/4] input: Introduce buflock, a one-to-many circular buffer mechanism Dmitry Torokhov
2010-06-04 8:43 ` Henrik Rydberg
2010-06-04 16:36 ` Dmitry Torokhov
2010-06-04 17:08 ` Jonathan Cameron
2010-06-04 19:13 ` Oleg Nesterov [this message]
2010-06-04 19:43 ` Henrik Rydberg
2010-06-05 17:40 ` Oleg Nesterov
2010-06-05 18:34 ` Henrik Rydberg
2010-06-04 16:36 ` Henrik Rydberg
2010-06-05 1:35 ` Andrew Morton
2010-06-05 11:21 ` Henrik Rydberg
2010-06-04 6:59 ` [PATCH 0/4] input: evdev: Dynamic buffers (rev3) Dmitry Torokhov
2010-06-04 16:11 ` Henrik Rydberg
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=20100604191308.GA10942@redhat.com \
--to=oleg@redhat.com \
--cc=dmitry.torokhov@gmail.com \
--cc=jkosina@suse.cz \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mika.kuoppala@nokia.com \
--cc=rafi@seas.upenn.edu \
--cc=rydberg@bitmath.org \
--cc=tissoire@cena.fr \
/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).