diff mbox

uhci: Lower uhci timer freq when guest is idle

Message ID 1395806243-11316-1-git-send-email-arei.gonglei@huawei.com
State New
Headers show

Commit Message

Gonglei (Arei) March 26, 2014, 3:57 a.m. UTC
From: Gonglei <arei.gonglei@huawei.com>

UHCI emulation polls the device at a freq of 1000HZ, which consumes
12~13% CPU even though a Windows guest is completely idle when the guest
was configed usb1.1 tablet devcie. This solution counts accumulated NAK
packets. when it reaches to 64, then the guest is supposed to be idle
and the freq is lowered to 10HZ.

This patch has been tested on Win7/WinXP/Win2008 guests, that reduces
the CPU consume from 12~13% to 6~7%.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 hw/usb/hcd-uhci.c |   17 ++++++++++++++++-
 1 files changed, 16 insertions(+), 1 deletions(-)

Comments

Gerd Hoffmann March 26, 2014, 7:58 a.m. UTC | #1
On Mi, 2014-03-26 at 11:57 +0800, arei.gonglei@huawei.com wrote:
> From: Gonglei <arei.gonglei@huawei.com>
> 
> UHCI emulation polls the device at a freq of 1000HZ, which consumes
> 12~13% CPU even though a Windows guest is completely idle when the guest
> was configed usb1.1 tablet devcie. This solution counts accumulated NAK
> packets. when it reaches to 64, then the guest is supposed to be idle
> and the freq is lowered to 10HZ.
> 
> This patch has been tested on Win7/WinXP/Win2008 guests, that reduces
> the CPU consume from 12~13% to 6~7%.

Which qemu version did you test with?  With any 2.0 release candidate
windows guests should suspend the usb-tablet.  And possibly stop all usb
polling done by the uhci controller in case the tables is the only
device connected.

So this should not be needed any more.

cheers,
  Gerd
Gonglei (Arei) March 26, 2014, 8:15 a.m. UTC | #2
> -----Original Message-----

> From: Gerd Hoffmann [mailto:kraxel@redhat.com]

> Sent: Wednesday, March 26, 2014 3:59 PM

> To: Gonglei (Arei)

> Cc: qemu-devel@nongnu.org; Huangweidong (C)

> Subject: Re: [PATCH] uhci: Lower uhci timer freq when guest is idle

> 

> On Mi, 2014-03-26 at 11:57 +0800, arei.gonglei@huawei.com wrote:

> > From: Gonglei <arei.gonglei@huawei.com>

> >

> > UHCI emulation polls the device at a freq of 1000HZ, which consumes

> > 12~13% CPU even though a Windows guest is completely idle when the guest

> > was configed usb1.1 tablet devcie. This solution counts accumulated NAK

> > packets. when it reaches to 64, then the guest is supposed to be idle

> > and the freq is lowered to 10HZ.

> >

> > This patch has been tested on Win7/WinXP/Win2008 guests, that reduces

> > the CPU consume from 12~13% to 6~7%.

> 

> Which qemu version did you test with?  

I tested it with the latest qemu upstream mainline.

BTW, I encountered the windows guest boot up failed problem which I have reported.

>With any 2.0 release candidate

> windows guests should suspend the usb-tablet.  And possibly stop all usb

> polling done by the uhci controller in case the tables is the only

> device connected.

Yeah, if there is no device attached uhci controller, I think we can reduce the freq,
otherwise the CPU consume is waste.

Best regards,
-Gonglei
Gonglei (Arei) April 28, 2014, 12:11 p.m. UTC | #3
Hi, Gerd.

What's your opinion about this issue? Thanks!



Best regards,
-Gonglei


> -----Original Message-----

> From: Gonglei (Arei)

> Sent: Wednesday, March 26, 2014 4:15 PM

> To: 'Gerd Hoffmann'

> Cc: qemu-devel@nongnu.org; Huangweidong (C)

> Subject: RE: [PATCH] uhci: Lower uhci timer freq when guest is idle

> 

> > -----Original Message-----

> > From: Gerd Hoffmann [mailto:kraxel@redhat.com]

> > Sent: Wednesday, March 26, 2014 3:59 PM

> > To: Gonglei (Arei)

> > Cc: qemu-devel@nongnu.org; Huangweidong (C)

> > Subject: Re: [PATCH] uhci: Lower uhci timer freq when guest is idle

> >

> > On Mi, 2014-03-26 at 11:57 +0800, arei.gonglei@huawei.com wrote:

> > > From: Gonglei <arei.gonglei@huawei.com>

> > >

> > > UHCI emulation polls the device at a freq of 1000HZ, which consumes

> > > 12~13% CPU even though a Windows guest is completely idle when the

> guest

> > > was configed usb1.1 tablet devcie. This solution counts accumulated NAK

> > > packets. when it reaches to 64, then the guest is supposed to be idle

> > > and the freq is lowered to 10HZ.

> > >

> > > This patch has been tested on Win7/WinXP/Win2008 guests, that reduces

> > > the CPU consume from 12~13% to 6~7%.

> >

> > Which qemu version did you test with?

> I tested it with the latest qemu upstream mainline.

> 

> BTW, I encountered the windows guest boot up failed problem which I have

> reported.

> 

> >With any 2.0 release candidate

> > windows guests should suspend the usb-tablet.  And possibly stop all usb

> > polling done by the uhci controller in case the tables is the only

> > device connected.

> Yeah, if there is no device attached uhci controller, I think we can reduce the

> freq,

> otherwise the CPU consume is waste.

> 

> Best regards,

> -Gonglei
Gerd Hoffmann April 28, 2014, 1:34 p.m. UTC | #4
On Mo, 2014-04-28 at 12:11 +0000, Gonglei (Arei) wrote:
> Hi, Gerd.
> 
> What's your opinion about this issue? Thanks!

qemu 2.0 should not need this.

background info:
https://www.kraxel.org/blog/2014/03/qemu-and-usb-tablet-cpu-consumtion/

cheers,
  Gerd
Gonglei (Arei) April 29, 2014, 2:06 a.m. UTC | #5
Hi,

> -----Original Message-----

> From: Gerd Hoffmann [mailto:kraxel@redhat.com]

> Sent: Monday, April 28, 2014 9:35 PM

> To: Gonglei (Arei)

> Cc: qemu-devel@nongnu.org; Huangweidong (C)

> Subject: Re: [PATCH] uhci: Lower uhci timer freq when guest is idle

> 

> On Mo, 2014-04-28 at 12:11 +0000, Gonglei (Arei) wrote:

> > Hi, Gerd.

> >

> > What's your opinion about this issue? Thanks!

> 

> qemu 2.0 should not need this.

> 

> background info:

> https://www.kraxel.org/blog/2014/03/qemu-and-usb-tablet-cpu-consumtion/

> 

That's great! Thanks.
I will test it on qemu 2.0.0. 


Best regards,
-Gonglei
diff mbox

Patch

diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 0820244..fb86959 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -73,6 +73,7 @@ 
 #define UHCI_PORT_WRITE_CLEAR  (UHCI_PORT_CSC | UHCI_PORT_ENC)
 
 #define FRAME_TIMER_FREQ 1000
+#define PERIODIC_INACTIVE  64
 
 #define FRAME_MAX_LOOPS  256
 
@@ -173,6 +174,8 @@  struct UHCIState {
     char *masterbus;
     uint32_t firstport;
     uint32_t maxframes;
+
+    /* Accumulated NAK counter */
+    uint32_t async_naks;
 };
 
 typedef struct UHCI_TD {
@@ -920,6 +923,12 @@  static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr,
         uhci_update_irq(s);
         return TD_RESULT_STOP_FRAME;
     }
+
+    if (async->packet.status == USB_RET_NAK) {
+        s->async_naks++;
+    } else {
+        s->async_naks = 0;
+    }
 
     if (async->packet.status == USB_RET_ASYNC) {
         uhci_async_link(async);
@@ -1153,6 +1162,7 @@  static void uhci_frame_timer(void *opaque)
 {
     UHCIState *s = opaque;
     uint64_t t_now, t_last_run;
+    uint64_t t_now, t_last_run, t_next;
     int i, frames;
     const uint64_t frame_t = get_ticks_per_sec() / FRAME_TIMER_FREQ;
 
@@ -1205,7 +1215,12 @@  static void uhci_frame_timer(void *opaque)
     }
     s->pending_int_mask = 0;
 
-    timer_mod(s->frame_timer, t_now + frame_t);
+    t_next = t_now + frame_t;
+    /* slower down the timer if the guest vm is idle */
+    if (s->async_naks > PERIODIC_INACTIVE) {
+        t_next += 100 * frame_t;
+    }
+
+    timer_mod(s->frame_timer, t_next);
 }
 
 static const MemoryRegionOps uhci_ioport_ops = {