util/cacheflush.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
<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
--
2.38.1
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.
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~
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
© 2016 - 2024 Red Hat, Inc.