lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <41840b750607301137t1e10fe88o3a1c73e7a4b4bf44@mail.gmail.com>
Date:	Sun, 30 Jul 2006 21:37:23 +0300
From:	"Shem Multinymous" <multinymous@...il.com>
To:	"Vojtech Pavlik" <vojtech@...e.cz>
Cc:	"Brown, Len" <len.brown@...el.com>, "Pavel Machek" <pavel@...e.cz>,
	"Matthew Garrett" <mjg59@...f.ucam.org>,
	"kernel list" <linux-kernel@...r.kernel.org>,
	linux-thinkpad@...ux-thinkpad.org, linux-acpi@...r.kernel.org,
	"Henrique de Moraes Holschuh" <hmh@...ian.org>,
	"Mark Underwood" <basicmark@...oo.com>, "Greg KH" <greg@...ah.com>,
	"Jean Delvare" <khali@...ux-fr.org>
Subject: Re: Generic battery interface

Hi all,

Here's an updated rough proto-spec for the userspace side of the
continuous-parameter polling interface, intended for hwmon, batteries
and their ilk, and maybe even the input infrastructure.

Compared to the parent post, this version adds a second parameter to
the ioctl (see discussion elsewhere in this thread), and corrects a
few inaccuracies.

With an event-based data source, this interface allows polling with no
time interrupts on tickless kernels. With a polling-based data source
and a bit of luck, the frequency of polling = frequency of induced
timer interrupts will be the minimum that satisfies the greediest
client (even if there are many). In general, complicated data sources
can be handled optimally by custom driver+infrastructure code. All of
this is completely transparent  to userspace, which just states its
needs and has its every desire fulfilled.

Hardware readouts are obtained from a dedicated file - a sysfs
attribute (as in hwmon and tp_smapi) or a device file (as in the input
infrastructure). The file has the following properties:

1. A new ioctl DELAYED_UPDATE, with parameters min_wait and
   min_fresh, meaning: "I want an a fresh readout. If I poll() this FD
   with POLLIN then send an input-ready event at time is T+min_wait, or
   when you have a readout that was received from the hardware at  time
   T+min_fresh, whichever is *later*. Likewise if I select()".
   Here T is the time of the ioctl call and min_wait>=min_fresh.
2. When the file is opened in O_NONBLOCKing mode, read() always return
   the latest cached readout rather than querying the hardware
   (unless the latter has negligible cost).
3. When the file is opened in normal (blocking) mode, read() blocks
   until a fresh readout is available and returns this readout; see
   below.

To illustrate, here's an example of a proper polling loop (sans error
checking). This app wants to refresh its display when the data has
changed, but not more often than once per second. It wants the
readouts to be reasonly spaced: they should be obtained at least 700ms
apart. And it needs to update its GUI every 3 seconds regardless of
readouts.

In some linux/foo.h:
--------------------------
struct delayed_update_req {
	int min_wait;
	int min_fresh;
};
--------------------------

Application code:
--------------------------
/* Open attribute file with O_NONBLOCK so that all reads will
* return cached values instead of blocking:
*/
int fd = open("/whatever/voltage", O_NONBLOCK|O_RDONLY);

/* Read and process latest cached attribute value: */
read(fd, ...);
...

while (1) {
	const struct delayed_update_req dureq =
		{ .min_wait=1000, min_fresh=700 };
	struct pollfd ufds = { .fd=fd, events=POLLIN };

	/* Tell the driver we want a fresh readout, but no sooner than
	 * 1sec from now, and we want the readout to reflect reality no
	 * sooner than 700ms now:
	 */
	ioctl(fd, DELAYED_UPDATE, &dureq);

	/* Wait for an update for at most 3 seconds. Nominally this will
	* block for at least 1 second, because of the above ioct. If we
	* were reading multiple attributes, we could poll them all
	* simultaneously.
	*/
	poll(&ufds, 1, 3000);

	/* Read latest cached attribute value: */
	read(fd, ...);

	... handle readout, update GUI ...
}
--------------------------

Legacy and lightweight applications (e.g., cat from shell) will open
the file in blocking mode. In this case, a "read(fd, ...)" has
semantics equivalent to the following O_NONBLOCK-mode code:

--------------------------
	const struct delayed_update_req dureq =
		{ .min_wait=0, min_fresh=0 };

	/* Tell driver we want an immediate update: */
	ioctl(fd, DELAYED_UPDATE, &dureq);

	/* Wait indefinitely for an update: */
	poll(&ufds, 1, -1);

	/* Read the latest cached attribute value: */
	read(fd, ...);
--------------------------

Similarly, select() and poll() on non-blocking files acts like you did
"ioctl(fd, DELAYED_UPDATE, &dureq)" with dureq={0,0} and then waited
for a refresh or timeout.

If we want to penalize code which doesn't use nonblocking mode and
delayed updates, we can increase the implicit dureq.min_wait above
from 0 to a sufficiently nasty (driver-dependent?) delay.


Comments?

(I still can't implement this myself. Just trying to elucidate my suggestion.)

  Shem
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ