qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] hid: Extend the event queue size to 1024
@ 2016-04-14 14:25 Alexander Graf
  2016-04-14 15:17 ` Gerd Hoffmann
  2016-04-19  9:28 ` Juan Quintela
  0 siblings, 2 replies; 10+ messages in thread
From: Alexander Graf @ 2016-04-14 14:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Juan Quintela, Dinar Valeev, Dirk Mueller

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 <dvaleev@suse.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 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;
 
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2016-04-19  9:28 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-04-14 14:25 [Qemu-devel] [PATCH] hid: Extend the event queue size to 1024 Alexander Graf
2016-04-14 15:17 ` Gerd Hoffmann
2016-04-14 15:29   ` Alexander Graf
2016-04-14 16:19     ` Gerd Hoffmann
2016-04-15 12:18       ` Dinar Valeev
2016-04-18  6:53     ` Gerd Hoffmann
2016-04-18  7:26       ` Alexander Graf
2016-04-18  9:21         ` Gerd Hoffmann
2016-04-18  9:27           ` Alexander Graf
2016-04-19  9:28 ` Juan Quintela

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).