From patchwork Thu Apr 14 14:25:12 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 610476 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3qm2yy3VMlz9sBl for ; Fri, 15 Apr 2016 00:26:02 +1000 (AEST) Received: from localhost ([::1]:40174 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aqiDY-0000MR-Ik for incoming@patchwork.ozlabs.org; Thu, 14 Apr 2016 10:26:00 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39117) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aqiCx-0007WL-Vd for qemu-devel@nongnu.org; Thu, 14 Apr 2016 10:25:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aqiCs-0006aA-Qu for qemu-devel@nongnu.org; Thu, 14 Apr 2016 10:25:23 -0400 Received: from mx2.suse.de ([195.135.220.15]:46649) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aqiCs-0006Xm-9H for qemu-devel@nongnu.org; Thu, 14 Apr 2016 10:25:18 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 305FBAC16; Thu, 14 Apr 2016 14:25:11 +0000 (UTC) From: Alexander Graf To: qemu-devel@nongnu.org Date: Thu, 14 Apr 2016 16:25:12 +0200 Message-Id: <1460643912-244245-1-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.8.5.6 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] X-Received-From: 195.135.220.15 Subject: [Qemu-devel] [PATCH] hid: Extend the event queue size to 1024 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Dirk Mueller , Dinar Valeev , Gerd Hoffmann , Juan Quintela Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" We can currently buffer up to 16 events in our event queue for input devices. While it sounds like 16 events backlog for everyone should be enough, our automated testing tools (OpenQA) manage to easily type faster than our guests can handle. So we run into queue overflows and start to drop input characters. By typing quickly, I was even able to reproduce this manually in a vnc session on SLOF. Fix this by increasing the queue buffer. With 1k events I'm sure we can get by for the foreseeable future. To maintain backwards compatibility on live migration, put the extra queue items into separate subsections. Reported-by: Dinar Valeev Signed-off-by: Alexander Graf --- hw/input/hid.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- include/hw/input/hid.h | 4 ++-- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/hw/input/hid.c b/hw/input/hid.c index d92c746..56119a3 100644 --- a/hw/input/hid.c +++ b/hw/input/hid.c @@ -569,6 +569,16 @@ static int hid_post_load(void *opaque, int version_id) return 0; } +static bool hid_extra_queue_needed(void *opaque) +{ + /* + * The queue is a ring, so chances are really good that we need to + * submit entries beyond entry 16 anyway. Let's just always send + * them, that way we have less chance of missing events by accident. + */ + return true; +} + static const VMStateDescription vmstate_hid_ptr_queue = { .name = "HIDPointerEventQueue", .version_id = 1, @@ -582,19 +592,47 @@ static const VMStateDescription vmstate_hid_ptr_queue = { } }; +static const VMStateDescription vmstate_hid_ptr_extra_queue = { + .name = "hid_ptr_extra_queue", + .version_id = 1, + .minimum_version_id = 1, + .needed = hid_extra_queue_needed, + .fields = (VMStateField[]) { + VMSTATE_STRUCT_SUB_ARRAY(ptr.queue, HIDState, 16, QUEUE_LENGTH - 16, 0, + vmstate_hid_ptr_queue, HIDPointerEvent), + VMSTATE_END_OF_LIST() + } +}; + const VMStateDescription vmstate_hid_ptr_device = { .name = "HIDPointerDevice", .version_id = 1, .minimum_version_id = 1, .post_load = hid_post_load, .fields = (VMStateField[]) { - VMSTATE_STRUCT_ARRAY(ptr.queue, HIDState, QUEUE_LENGTH, 0, - vmstate_hid_ptr_queue, HIDPointerEvent), + VMSTATE_STRUCT_SUB_ARRAY(ptr.queue, HIDState, 0, 16, 0, + vmstate_hid_ptr_queue, HIDPointerEvent), VMSTATE_UINT32(head, HIDState), VMSTATE_UINT32(n, HIDState), VMSTATE_INT32(protocol, HIDState), VMSTATE_UINT8(idle, HIDState), VMSTATE_END_OF_LIST(), + }, + .subsections = (const VMStateDescription*[]) { + &vmstate_hid_ptr_extra_queue, + NULL + } +}; + +static const VMStateDescription vmstate_hid_keyboard_extra_keys = { + .name = "hid_kbd_extra_keys", + .version_id = 1, + .minimum_version_id = 1, + .needed = hid_extra_queue_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT32_SUB_ARRAY(kbd.keycodes, HIDState, 16, QUEUE_LENGTH - 16), + VMSTATE_UINT8_SUB_ARRAY(kbd.key, HIDState, 16, QUEUE_LENGTH - 16), + VMSTATE_END_OF_LIST() } }; @@ -604,15 +642,19 @@ const VMStateDescription vmstate_hid_keyboard_device = { .minimum_version_id = 1, .post_load = hid_post_load, .fields = (VMStateField[]) { - VMSTATE_UINT32_ARRAY(kbd.keycodes, HIDState, QUEUE_LENGTH), + VMSTATE_UINT32_SUB_ARRAY(kbd.keycodes, HIDState, 0, 16), VMSTATE_UINT32(head, HIDState), VMSTATE_UINT32(n, HIDState), VMSTATE_UINT16(kbd.modifiers, HIDState), VMSTATE_UINT8(kbd.leds, HIDState), - VMSTATE_UINT8_ARRAY(kbd.key, HIDState, 16), + VMSTATE_UINT8_SUB_ARRAY(kbd.key, HIDState, 0, 16), VMSTATE_INT32(kbd.keys, HIDState), VMSTATE_INT32(protocol, HIDState), VMSTATE_UINT8(idle, HIDState), VMSTATE_END_OF_LIST(), + }, + .subsections = (const VMStateDescription*[]) { + &vmstate_hid_keyboard_extra_keys, + NULL } }; diff --git a/include/hw/input/hid.h b/include/hw/input/hid.h index 2127c7c..bc561d4 100644 --- a/include/hw/input/hid.h +++ b/include/hw/input/hid.h @@ -13,7 +13,7 @@ typedef struct HIDPointerEvent { int32_t dz, buttons_state; } HIDPointerEvent; -#define QUEUE_LENGTH 16 /* should be enough for a triple-click */ +#define QUEUE_LENGTH 1024 #define QUEUE_MASK (QUEUE_LENGTH-1u) #define QUEUE_INCR(v) ((v)++, (v) &= QUEUE_MASK) @@ -29,7 +29,7 @@ typedef struct HIDKeyboardState { uint32_t keycodes[QUEUE_LENGTH]; uint16_t modifiers; uint8_t leds; - uint8_t key[16]; + uint8_t key[QUEUE_LENGTH]; int32_t keys; } HIDKeyboardState;