[RFC][PATCH] Input: Add infrastrucutre for selecting clockid for event time stamps.

Subsystems: input (keyboard, mouse, joystick, touchscreen) drivers, the rest

4 messages, 4 authors, 2012-01-09 · open the first message on its own page

[RFC][PATCH] Input: Add infrastrucutre for selecting clockid for event time stamps.

From: John Stultz <hidden>
Date: 2012-01-07 03:41:22

Ok, hopefully getting close. Updated fixing the bool/int issue
Daniel pointed out. Let me know if you have any other thoughts!

thanks
-john

As noted by Arve and others since wall time can jump backwards, it
is difficult to use for input because one cannot determine if one
event occured before another or for how long a key was pressed.

However, the timestamp field is part of the kernel ABI, and cannot
be changed without possibly breaking existing users.

This patch adds a new IOCTL that allows a clockid to be set in
the evdev_client struct that will specify which time base to
use for event timestamps (ie: CLOCK_MONOTONIC instead
of CLOCK_REALTIME).

For now we only support CLOCK_MONOTONIC and CLOCK_REALTIME, but
in the future we could support other clockids if appropriate.

The default remains CLOCK_REALTIME, so we don't change the ABI.

CC: Dmitry Torokhov <dmitry.torokhov@gmail.com>
CC: Daniel Kurtz <redacted>
CC: linux-input@vger.kernel.org
CC: Arve Hj�nnev�g <arve@android.com>
CC: Brian Swetland <redacted>
CC: Colin Cross <redacted>
CC: Dima Zavin <redacted>
Signed-off-by: John Stultz <redacted>
---
 drivers/input/evdev.c |   33 +++++++++++++++++++++++++++++----
 include/linux/input.h |    2 ++
 2 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 4cf2534..edabd9e 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -46,6 +46,7 @@ struct evdev_client {
 	struct fasync_struct *fasync;
 	struct evdev *evdev;
 	struct list_head node;
+	int timestamp_clkid;
 	unsigned int bufsize;
 	struct input_event buffer[];
 };
@@ -54,8 +55,19 @@ static struct evdev *evdev_table[EVDEV_MINORS];
 static DEFINE_MUTEX(evdev_table_mutex);
 
 static void evdev_pass_event(struct evdev_client *client,
-			     struct input_event *event)
+			     struct input_event *event,
+			     ktime_t mono, ktime_t real)
 {
+	struct timespec ts;
+
+	if (client->timestamp_clkid == CLOCK_MONOTONIC)
+		ts = ktime_to_timespec(mono);
+	else
+		ts = ktime_to_timespec(real);
+	event->time.tv_sec = ts.tv_sec;
+	event->time.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
+
+
 	/* Interrupts are disabled, just acquire the lock. */
 	spin_lock(&client->buffer_lock);
 
@@ -94,8 +106,11 @@ static void evdev_event(struct input_handle *handle,
 	struct evdev *evdev = handle->private;
 	struct evdev_client *client;
 	struct input_event event;
+	ktime_t time_mono, time_real;
+
+	time_mono = ktime_get();
+	time_real = ktime_sub(time_mono, ktime_get_monotonic_offset());
 
-	do_gettimeofday(&event.time);
 	event.type = type;
 	event.code = code;
 	event.value = value;
@@ -103,11 +118,12 @@ static void evdev_event(struct input_handle *handle,
 	rcu_read_lock();
 
 	client = rcu_dereference(evdev->grab);
+
 	if (client)
-		evdev_pass_event(client, &event);
+		evdev_pass_event(client, &event, time_mono, time_real);
 	else
 		list_for_each_entry_rcu(client, &evdev->client_list, node)
-			evdev_pass_event(client, &event);
+			evdev_pass_event(client, &event, time_mono, time_real);
 
 	rcu_read_unlock();
 
@@ -683,6 +699,15 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
 		else
 			return evdev_ungrab(evdev, client);
 
+	case EVIOCCLOCKID:
+		if (copy_from_user(&i, p, sizeof(unsigned int)))
+			return -EFAULT;
+		if ((i == CLOCK_MONOTONIC) || (i == CLOCK_REALTIME)) {
+			client->timestamp_clkid = i;
+			return 0;
+		}
+		return -EINVAL;
+
 	case EVIOCGKEYCODE:
 		return evdev_handle_get_keycode(dev, p);
 
diff --git a/include/linux/input.h b/include/linux/input.h
index 3862e32..9618e14 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -129,6 +129,8 @@ struct input_keymap_entry {
 
 #define EVIOCGRAB		_IOW('E', 0x90, int)			/* Grab/Release device */
 
+#define EVIOCCLOCKID		_IOW('E', 0xA0, int)			/* Set clockid to be used for timestamps */
+
 /*
  * Device properties and quirks
  */
-- 
1.7.3.2.146.gca209

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Re: [RFC][PATCH] Input: Add infrastrucutre for selecting clockid for event time stamps.

From: Daniel Kurtz <hidden>
Date: 2012-01-07 06:42:56

On Sat, Jan 7, 2012 at 11:40 AM, John Stultz [off-list ref] wrote:
quoted hunk
Ok, hopefully getting close. Updated fixing the bool/int issue
Daniel pointed out. Let me know if you have any other thoughts!

thanks
-john

As noted by Arve and others since wall time can jump backwards, it
is difficult to use for input because one cannot determine if one
event occured before another or for how long a key was pressed.

However, the timestamp field is part of the kernel ABI, and cannot
be changed without possibly breaking existing users.

This patch adds a new IOCTL that allows a clockid to be set in
the evdev_client struct that will specify which time base to
use for event timestamps (ie: CLOCK_MONOTONIC instead
of CLOCK_REALTIME).

For now we only support CLOCK_MONOTONIC and CLOCK_REALTIME, but
in the future we could support other clockids if appropriate.

The default remains CLOCK_REALTIME, so we don't change the ABI.

CC: Dmitry Torokhov <dmitry.torokhov@gmail.com>
CC: Daniel Kurtz <redacted>
CC: linux-input@vger.kernel.org
CC: Arve Hjønnevåg <arve@android.com>
CC: Brian Swetland <redacted>
CC: Colin Cross <redacted>
CC: Dima Zavin <redacted>
Signed-off-by: John Stultz <redacted>
---
 drivers/input/evdev.c |   33 +++++++++++++++++++++++++++++----
 include/linux/input.h |    2 ++
 2 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 4cf2534..edabd9e 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -46,6 +46,7 @@ struct evdev_client {
       struct fasync_struct *fasync;
       struct evdev *evdev;
       struct list_head node;
+       int timestamp_clkid;
       unsigned int bufsize;
       struct input_event buffer[];
 };
@@ -54,8 +55,19 @@ static struct evdev *evdev_table[EVDEV_MINORS];
 static DEFINE_MUTEX(evdev_table_mutex);

 static void evdev_pass_event(struct evdev_client *client,
-                            struct input_event *event)
+                            struct input_event *event,
+                            ktime_t mono, ktime_t real)
 {
+       struct timespec ts;
+
+       if (client->timestamp_clkid == CLOCK_MONOTONIC)
+               ts = ktime_to_timespec(mono);
+       else
+               ts = ktime_to_timespec(real);
+       event->time.tv_sec = ts.tv_sec;
+       event->time.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
Maybe just:

 event->time = (client->timestamp_clkid == CLOCK_MONOTONIC) ?
                      ktime_to_timeval(mono) : ktime_to_timeval(real);

Either way, lgtm...

Reviewed-by: Daniel Kurtz <redacted>
quoted hunk
+
+
       /* Interrupts are disabled, just acquire the lock. */
       spin_lock(&client->buffer_lock);
@@ -94,8 +106,11 @@ static void evdev_event(struct input_handle *handle,
       struct evdev *evdev = handle->private;
       struct evdev_client *client;
       struct input_event event;
+       ktime_t time_mono, time_real;
+
+       time_mono = ktime_get();
+       time_real = ktime_sub(time_mono, ktime_get_monotonic_offset());

-       do_gettimeofday(&event.time);
       event.type = type;
       event.code = code;
       event.value = value;
@@ -103,11 +118,12 @@ static void evdev_event(struct input_handle *handle,
       rcu_read_lock();

       client = rcu_dereference(evdev->grab);
+
       if (client)
-               evdev_pass_event(client, &event);
+               evdev_pass_event(client, &event, time_mono, time_real);
       else
               list_for_each_entry_rcu(client, &evdev->client_list, node)
-                       evdev_pass_event(client, &event);
+                       evdev_pass_event(client, &event, time_mono, time_real);

       rcu_read_unlock();
@@ -683,6 +699,15 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
               else
                       return evdev_ungrab(evdev, client);

+       case EVIOCCLOCKID:
+               if (copy_from_user(&i, p, sizeof(unsigned int)))
+                       return -EFAULT;
+               if ((i == CLOCK_MONOTONIC) || (i == CLOCK_REALTIME)) {
+                       client->timestamp_clkid = i;
+                       return 0;
+               }
+               return -EINVAL;
+
       case EVIOCGKEYCODE:
               return evdev_handle_get_keycode(dev, p);
diff --git a/include/linux/input.h b/include/linux/input.h
index 3862e32..9618e14 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -129,6 +129,8 @@ struct input_keymap_entry {
 #define EVIOCGRAB              _IOW('E', 0x90, int)                    /* Grab/Release device */

+#define EVIOCCLOCKID           _IOW('E', 0xA0, int)                    /* Set clockid to be used for timestamps */
+
 /*
 * Device properties and quirks
 */
--
1.7.3.2.146.gca209

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Re: [RFC][PATCH] Input: Add infrastrucutre for selecting clockid for event time stamps.

From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Date: 2012-01-09 18:04:28

On Sat, Jan 07, 2012 at 02:42:32PM +0800, Daniel Kurtz wrote:
On Sat, Jan 7, 2012 at 11:40 AM, John Stultz [off-list ref] wrote:
quoted
 static void evdev_pass_event(struct evdev_client *client,
-                            struct input_event *event)
+                            struct input_event *event,
+                            ktime_t mono, ktime_t real)
 {
+       struct timespec ts;
+
+       if (client->timestamp_clkid == CLOCK_MONOTONIC)
+               ts = ktime_to_timespec(mono);
+       else
+               ts = ktime_to_timespec(real);
+       event->time.tv_sec = ts.tv_sec;
+       event->time.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
Maybe just:

 event->time = (client->timestamp_clkid == CLOCK_MONOTONIC) ?
                      ktime_to_timeval(mono) : ktime_to_timeval(real);

Either way, lgtm...

Reviewed-by: Daniel Kurtz <redacted>
I'm OK with the patch but do we actually have a buy-in from
Android/Chrome folks for this? If they will actually use it I'll apply
it, otherwise I'll sit on it.

Thanks.

-- 
Dmitry
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Re: [RFC][PATCH] Input: Add infrastrucutre for selecting clockid for event time stamps.

From: Arve Hjønnevåg <arve@android.com>
Date: 2012-01-09 22:49:11

On Mon, Jan 9, 2012 at 10:04 AM, Dmitry Torokhov
[off-list ref] wrote:
On Sat, Jan 07, 2012 at 02:42:32PM +0800, Daniel Kurtz wrote:
quoted
On Sat, Jan 7, 2012 at 11:40 AM, John Stultz [off-list ref] wrote:
quoted
 static void evdev_pass_event(struct evdev_client *client,
-                            struct input_event *event)
+                            struct input_event *event,
+                            ktime_t mono, ktime_t real)
 {
+       struct timespec ts;
+
+       if (client->timestamp_clkid == CLOCK_MONOTONIC)
+               ts = ktime_to_timespec(mono);
+       else
+               ts = ktime_to_timespec(real);
+       event->time.tv_sec = ts.tv_sec;
+       event->time.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
Maybe just:

 event->time = (client->timestamp_clkid == CLOCK_MONOTONIC) ?
                      ktime_to_timeval(mono) : ktime_to_timeval(real);

Either way, lgtm...

Reviewed-by: Daniel Kurtz <redacted>
I'm OK with the patch but do we actually have a buy-in from
Android/Chrome folks for this? If they will actually use it I'll apply
it, otherwise I'll sit on it.
Yes, this seems reasonable to me.

-- 
Arve Hjønnevåg
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help