Re: [PATCH 3/3] USB: EHCI: disable IAA_WATCHDOG and START_UNLINK_INTR if they needn't to be handled
On Mon, Aug 19, 2013 at 10:33 PM, Greg Kroah-Hartman gre...@linuxfoundation.org wrote: Why would those events not need to be handled? For IAA_WATCHDOG event, it needn't to handle when IAA interrupt comes. For START_UNLINK_INTR event, we don't need to unlink intr qh any more if intr urb submit request comes. What does this help with? Measurements please. The patch may avoid unnecessary CPU wakeups caused by timer expiration, and measurement is provided below. On Mon, Aug 19, 2013 at 11:30 PM, Alan Stern st...@rowland.harvard.edu wrote: On Mon, 19 Aug 2013, Ming Lei wrote: This patch introduces ehci_disable_event(), which is applied on IAA_WATCHDOG and START_UNLINK_INTR events in case that the two events needn't to be handled, so that we may avoid unnecessary CPU wakeup. @@ -100,6 +100,20 @@ static void ehci_enable_event(struct ehci_hcd *ehci, unsigned event, } Only one blank line here, please. OK. +/* Warning: don't call this function from hrtimer handler context */ +static void ehci_disable_event(struct ehci_hcd *ehci, unsigned event) +{ + ehci-enabled_hrtimer_events = ~(1 event); + if (!ehci-enabled_hrtimer_events) { + ehci-next_hrtimer_event = EHCI_HRTIMER_NO_EVENT; + hrtimer_cancel(ehci-hrtimer); + } else if (ehci-next_hrtimer_event == event) { + ehci-next_hrtimer_event = + ffs(ehci-enabled_hrtimer_events) - 1; Should the timer be rescheduled here? It's hard to say without seeing some test results. You are right, the timer should be rescheduled here, otherwise there is no effect on HCD with need_io_watchdog set. With below change on ehci_disable_event(), about 7~8 times timer expiration can be saved when one asix network NIC is connected to EHCI without network traffic(the device responds interrupt poll 7~8 times per second constantly for link status query), no matter ehci-need_io_watchdog is set or not. BTW, the timer expiration event is observed via /proc/timer_stats. /* Warning: don't call this function from hrtimer handler context */ static void ehci_disable_event(struct ehci_hcd *ehci, unsigned event) { ehci-enabled_hrtimer_events = ~(1 event); if (!ehci-enabled_hrtimer_events) { ehci-next_hrtimer_event = EHCI_HRTIMER_NO_EVENT; hrtimer_cancel(ehci-hrtimer); } else if (ehci-next_hrtimer_event == event) { ehci-next_hrtimer_event = EHCI_HRTIMER_NO_EVENT; enum ehci_hrtimer_event next = ffs(ehci-enabled_hrtimer_events) - 1; ehci_enable_event(ehci, next, 0); } } Thanks, -- Ming Lei -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/3] USB: EHCI: disable IAA_WATCHDOG and START_UNLINK_INTR if they needn't to be handled
On Tue, 20 Aug 2013, Ming Lei wrote: On Mon, Aug 19, 2013 at 10:33 PM, Greg Kroah-Hartman gre...@linuxfoundation.org wrote: Why would those events not need to be handled? For IAA_WATCHDOG event, it needn't to handle when IAA interrupt comes. For START_UNLINK_INTR event, we don't need to unlink intr qh any more if intr urb submit request comes. This could be explained more clearly. The events mentioned in the patch description aren't real events at all; they are timeouts. The actual events are the IAA interrupt and URB submission. The idea of the patch is that once the actual event occurs, the corresponding timeout isn't needed any more and so the timer can be cancelled. +/* Warning: don't call this function from hrtimer handler context */ +static void ehci_disable_event(struct ehci_hcd *ehci, unsigned event) +{ + ehci-enabled_hrtimer_events = ~(1 event); + if (!ehci-enabled_hrtimer_events) { + ehci-next_hrtimer_event = EHCI_HRTIMER_NO_EVENT; + hrtimer_cancel(ehci-hrtimer); + } else if (ehci-next_hrtimer_event == event) { + ehci-next_hrtimer_event = + ffs(ehci-enabled_hrtimer_events) - 1; Should the timer be rescheduled here? It's hard to say without seeing some test results. You are right, the timer should be rescheduled here, otherwise there is no effect on HCD with need_io_watchdog set. With below change on ehci_disable_event(), about 7~8 times timer expiration can be saved when one asix network NIC is connected to EHCI without network traffic(the device responds interrupt poll 7~8 times per second constantly for link status query), no matter ehci-need_io_watchdog is set or not. BTW, the timer expiration event is observed via /proc/timer_stats. /* Warning: don't call this function from hrtimer handler context */ static void ehci_disable_event(struct ehci_hcd *ehci, unsigned event) { ehci-enabled_hrtimer_events = ~(1 event); if (!ehci-enabled_hrtimer_events) { ehci-next_hrtimer_event = EHCI_HRTIMER_NO_EVENT; hrtimer_cancel(ehci-hrtimer); } else if (ehci-next_hrtimer_event == event) { ehci-next_hrtimer_event = EHCI_HRTIMER_NO_EVENT; enum ehci_hrtimer_event next = ffs(ehci-enabled_hrtimer_events) - 1; Don't declare new variables in the middle of a block. ehci_enable_event(ehci, next, 0); The third argument should be false, not 0. It is a bool. Alan Stern -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] USB: EHCI: disable IAA_WATCHDOG and START_UNLINK_INTR if they needn't to be handled
This patch introduces ehci_disable_event(), which is applied on IAA_WATCHDOG and START_UNLINK_INTR events in case that the two events needn't to be handled, so that we may avoid unnecessary CPU wakeup. Cc: Alan Stern st...@rowland.harvard.edu Signed-off-by: Ming Lei ming@canonical.com --- drivers/usb/host/ehci-hcd.c | 12 +--- drivers/usb/host/ehci-sched.c |4 +++- drivers/usb/host/ehci-timer.c | 14 ++ 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 73c7299..549da36 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -738,17 +738,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) if (status STS_IAA) { /* Turn off the IAA watchdog */ - ehci-enabled_hrtimer_events = ~BIT(EHCI_HRTIMER_IAA_WATCHDOG); - - /* -* Mild optimization: Allow another IAAD to reset the -* hrtimer, if one occurs before the next expiration. -* In theory we could always cancel the hrtimer, but -* tests show that about half the time it will be reset -* for some other event anyway. -*/ - if (ehci-next_hrtimer_event == EHCI_HRTIMER_IAA_WATCHDOG) - ++ehci-next_hrtimer_event; + ehci_disable_event(ehci, EHCI_HRTIMER_IAA_WATCHDOG); /* guard against (alleged) silicon errata */ if (cmd CMD_IAAD) diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 6631089..83be03f 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -610,9 +610,11 @@ static void cancel_unlink_wait_intr(struct ehci_hcd *ehci, struct ehci_qh *qh) list_del_init(qh-unlink_node); /* -* TODO: disable the event of EHCI_HRTIMER_START_UNLINK_INTR for +* disable the event of EHCI_HRTIMER_START_UNLINK_INTR for * avoiding unnecessary CPU wakeup */ + if (list_empty(ehci-intr_unlink_wait)) + ehci_disable_event(ehci, EHCI_HRTIMER_START_UNLINK_INTR); } static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh) diff --git a/drivers/usb/host/ehci-timer.c b/drivers/usb/host/ehci-timer.c index 424ac5d..89bce50 100644 --- a/drivers/usb/host/ehci-timer.c +++ b/drivers/usb/host/ehci-timer.c @@ -100,6 +100,20 @@ static void ehci_enable_event(struct ehci_hcd *ehci, unsigned event, } +/* Warning: don't call this function from hrtimer handler context */ +static void ehci_disable_event(struct ehci_hcd *ehci, unsigned event) +{ + ehci-enabled_hrtimer_events = ~(1 event); + if (!ehci-enabled_hrtimer_events) { + ehci-next_hrtimer_event = EHCI_HRTIMER_NO_EVENT; + hrtimer_cancel(ehci-hrtimer); + } else if (ehci-next_hrtimer_event == event) { + ehci-next_hrtimer_event = + ffs(ehci-enabled_hrtimer_events) - 1; + } +} + + /* Poll the STS_ASS status bit; see when it agrees with CMD_ASE */ static void ehci_poll_ASS(struct ehci_hcd *ehci) { -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/3] USB: EHCI: disable IAA_WATCHDOG and START_UNLINK_INTR if they needn't to be handled
On Mon, Aug 19, 2013 at 07:04:20PM +0800, Ming Lei wrote: This patch introduces ehci_disable_event(), which is applied on IAA_WATCHDOG and START_UNLINK_INTR events in case that the two events needn't to be handled, so that we may avoid unnecessary CPU wakeup. Why would those events not need to be handled? What does this help with? Measurements please. greg k-h -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/3] USB: EHCI: disable IAA_WATCHDOG and START_UNLINK_INTR if they needn't to be handled
On Mon, 19 Aug 2013, Ming Lei wrote: This patch introduces ehci_disable_event(), which is applied on IAA_WATCHDOG and START_UNLINK_INTR events in case that the two events needn't to be handled, so that we may avoid unnecessary CPU wakeup. @@ -100,6 +100,20 @@ static void ehci_enable_event(struct ehci_hcd *ehci, unsigned event, } Only one blank line here, please. +/* Warning: don't call this function from hrtimer handler context */ +static void ehci_disable_event(struct ehci_hcd *ehci, unsigned event) +{ + ehci-enabled_hrtimer_events = ~(1 event); + if (!ehci-enabled_hrtimer_events) { + ehci-next_hrtimer_event = EHCI_HRTIMER_NO_EVENT; + hrtimer_cancel(ehci-hrtimer); + } else if (ehci-next_hrtimer_event == event) { + ehci-next_hrtimer_event = + ffs(ehci-enabled_hrtimer_events) - 1; Should the timer be rescheduled here? It's hard to say without seeing some test results. Alan Stern -- To unsubscribe from this list: send the line unsubscribe linux-usb in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html