Re: [Qemu-devel] High CPU use of -usbdevice tablet (was Re: KVM usability)

Paul Brook
2010-04-04T14:25:21Z

> > Looks like the tablet is set to 100 Hz polling rate. We may be able
> > to get away with 30 Hz or even less (ep_bInterval, in ms, in
> > hw/usb-wacom.c).
>
> Changing the USB tablet polling interval from 10ms to 100ms in both
> hw/usb-wacom.c and hw/usb-hid.c made no difference except the an increase
> in bInterval shown in lsusb -v in the guest and the hint of jerky mouse
> movement I expected from setting this value so high. A similar change to
> the polling interval for the keyboard and mouse also made no difference to
> their performance impact.

The USB HID devices implement the SET_IDLE command, so the polling interval
will have no real effect on performance.

My guess is that the overhead you're seeing is entirely from the USB host
adapter having to wake up and check the transport descriptor lists. This will
only result in the guest being woken if a device actually responds (as
mentioned above it should not).

>Taking the FRAME_TIMER_FREQ down to 100 in hw/usb-uhci.c does seem to reduce
>the CPU load quite a bit, but at the expense of making the USB tablet (and
>presumably all other USB devices) very laggy.

The guest USB driver explicitly decides which devices to poll each frame.
Slowing down the frame rate will effectively change the polling period by the
same factor. e.g. the HID device requests a polling rate of 10ms, you slowed
down frame rate by 10x, so you're efectively only polling every 100ms.

If you want a quick and nasty hack then you can probably make the device wake
up less often, and process multiple frames every wakeup. However this is
probably going to do bad things (at best extremely poor performance) when
using actual USB devices.

Fixing this properly is hard because the transport descriptor lists are stores
in system RAM, and polled by the host adapter. The first step is to read the
whole table of descriptors, and calculate when the next event is due. However
the guest will not explicitly notify the HBA when these tables are modified,
so you also need some sort of MMU trap to trigger recalculation.

This only gets you down to the base polling interval requested by the device.
Increasing this interval causes significant user visible latency, so
increasing it is not an option. The guest is also likely to distribute polling
events evenly, further reducing the effective sleep interval. To fix this you
need additional APIs so that a device can report when an endpoint will become
unblocked, rather than just waiting to be polled and NAKing the request.

Paul