Re: Synchronizing evdev readers and drivers?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Dec 03, 2010 at 11:36:50AM -0600, Bill Gatliff wrote:

I guess my main thing here is that I don't see why we'd want to present
applications with an interface which means we can't make use of hardware
scheduling facilities where they exist.  The other thing is that this
feels like a workaround for applications that are already doing
application layer scheduling rather than anything else and that feels
more like a workaround for a lack of control provided by the kernel than
anything else.

> The poll() and blocking read() system calls allow an application to
> tell an input device that it is prepared to receive an event, and for
> an input device driver to tell userspace when an event has occurred.
> As implemented in evdev, however, neither system call provides a
> natural, consistent way for userspace to tell an input device driver
> how often it wants data--- or even if it wants any (at the moment) at
> all.

This is what I'm saying the sysfs interface polldev provides (or a
similar interface done via ioctl() or whatever) should do.

> I think that you and I talking about two different scenarios.  You
> seem to be focused on the one where userspace is informed when an
> input event occurs, but has no ability to request or schedule those

No, not at all.  What I'm saying is that userspace should be able to
express to the kernel that it wants events delivering at a given rate
and the kernel should then attempt to deliver events at that rate.

> events.  That model makes perfect sense for USB mice and keyboards
> where the hardware itself is inherently event-driven.  For those kinds
> of devices, users don't know or care when a key will be pressed---
> they just need to respond when one is.  So they simply block in a
> poll() or read() until a keypress shows up.  Problem solved.

This is also true for things like touchscreens which work by
continuously delivering samples (ideally only while there is a touch) at
intervals which currently can't be configured in the application layer -
they're also polling, and they may not even be doing so in hardware.

> I'm looking at input devices like accelerometers and compasses, which
> must be explicitly sampled and can send events at upwards of 4K/sec if
> you ask them to.  The vast majority of user applications don't need

Right, and what I'm saying is that userspace should just say what rate
it wants and then get that.

> data anywhere near that fast, but the range of desirable rates can't
> be met by a simple "just sample it at 100 Hz" kernel thread because of
> other modes want the data at 200 Hz with minimal latency.  The current

Resolving the rate needs of multiple simultaneous users sounds like a
tractable bit of programming which we'd only ever need to do once in the
input layer, surely?

> architecture requires me to implement that range using a dedicated
> kernel thread, plus a sysfs attribute/ioctl to dial the rate up or
> down from userspace.

No need for the kernel thread - timers should do the trick - but other
than that I see no problem with this at all, other than the fact that we
probably want to implement a standard API for setting the rate which can
be used across devices.  Worst case a fully software implementation is
pretty much equivalent to what you want to do but is very simple to use
in the application layer.  Best case the hardware is able to clock out
the samples by itself and we get to skip the bit where software
initiates the transfer which saves us work and is especially nice at
higher data rates.

For a devices like touchscreens driving the reads from the application
would typically be a 50-100% overhead on the I/O costs and involves
blocking the application while the conversion happens, neither of which
seems desirable.

> I don't want to do an ad-hoc method for communicating a polling rate
> request to the hardware for each hardware driver that I have to deal
> with.  One way to avoid this is to add a standard sysfs attribute or

I wasn't suggesting that at all.  Like you say, define a standard one
and/or use the interface we already have in polldev which looks general
enough for a lot of cases though it's pretty much root only.

> The other option, which is the one I'm proposing and which seems more
> natural for end users, is to add an optional read callback in the
> input_dev structure that, if implemented by the driver, will call the
> driver back whenever someone is asking for the state of the input
> device.  Drivers can then choose to initiate a sampling operation only
> when a user is asking for the data.  Users just call poll() or read()
> at the rate they want the sampling to occur, and never get blocked for
> longer than it takes to acquire a sample.

This seems painful for applications, it means they need to deal with
their own data scheduling and means we have to take the hit of
explicitly polling the device even when it is capable of pushing the
data at us.  If we triggered the callback on poll() they'd also have
issues blocking on other file descriptors simultaneously.

> Finally, with the read callback approach there isn't any behavioral
> change in the evdev interface at all for existing drivers (and
> existing drivers will continue to work as they do now).  When drivers
> start implementing the read callback, users will just notice that
> their drivers are simpler and their data is more recent--- if they
> care to investigate either of those.

Assuming the applications are behaving as you describe and not blocking
waiting for data - I'd expect that if they block waiting for data they'd
also end up seeing data delievered much faster.

I don't see any meaningful difference in the timeliness of data
delivery with the two approaches - no matter who's clocking the poll the
application will get the data at pretty much the same time after the
sample, the difference would be for applications that current schedule
their own reads.  For drivers that don't or can't have the hardware push
samples out I'd expect librification would mean that there'd be little
impact on driver code, obviously if the hardware was helping the
complexity would depend on how helpful the hardware is.

> What I'm proposing is something that is very similar to input-polldev,
> except that users don't even have to specify the polling rate: they
> just call read() or poll() at the rate they want the input device
> hardware to scan/sample itself.  Some current users of input-polldev
> might be better served by a read callback, in fact.

Perhaps I'm missing something here but my experience has always been
that having to worry about time periods adds rather than removes
complexity in applications; the raw POSIX APIs aren't especially
convenient here.  Obviously higher level libraries will often provide
timer facilities which make these useful (I've written such things
myself) but it's still going to be more work for the system than if the
hardware can push data out for us.

> The read callback approach is completely wrong for USB-ish keyboards
> and mice, so those drivers won't implement a read callback.  But for
> accelerometers, pushbuttons and such, a read callback seems like a
> very useful tool.  I hope to have first-hand evidence of that later
> today, preferably in a way that will be useful to the broader
> community as well.  :)

Pushbuttons seem like they'd want to be event driven, surely?
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux