From: will.deacon@arm.com (Will Deacon)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 2/2] arm64: use WFE for long delays
Date: Fri, 22 Sep 2017 11:41:02 +0100 [thread overview]
Message-ID: <20170922104102.GB23365@arm.com> (raw)
In-Reply-To: <1502959160-30900-3-git-send-email-julien.thierry@arm.com>
On Thu, Aug 17, 2017 at 09:39:20AM +0100, Julien Thierry wrote:
> The current delay implementation uses the yield instruction, which is a hint
> that it is beneficial to schedule another thread. As this is a hint, it may be
> implemented as a NOP, causing all delays to be busy loops. This is the case for
> many existing CPUs.
>
> Taking advantage of the generic timer sending periodic events to all cores, we
> can use WFE during delays to reduce power consumption. This is beneficial only
> for delays longer than the period of the timer event stream.
>
> If timer event stream is not enabled, delays will behave as yield/busy loops.
>
> Signed-off-by: Julien Thierry <julien.thierry@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> ---
> arch/arm64/lib/delay.c | 25 ++++++++++++++++++++-----
> include/asm-generic/delay.h | 9 +++++++--
> 2 files changed, 27 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm64/lib/delay.c b/arch/arm64/lib/delay.c
> index dad4ec9..ada7005 100644
> --- a/arch/arm64/lib/delay.c
> +++ b/arch/arm64/lib/delay.c
> @@ -24,10 +24,28 @@
> #include <linux/module.h>
> #include <linux/timex.h>
>
> +#include <clocksource/arm_arch_timer.h>
> +
> +#define USECS_TO_CYCLES(TIME_USECS) \
> + (xloops_to_cycles(usecs_to_xloops(TIME_USECS)))
> +
> +static inline unsigned long xloops_to_cycles(unsigned long xloops)
> +{
> + return (xloops * loops_per_jiffy * HZ) >> 32;
> +}
> +
> void __delay(unsigned long cycles)
> {
> cycles_t start = get_cycles();
>
> + if (arch_timer_evtstrm_available()) {
> + const cycles_t timer_evt_period =
> + USECS_TO_CYCLES(1000000 / ARCH_TIMER_EVT_STREAM_FREQ);
Given that ARCH_TIMER_EVT_STREAM_FREQ is defined as:
#define ARCH_TIMER_EVT_STREAM_FREQ 10000 /* 100us */
perhaps it would actually be better to define all of this in terms of
a 100us period.
> +
> + while (get_cycles() - start + timer_evt_period < cycles)
Please add some brackets here for clarify.
> + wfe();
> + }
> +
> while ((get_cycles() - start) < cycles)
> cpu_relax();
> }
> @@ -35,16 +53,13 @@ void __delay(unsigned long cycles)
>
> inline void __const_udelay(unsigned long xloops)
> {
> - unsigned long loops;
> -
> - loops = xloops * loops_per_jiffy * HZ;
> - __delay(loops >> 32);
> + __delay(xloops_to_cycles(xloops));
> }
> EXPORT_SYMBOL(__const_udelay);
>
> void __udelay(unsigned long usecs)
> {
> - __const_udelay(usecs * 0x10C7UL); /* 2**32 / 1000000 (rounded up) */
> + __const_udelay(usecs_to_xloops(usecs));
> }
> EXPORT_SYMBOL(__udelay);
>
> diff --git a/include/asm-generic/delay.h b/include/asm-generic/delay.h
> index 0f79054..1538e58 100644
> --- a/include/asm-generic/delay.h
> +++ b/include/asm-generic/delay.h
> @@ -10,19 +10,24 @@
> extern void __const_udelay(unsigned long xloops);
> extern void __delay(unsigned long loops);
>
> +/* 0x10c7 is 2**32 / 1000000 (rounded up) */
> +static inline unsigned long usecs_to_xloops(unsigned long usecs)
> +{
> + return usecs * 0x10C7UL;
> +}
I'm not sure it's worth factoring this out tbh. It's not got lots of use,
and you haven't done one for nsecs so I'd be inclined to leave the generic
code as-is.
Will
prev parent reply other threads:[~2017-09-22 10:41 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-17 8:39 [PATCH v2 0/2] WFE for long delays Julien Thierry
2017-08-17 8:39 ` [PATCH v2 1/2] arm_arch_timer: Expose event stream status Julien Thierry
2017-09-22 10:25 ` Will Deacon
2017-09-22 10:58 ` Julien Thierry
2017-08-17 8:39 ` [PATCH v2 2/2] arm64: use WFE for long delays Julien Thierry
2017-09-22 10:41 ` Will Deacon [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170922104102.GB23365@arm.com \
--to=will.deacon@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).