qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] hid: Extend the event queue size to 1024


From: Alexander Graf
Subject: [Qemu-devel] [PATCH] hid: Extend the event queue size to 1024
Date: Thu, 14 Apr 2016 16:25:12 +0200

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 <address@hidden>
Signed-off-by: Alexander Graf <address@hidden>
---
 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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]