Message ID | 20230605195911.96033-1-philmd@linaro.org |
---|---|
State | New |
Headers | show |
Series | util/cacheflush: Avoid flushing dcache twice when not necessary | expand |
Subject: "Avoid flushing dcache twice [on Darwin] when not necessary" On 5/6/23 21:59, Philippe Mathieu-Daudé wrote: > <libkern/OSCacheControl.h> describes sys_icache_invalidate() as > "equivalent to sys_cache_control(kCacheFunctionPrepareForExecution)", > having kCacheFunctionPrepareForExecution defined as: > > /* Prepare memory for execution. This should be called > * after writing machine instructions to memory, before > * executing them. It syncs the dcache and icache. [...] > */ > > Since the dcache is also sync'd, we can avoid the sys_dcache_flush() > call when both rx/rw pointers are equal. > > Suggested-by: Richard Henderson <richard.henderson@linaro.org> > Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> > --- > Based-on: <20230605175647.88395-2-philmd@linaro.org> > --- > util/cacheflush.c | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > > diff --git a/util/cacheflush.c b/util/cacheflush.c > index de35616718..a08906155a 100644 > --- a/util/cacheflush.c > +++ b/util/cacheflush.c > @@ -241,7 +241,14 @@ static void __attribute__((constructor)) init_cache_info(void) > > void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len) > { > - sys_dcache_flush((void *)rw, len); > + if (rx == rw) { > + /* > + * sys_icache_invalidate() syncs the dcache and icache, > + * so no need to call sys_dcache_flush(). > + */ > + } else { > + sys_dcache_flush((void *)rw, len); > + } > sys_icache_invalidate((void *)rx, len); > } > #else
On 6/5/23 12:59, Philippe Mathieu-Daudé wrote: > <libkern/OSCacheControl.h> describes sys_icache_invalidate() as > "equivalent to sys_cache_control(kCacheFunctionPrepareForExecution)", > having kCacheFunctionPrepareForExecution defined as: > > /* Prepare memory for execution. This should be called > * after writing machine instructions to memory, before > * executing them. It syncs the dcache and icache. [...] > */ > > Since the dcache is also sync'd, we can avoid the sys_dcache_flush() > call when both rx/rw pointers are equal. > > Suggested-by: Richard Henderson<richard.henderson@linaro.org> > Signed-off-by: Philippe Mathieu-Daudé<philmd@linaro.org> > --- > Based-on:<20230605175647.88395-2-philmd@linaro.org> > --- > util/cacheflush.c | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) Reviewed-by: Richard Henderson <richard.henderson@linaro.org> r~
On Mon, 5 Jun 2023, Philippe Mathieu-Daudé wrote: > <libkern/OSCacheControl.h> describes sys_icache_invalidate() as > "equivalent to sys_cache_control(kCacheFunctionPrepareForExecution)", > having kCacheFunctionPrepareForExecution defined as: > > /* Prepare memory for execution. This should be called > * after writing machine instructions to memory, before > * executing them. It syncs the dcache and icache. [...] > */ > > Since the dcache is also sync'd, we can avoid the sys_dcache_flush() > call when both rx/rw pointers are equal. > > Suggested-by: Richard Henderson <richard.henderson@linaro.org> > Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> > --- > Based-on: <20230605175647.88395-2-philmd@linaro.org> > --- > util/cacheflush.c | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > > diff --git a/util/cacheflush.c b/util/cacheflush.c > index de35616718..a08906155a 100644 > --- a/util/cacheflush.c > +++ b/util/cacheflush.c > @@ -241,7 +241,14 @@ static void __attribute__((constructor)) init_cache_info(void) > > void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len) > { > - sys_dcache_flush((void *)rw, len); > + if (rx == rw) { Isn't it more straight forward to use rx != rw and drop the else branch than having an empty if branch? You can still keep the comment above the if to explain it if needed. Regards, BALATON Zoltan > + /* > + * sys_icache_invalidate() syncs the dcache and icache, > + * so no need to call sys_dcache_flush(). > + */ > + } else { > + sys_dcache_flush((void *)rw, len); > + } > sys_icache_invalidate((void *)rx, len); > } > #else >
On 5/6/23 23:56, BALATON Zoltan wrote: > On Mon, 5 Jun 2023, Philippe Mathieu-Daudé wrote: >> <libkern/OSCacheControl.h> describes sys_icache_invalidate() as >> "equivalent to sys_cache_control(kCacheFunctionPrepareForExecution)", >> having kCacheFunctionPrepareForExecution defined as: >> >> /* Prepare memory for execution. This should be called >> * after writing machine instructions to memory, before >> * executing them. It syncs the dcache and icache. [...] >> */ >> >> Since the dcache is also sync'd, we can avoid the sys_dcache_flush() >> call when both rx/rw pointers are equal. >> >> Suggested-by: Richard Henderson <richard.henderson@linaro.org> >> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> >> --- >> Based-on: <20230605175647.88395-2-philmd@linaro.org> >> --- >> util/cacheflush.c | 9 ++++++++- >> 1 file changed, 8 insertions(+), 1 deletion(-) >> >> diff --git a/util/cacheflush.c b/util/cacheflush.c >> index de35616718..a08906155a 100644 >> --- a/util/cacheflush.c >> +++ b/util/cacheflush.c >> @@ -241,7 +241,14 @@ static void __attribute__((constructor)) >> init_cache_info(void) >> >> void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len) >> { >> - sys_dcache_flush((void *)rw, len); >> + if (rx == rw) { > > Isn't it more straight forward to use rx != rw and drop the else branch > than having an empty if branch? You can still keep the comment above the > if to explain it if needed. I tried that first but found it was not obvious, so chose this form because it seemed clearer to me.
diff --git a/util/cacheflush.c b/util/cacheflush.c index de35616718..a08906155a 100644 --- a/util/cacheflush.c +++ b/util/cacheflush.c @@ -241,7 +241,14 @@ static void __attribute__((constructor)) init_cache_info(void) void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len) { - sys_dcache_flush((void *)rw, len); + if (rx == rw) { + /* + * sys_icache_invalidate() syncs the dcache and icache, + * so no need to call sys_dcache_flush(). + */ + } else { + sys_dcache_flush((void *)rw, len); + } sys_icache_invalidate((void *)rx, len); } #else
<libkern/OSCacheControl.h> describes sys_icache_invalidate() as "equivalent to sys_cache_control(kCacheFunctionPrepareForExecution)", having kCacheFunctionPrepareForExecution defined as: /* Prepare memory for execution. This should be called * after writing machine instructions to memory, before * executing them. It syncs the dcache and icache. [...] */ Since the dcache is also sync'd, we can avoid the sys_dcache_flush() call when both rx/rw pointers are equal. Suggested-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> --- Based-on: <20230605175647.88395-2-philmd@linaro.org> --- util/cacheflush.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)