[PATCH] powerpc: reduce number of WATCHDOG_RESET calls from flush_cache
Rasmus Villemoes
rasmus.villemoes at prevas.dk
Fri Sep 18 10:20:46 CEST 2020
On 04/06/2020 12.31, Stefan Roese wrote:
> On 04.06.20 11:30, Rasmus Villemoes wrote:
>> Calling WATCHDOG_RESET for each and every cache line is overkill.
>>
>> In our case, the kernel image is a little over 7MB, and the almost
>> 500000 calls of WATCHDOG_RESET() adds about one second to the
>> boottime.
>>
>> I very highly doubt there's any real hardware where flushing 64K
>> from cache to memory takes more than a few milliseconds, so this
>> should be completely safe. Since it reduces the number of
>> WATCHDOG_RESET() calls by roughly a factor of 1000, the overhead from
>> those is practically eliminated. (Just in case the range flushed is so
>> small that it doesn't cross a 64K boundary, add a single
>> WATCHDOG_RESET() between the loops).
>>
>> 64K is chosen because that's also the default chunk size used by the
>> hashing algorithms, and when, say, a sha256 digest of a kernel image of
>> a few MB is being verified, that's almost guaranteed to be cache-cold,
>> so apart from the computations being done, the hashing is also bounded
>> by memory speed - so if 64K works for those cases, it should certainly
>> also work when memory access is the only thing being done.
>>
>> Signed-off-by: Rasmus Villemoes <rasmus.villemoes at prevas.dk>
>
> Reviewed-by: Stefan Roese <sr at denx.de>
Ping.
> Thanks,
> Stefan
>
>> ---
>> arch/powerpc/lib/cache.c | 8 ++++++--
>> 1 file changed, 6 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/powerpc/lib/cache.c b/arch/powerpc/lib/cache.c
>> index 528361e972..df2310f4e2 100644
>> --- a/arch/powerpc/lib/cache.c
>> +++ b/arch/powerpc/lib/cache.c
>> @@ -8,6 +8,7 @@
>> #include <cpu_func.h>
>> #include <asm/cache.h>
>> #include <watchdog.h>
>> +#include <linux/sizes.h>
>> void flush_cache(ulong start_addr, ulong size)
>> {
>> @@ -21,15 +22,18 @@ void flush_cache(ulong start_addr, ulong size)
>> for (addr = start; (addr <= end) && (addr >= start);
>> addr += CONFIG_SYS_CACHELINE_SIZE) {
>> asm volatile("dcbst 0,%0" : : "r" (addr) : "memory");
>> - WATCHDOG_RESET();
>> + if ((addr & (SZ_64K - 1)) == 0)
>> + WATCHDOG_RESET();
>> }
>> /* wait for all dcbst to complete on bus */
>> asm volatile("sync" : : : "memory");
>> + WATCHDOG_RESET();
>> for (addr = start; (addr <= end) && (addr >= start);
>> addr += CONFIG_SYS_CACHELINE_SIZE) {
>> asm volatile("icbi 0,%0" : : "r" (addr) : "memory");
>> - WATCHDOG_RESET();
>> + if ((addr & (SZ_64K - 1)) == 0)
>> + WATCHDOG_RESET();
>> }
>> asm volatile("sync" : : : "memory");
>> /* flush prefetch queue */
>>
--
Rasmus Villemoes
Software Developer
Prevas A/S
Hedeager 3
DK-8200 Aarhus N
+45 51210274
rasmus.villemoes at prevas.dk
www.prevas.dk
More information about the U-Boot
mailing list