[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