All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
To: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Cc: Anshul Garg <anshul.g@samsung.com>,
	Peter Hutterer <peter.hutterer@redhat.com>,
	linux-input@vger.kernel.org
Subject: Re: Regression in dtor/input.git/next - flush pending events on clock type change
Date: Thu, 5 Feb 2015 15:58:16 -0800	[thread overview]
Message-ID: <20150205235816.GA21288@dtor-ws> (raw)
In-Reply-To: <20150205230629.GC21618@mail.corp.redhat.com>

Hi Benjamin,

On Thu, Feb 05, 2015 at 06:06:29PM -0500, Benjamin Tissoires wrote:
> Hi Anshul,
> 
> The commit 0c3e99437a66e4c869c60c2398449e6d98f3a988 in dtor/input.git/next
> tree introduce an interesting regression in libinput. The tests fail :)
> 
> Actually, evemu-record and libinput switch the clock to monotonic when
> opening an input node, and the first thing that gets queued is a
> SYN_DROPPED event.
> 
> However, in the libinput test suite, events are the bare minimum, and
> most of the tests contain only one event set (one EV_SYN).
> When seeing the SYN_DROPPED, the clients are supposed to drain the events
> until the next EV_SYN, and so they are losing the events that came long
> after the ioctl call.
> And in the end, the test suite does not receive any events.
> 
> Removing the evdev_queue_syn_dropped() call in the ioctl handling fixes
> the test suite, and Peter suggested that maybe we should queue a
> SYN_DROPPED event iff there are events in the queue.

Does the following patch fixe it? But I would like to see libinput
tests more robust.

Thanks.

-- 
Dmitry

Input: evdev - do not queue SYN_DROPPED if queue is empty

From: Dmitry Torokhov <dmitry.torokhov@gmail.com>

Reported-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/evdev.c |   34 +++++++++++++++++++++++-----------
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index e7cee38..f2a494a 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -108,10 +108,8 @@ static void __evdev_flush_queue(struct evdev_client *client, unsigned int type)
 	client->head = head;
 }
 
-/* queue SYN_DROPPED event and flush queue if flush parameter is true */
-static void evdev_queue_syn_dropped(struct evdev_client *client, bool flush)
+static void __evdev_queue_syn_dropped(struct evdev_client *client)
 {
-	unsigned long flags;
 	struct input_event ev;
 	ktime_t time;
 
@@ -126,11 +124,6 @@ static void evdev_queue_syn_dropped(struct evdev_client *client, bool flush)
 	ev.code = SYN_DROPPED;
 	ev.value = 0;
 
-	spin_lock_irqsave(&client->buffer_lock, flags);
-
-	if (flush)
-		client->packet_head = client->head = client->tail;
-
 	client->buffer[client->head++] = ev;
 	client->head &= client->bufsize - 1;
 
@@ -139,12 +132,21 @@ static void evdev_queue_syn_dropped(struct evdev_client *client, bool flush)
 		client->tail = (client->head - 1) & (client->bufsize - 1);
 		client->packet_head = client->tail;
 	}
+}
+
+static void evdev_queue_syn_dropped(struct evdev_client *client)
+{
+	unsigned long flags;
 
+	spin_lock_irqsave(&client->buffer_lock, flags);
+	__evdev_queue_syn_dropped(client);
 	spin_unlock_irqrestore(&client->buffer_lock, flags);
 }
 
 static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid)
 {
+	unsigned long flags;
+
 	if (client->clk_type == clkid)
 		return 0;
 
@@ -163,8 +165,18 @@ static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid)
 		return -EINVAL;
 	}
 
-	/* Flush pending events and queue SYN_DROPPED event.*/
-	evdev_queue_syn_dropped(client, true);
+	/*
+	 * Flush pending events and queue SYN_DROPPED event,
+	 * but only if queue is not empty.
+	 */
+	spin_lock_irqsave(&client->buffer_lock, flags);
+
+	if (client->head != client->tail) {
+		client->packet_head = client->head = client->tail;
+		__evdev_queue_syn_dropped(client);
+	}
+
+	spin_unlock_irqrestore(&client->buffer_lock, flags);
 
 	return 0;
 }
@@ -803,7 +815,7 @@ static int evdev_handle_get_val(struct evdev_client *client,
 
 	ret = bits_to_user(mem, maxbit, maxlen, p, compat);
 	if (ret < 0)
-		evdev_queue_syn_dropped(client, false);
+		evdev_queue_syn_dropped(client);
 
 	kfree(mem);
 

  reply	other threads:[~2015-02-05 23:58 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-05 23:06 Regression in dtor/input.git/next - flush pending events on clock type change Benjamin Tissoires
2015-02-05 23:58 ` Dmitry Torokhov [this message]
     [not found]   ` <CAN+gG=HG+f66TosBowTWKnh-sMqVobEx18DK0AoPX_7OCfBDsg@mail.gmail.com>
2015-02-06  1:53     ` Dmitry Torokhov
2015-02-06  2:14     ` Benjamin Tissoires

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=20150205235816.GA21288@dtor-ws \
    --to=dmitry.torokhov@gmail.com \
    --cc=anshul.g@samsung.com \
    --cc=benjamin.tissoires@redhat.com \
    --cc=linux-input@vger.kernel.org \
    --cc=peter.hutterer@redhat.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.