From patchwork Thu Jan 21 17:37:19 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aniroop Mathur X-Patchwork-Id: 8083641 Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 769A8BEEE5 for ; Thu, 21 Jan 2016 17:35:14 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 44ABA2034A for ; Thu, 21 Jan 2016 17:35:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6C20A2022A for ; Thu, 21 Jan 2016 17:35:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965568AbcAURfK (ORCPT ); Thu, 21 Jan 2016 12:35:10 -0500 Received: from mail-pf0-f177.google.com ([209.85.192.177]:35838 "EHLO mail-pf0-f177.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965369AbcAURfJ (ORCPT ); Thu, 21 Jan 2016 12:35:09 -0500 Received: by mail-pf0-f177.google.com with SMTP id 65so26794455pff.2; Thu, 21 Jan 2016 09:35:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id; bh=7VSrEGujviVRyZZ3jVv3IO0Nk5pPQbt19THpdNvInVU=; b=z9FRnCgdyoSUryKHpjQ5I0m/yEZEUPeSw6Ji1hJkDUy819f4B7Q5/4dEz5Ty7XRcbj WxdFputW4oyHvzx+EyRki4Q0CcWAzPmQ2SM/9RdQA8we19IXLAMTkw46pvGdTAIvsuE7 X/nWEH6kld4qr9QV9G2SrM2n2QtI9COBdVzGjqA7ThcnYISoFS98EQtpomCLA+HpiFi/ 3aRe3fUqdRiyEHmtkXiIjV4eUuw3rU4kX0hgdAs+SPZEuT3xA4w2QDscOe6Xk8VdcYbb QLFFY+XW/YkhDefuKx1Xwik4dt3rPTkAIbYppQC55qbguXMGcecIPIn6y96xO9Lvn3U5 dvFQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id; bh=7VSrEGujviVRyZZ3jVv3IO0Nk5pPQbt19THpdNvInVU=; b=Q2AQ+C5GEpgVwugH36Hla7iW/RgObhjVVS/q9X5rlIY7HCWbO1MzYzkNuq9wpnR5Cf HMGKj+ILz11TfiOpL2jM6zGBJrBGic1IGeNt6Nt/ZPWVXHYp1yMGiASepNQ6J9KQj/ad L8p2TMUDqZ2S6LpfA7Sns6MwP3F1o0cIucLvVHmQ8aV53mNbGOtbsirdgO73yInZst92 V7N/gtGuGELz2Z0j5/KTiCrrtbxJLwRNkrmgvRGcskDZNqLLvToHSOecTv3YM6ZMwAOv rV4kihKERkNw/2rrksnVqSmGpZeaA63N31t+cgXd31YjmvVfe340Z2CuVu3HdA3FokCO mE7g== X-Gm-Message-State: ALoCoQne10IUaPU+qkK64YVJE48mCHq/wXfQOCeVnDuXAXO8m6xOuGobNY2zZCsKLUvwezjFgFVa0JvZc7pR8SRn4r5sSExSYg== X-Received: by 10.98.89.78 with SMTP id n75mr61719621pfb.120.1453397708358; Thu, 21 Jan 2016 09:35:08 -0800 (PST) Received: from Aniroops-MacBook-Pro.local.name ([203.122.1.49]) by smtp.gmail.com with ESMTPSA id u69sm3982350pfa.61.2016.01.21.09.35.05 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 21 Jan 2016 09:35:07 -0800 (PST) From: Aniroop Mathur To: dmitry.torokhov@gmail.com Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, aniroop.mathur@gmail.com, Aniroop Mathur Subject: [PATCH] [v8]Input: evdev: fix bug of dropping valid packet after syn_dropped event Date: Thu, 21 Jan 2016 23:07:19 +0530 Message-Id: <1453397839-942-1-git-send-email-a.mathur@samsung.com> X-Mailer: git-send-email 2.6.2 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP If last event dropped in the old queue was EVi_SYN/SYN_REPORT, then lets generate EV_SYN/SYN_REPORT immediately after queing EV_SYN/SYN_DROPPED so that clients would not ignore next valid full packet events. Signed-off-by: Aniroop Mathur --- drivers/input/evdev.c | 46 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index e9ae3d5..821b68a 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -156,7 +156,12 @@ static void __evdev_flush_queue(struct evdev_client *client, unsigned int type) static void __evdev_queue_syn_dropped(struct evdev_client *client) { struct input_event ev; + struct input_event *last_ev; ktime_t time; + unsigned int mask = client->bufsize - 1; + + /* capture last event stored in the buffer */ + last_ev = &client->buffer[(client->head - 1) & mask]; time = client->clk_type == EV_CLK_REAL ? ktime_get_real() : @@ -170,13 +175,28 @@ static void __evdev_queue_syn_dropped(struct evdev_client *client) ev.value = 0; client->buffer[client->head++] = ev; - client->head &= client->bufsize - 1; + client->head &= mask; if (unlikely(client->head == client->tail)) { /* drop queue but keep our SYN_DROPPED event */ - client->tail = (client->head - 1) & (client->bufsize - 1); + client->tail = (client->head - 1) & mask; client->packet_head = client->tail; } + + /* + * If last packet was completely stored, then queue SYN_REPORT + * so that clients would not ignore next valid full packet + */ + if (last_ev->type == EV_SYN && last_ev->code == SYN_REPORT) { + last_ev->time = ev.time; + client->buffer[client->head++] = *last_ev; + client->head &= mask; + client->packet_head = client->head; + + /* drop queue but keep our SYN_DROPPED & SYN_REPORT event */ + if (unlikely(client->head == client->tail)) + client->tail = (client->head - 2) & mask; + } } static void evdev_queue_syn_dropped(struct evdev_client *client) @@ -218,7 +238,7 @@ static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid) spin_lock_irqsave(&client->buffer_lock, flags); if (client->head != client->tail) { - client->packet_head = client->head = client->tail; + client->packet_head = client->tail = client->head; __evdev_queue_syn_dropped(client); } @@ -231,22 +251,24 @@ static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid) static void __pass_event(struct evdev_client *client, const struct input_event *event) { + unsigned int mask = client->bufsize - 1; + client->buffer[client->head++] = *event; - client->head &= client->bufsize - 1; + client->head &= mask; if (unlikely(client->head == client->tail)) { /* * This effectively "drops" all unconsumed events, leaving - * EV_SYN/SYN_DROPPED plus the newest event in the queue. + * EV_SYN/SYN_DROPPED, EV_SYN/SYN_REPORT (if required) and + * newest event in the queue. */ - client->tail = (client->head - 2) & (client->bufsize - 1); + client->head = (client->head - 1) & mask; + client->packet_head = client->tail = client->head; + __evdev_queue_syn_dropped(client); - client->buffer[client->tail].time = event->time; - client->buffer[client->tail].type = EV_SYN; - client->buffer[client->tail].code = SYN_DROPPED; - client->buffer[client->tail].value = 0; - - client->packet_head = client->tail; + client->buffer[client->head++] = *event; + client->head &= mask; + /* No need to check for buffer overflow as it just occurred */ } if (event->type == EV_SYN && event->code == SYN_REPORT) {