Patchwork [6/6] usb-tablet: Allow connecting to ehci

login
register
mail settings
Submitter Gerd Hoffmann
Date Dec. 5, 2012, 10:11 a.m.
Message ID <1354702284-13518-7-git-send-email-kraxel@redhat.com>
Download mbox | patch
Permalink /patch/203814/
State New
Headers show

Comments

Gerd Hoffmann - Dec. 5, 2012, 10:11 a.m.
From: Hans de Goede <hdegoede@redhat.com>

Our ehci code has is capable of significantly lowering the wakeup rate
for the hcd emulation while the device is idle. It is possible to add
similar code ot the uhci emulation, but that simply is not there atm,
and there is no reason why a (virtual) usb-tablet can not be a USB-2 device.

Making usb-hid devices connect to the emulated ehci controller instead
of the emulated uhci controller on vms which have both lowers the cpuload
for a fully idle vm from 20% to 2-3% (on my laptop).

An alternative implementation to using a property to select the tablet
type, would be simply making it a new device type, ie usb-tablet2, but the
downside of that is that this will require libvirt changes to be available
through libvirt at all, and then management tools changes to become the
default for new vms, where as using a property will automatically get
any pc-1.3 type vms the lower cpuload.

[ kraxel: adapt compat property for post-1.3 merge ]

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>

tablet compat fixup

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/pc_piix.c     |    9 ++++++
 hw/usb/dev-hid.c |   85 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 93 insertions(+), 1 deletions(-)
Erik Rull - Dec. 26, 2012, 12:07 p.m.
Hi Gerd, hi Hans,

is my assumption correct that if I check out and compile this version from 
GIT master that the usb-tablet device is automatically routed to ehci 
without changing anything else in the qemu call arguments? (And the 
performance enhancement takes place automatically)
If not - what has to be changed to get it working?

Best regards,

Erik



Gerd Hoffmann wrote:
> From: Hans de Goede <hdegoede@redhat.com>
>
> Our ehci code has is capable of significantly lowering the wakeup rate
> for the hcd emulation while the device is idle. It is possible to add
> similar code ot the uhci emulation, but that simply is not there atm,
> and there is no reason why a (virtual) usb-tablet can not be a USB-2 device.
>
> Making usb-hid devices connect to the emulated ehci controller instead
> of the emulated uhci controller on vms which have both lowers the cpuload
> for a fully idle vm from 20% to 2-3% (on my laptop).
>
> An alternative implementation to using a property to select the tablet
> type, would be simply making it a new device type, ie usb-tablet2, but the
> downside of that is that this will require libvirt changes to be available
> through libvirt at all, and then management tools changes to become the
> default for new vms, where as using a property will automatically get
> any pc-1.3 type vms the lower cpuload.
>
> [ kraxel: adapt compat property for post-1.3 merge ]
>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
>
> tablet compat fixup
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Hao Luo - Dec. 26, 2012, 3:53 p.m.
Erik,

You can take a look at my recent post about usb tablet peforamnce over ehci, in which I mentioned a libvirt config of how to let usb tablet connect to ehci.

2012-12-26



Hao Luo



发件人:Erik Rull
发送时间:2012-12-26 20:08
主题:Re: [Qemu-devel] [PATCH 6/6] usb-tablet: Allow connecting to ehci
收件人:"Gerd Hoffmann"<kraxel@redhat.com>
抄送:"Hans de Goede"<hdegoede@redhat.com>,"qemu-devel"<qemu-devel@nongnu.org>

Hi Gerd, hi Hans, 

is my assumption correct that if I check out and compile this version from  
GIT master that the usb-tablet device is automatically routed to ehci  
without changing anything else in the qemu call arguments? (And the  
performance enhancement takes place automatically) 
If not - what has to be changed to get it working? 

Best regards, 

Erik 



Gerd Hoffmann wrote: 
> From: Hans de Goede <hdegoede@redhat.com> 

> 

> Our ehci code has is capable of significantly lowering the wakeup rate 

> for the hcd emulation while the device is idle. It is possible to add 

> similar code ot the uhci emulation, but that simply is not there atm, 

> and there is no reason why a (virtual) usb-tablet can not be a USB-2 device. 

> 

> Making usb-hid devices connect to the emulated ehci controller instead 

> of the emulated uhci controller on vms which have both lowers the cpuload 

> for a fully idle vm from 20% to 2-3% (on my laptop). 

> 

> An alternative implementation to using a property to select the tablet 

> type, would be simply making it a new device type, ie usb-tablet2, but the 

> downside of that is that this will require libvirt changes to be available 

> through libvirt at all, and then management tools changes to become the 

> default for new vms, where as using a property will automatically get 

> any pc-1.3 type vms the lower cpuload. 

> 

> [ kraxel: adapt compat property for post-1.3 merge ] 

> 

> Signed-off-by: Hans de Goede <hdegoede@redhat.com> 

> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> 

> 

> tablet compat fixup 

> 

> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Hans de Goede - Dec. 30, 2012, 9:29 a.m.
Hi,

On 12/26/2012 01:07 PM, Erik Rull wrote:
> Hi Gerd, hi Hans,
>
> is my assumption correct that if I check out and compile this version from GIT master that the usb-tablet device is automatically routed to ehci without changing anything else in the qemu call arguments? (And the performance enhancement takes place automatically)
> If not - what has to be changed to get it working?

That depends, if you specify a machine model, you need to change it to pc-1.4, if you
don't specify a machine model you will get the change automatically, as 1.4 is the new
default machine model.

Regards,

Hans
Erik Rull - Dec. 30, 2012, 11:55 a.m.
Hi Hans,

Hans de Goede wrote:
> Hi,
>
> On 12/26/2012 01:07 PM, Erik Rull wrote:
>> Hi Gerd, hi Hans,
>>
>> is my assumption correct that if I check out and compile this version
>> from GIT master that the usb-tablet device is automatically routed to
>> ehci without changing anything else in the qemu call arguments? (And the
>> performance enhancement takes place automatically)
>> If not - what has to be changed to get it working?
>
> That depends, if you specify a machine model, you need to change it to
> pc-1.4, if you
> don't specify a machine model you will get the change automatically, as 1.4
> is the new
> default machine model.
>
> Regards,
>
> Hans

Thanks.

QEMU shows version 1.3.50 at the moment (from git), is the 1.4 model 
internally already active there?

Best regards,

Erik
Hans de Goede - Jan. 2, 2013, 3:57 p.m.
Hi,

On 12/30/2012 12:55 PM, Erik Rull wrote:
> Hi Hans,
>
> Hans de Goede wrote:
>> Hi,
>>
>> On 12/26/2012 01:07 PM, Erik Rull wrote:
>>> Hi Gerd, hi Hans,
>>>
>>> is my assumption correct that if I check out and compile this version
>>> from GIT master that the usb-tablet device is automatically routed to
>>> ehci without changing anything else in the qemu call arguments? (And the
>>> performance enhancement takes place automatically)
>>> If not - what has to be changed to get it working?
>>
>> That depends, if you specify a machine model, you need to change it to
>> pc-1.4, if you
>> don't specify a machine model you will get the change automatically, as 1.4
>> is the new
>> default machine model.
>>
>> Regards,
>>
>> Hans
>
> Thanks.
>
> QEMU shows version 1.3.50 at the moment (from git), is the 1.4 model internally already active there?

Probably, that depends on the exact git version you're using (the 1.3.50 just
indicates you're using a git build, not which version exactly). If you've build
from a recent git checkout, then yes the default model is already 1.4

Regards,

Hans

Patch

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 040cd07..19e342a 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -290,17 +290,26 @@  static QEMUMachine pc_machine_v1_4 = {
     .is_default = 1,
 };
 
+#define PC_COMPAT_1_3 \
+        {\
+            .driver   = "usb-tablet",\
+            .property = "usb_version",\
+            .value    = stringify(1),\
+        }
+
 static QEMUMachine pc_machine_v1_3 = {
     .name = "pc-1.3",
     .desc = "Standard PC",
     .init = pc_init_pci_1_3,
     .max_cpus = 255,
     .compat_props = (GlobalProperty[]) {
+        PC_COMPAT_1_3,
         { /* end of list */ }
     },
 };
 
 #define PC_COMPAT_1_2 \
+        PC_COMPAT_1_3,\
         {\
             .driver   = "nec-usb-xhci",\
             .property = "msi",\
diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c
index 55266b1..8749128 100644
--- a/hw/usb/dev-hid.c
+++ b/hw/usb/dev-hid.c
@@ -46,6 +46,7 @@  typedef struct USBHIDState {
     USBDevice dev;
     USBEndpoint *intr;
     HIDState hid;
+    uint32_t usb_version;
 } USBHIDState;
 
 enum {
@@ -131,6 +132,36 @@  static const USBDescIface desc_iface_tablet = {
     },
 };
 
+static const USBDescIface desc_iface_tablet2 = {
+    .bInterfaceNumber              = 0,
+    .bNumEndpoints                 = 1,
+    .bInterfaceClass               = USB_CLASS_HID,
+    .bInterfaceProtocol            = 0x02,
+    .ndesc                         = 1,
+    .descs = (USBDescOther[]) {
+        {
+            /* HID descriptor */
+            .data = (uint8_t[]) {
+                0x09,          /*  u8  bLength */
+                USB_DT_HID,    /*  u8  bDescriptorType */
+                0x01, 0x00,    /*  u16 HID_class */
+                0x00,          /*  u8  country_code */
+                0x01,          /*  u8  num_descriptors */
+                USB_DT_REPORT, /*  u8  type: Report */
+                74, 0,         /*  u16 len */
+            },
+        },
+    },
+    .eps = (USBDescEndpoint[]) {
+        {
+            .bEndpointAddress      = USB_DIR_IN | 0x01,
+            .bmAttributes          = USB_ENDPOINT_XFER_INT,
+            .wMaxPacketSize        = 8,
+            .bInterval             = 4, /* 2 ^ (4-1) * 125 usecs = 1 ms */
+        },
+    },
+};
+
 static const USBDescIface desc_iface_keyboard = {
     .bInterfaceNumber              = 0,
     .bNumEndpoints                 = 1,
@@ -196,6 +227,23 @@  static const USBDescDevice desc_device_tablet = {
     },
 };
 
+static const USBDescDevice desc_device_tablet2 = {
+    .bcdUSB                        = 0x0200,
+    .bMaxPacketSize0               = 64,
+    .bNumConfigurations            = 1,
+    .confs = (USBDescConfig[]) {
+        {
+            .bNumInterfaces        = 1,
+            .bConfigurationValue   = 1,
+            .iConfiguration        = STR_CONFIG_TABLET,
+            .bmAttributes          = 0xa0,
+            .bMaxPower             = 50,
+            .nif = 1,
+            .ifs = &desc_iface_tablet2,
+        },
+    },
+};
+
 static const USBDescDevice desc_device_keyboard = {
     .bcdUSB                        = 0x0100,
     .bMaxPacketSize0               = 8,
@@ -239,6 +287,20 @@  static const USBDesc desc_tablet = {
     .str  = desc_strings,
 };
 
+static const USBDesc desc_tablet2 = {
+    .id = {
+        .idVendor          = 0x0627,
+        .idProduct         = 0x0001,
+        .bcdDevice         = 0,
+        .iManufacturer     = STR_MANUFACTURER,
+        .iProduct          = STR_PRODUCT_TABLET,
+        .iSerialNumber     = STR_SERIALNUMBER,
+    },
+    .full = &desc_device_tablet,
+    .high = &desc_device_tablet2,
+    .str  = desc_strings,
+};
+
 static const USBDesc desc_keyboard = {
     .id = {
         .idVendor          = 0x0627,
@@ -508,6 +570,21 @@  static int usb_hid_initfn(USBDevice *dev, int kind)
 
 static int usb_tablet_initfn(USBDevice *dev)
 {
+    USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev);
+
+    switch (us->usb_version) {
+    case 1:
+        dev->usb_desc = &desc_tablet;
+        break;
+    case 2:
+        dev->usb_desc = &desc_tablet2;
+        break;
+    default:
+        error_report("Invalid usb version %d for usb-tabler (must be 1 or 2)",
+                     us->usb_version);
+        return -1;
+    }
+
     return usb_hid_initfn(dev, HID_TABLET);
 }
 
@@ -562,8 +639,14 @@  static void usb_hid_class_initfn(ObjectClass *klass, void *data)
     uc->handle_control = usb_hid_handle_control;
     uc->handle_data    = usb_hid_handle_data;
     uc->handle_destroy = usb_hid_handle_destroy;
+    uc->handle_attach  = usb_desc_attach;
 }
 
+static Property usb_tablet_properties[] = {
+        DEFINE_PROP_UINT32("usb_version", USBHIDState, usb_version, 2),
+        DEFINE_PROP_END_OF_LIST(),
+};
+
 static void usb_tablet_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -572,8 +655,8 @@  static void usb_tablet_class_initfn(ObjectClass *klass, void *data)
     usb_hid_class_initfn(klass, data);
     uc->init           = usb_tablet_initfn;
     uc->product_desc   = "QEMU USB Tablet";
-    uc->usb_desc       = &desc_tablet;
     dc->vmsd = &vmstate_usb_ptr;
+    dc->props = usb_tablet_properties;
 }
 
 static TypeInfo usb_tablet_info = {