[PATCH 01/18] clflush
Chris Wilson
chris at chris-wilson.co.uk
Sat Jan 2 13:20:05 UTC 2021
---
drivers/gpu/drm/drm_cache.c | 32 +++++++++++++++-----------------
1 file changed, 15 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index 0fe3c496002a..41bcf16038e2 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -36,6 +36,19 @@
#if defined(CONFIG_X86)
#include <asm/smp.h>
+static void __clflush_virt_range(void *addr, unsigned long length)
+{
+ const int size = boot_cpu_data.x86_clflush_size;
+ void *end = addr + length;
+
+ addr = (void *)(((unsigned long)addr) & -size);
+ mb(); /* CLFLUSH is only ordered with a full memory barrier */
+ for (; addr < end; addr += size)
+ clflushopt(addr);
+ clflushopt(end - 1); /* force serialisation */
+ mb(); /* Ensure that evry data cache line entry is flushed */
+}
+
/*
* clflushopt is an unordered instruction which needs fencing with mfence or
* sfence to avoid ordering issues. For drm_clflush_page this fencing happens
@@ -45,15 +58,12 @@ static void
drm_clflush_page(struct page *page)
{
uint8_t *page_virtual;
- unsigned int i;
- const int size = boot_cpu_data.x86_clflush_size;
if (unlikely(page == NULL))
return;
page_virtual = kmap_atomic(page);
- for (i = 0; i < PAGE_SIZE; i += size)
- clflushopt(page_virtual + i);
+ __clflush_virt_range(page_virtual, PAGE_SIZE);
kunmap_atomic(page_virtual);
}
@@ -62,10 +72,8 @@ static void drm_cache_flush_clflush(struct page *pages[],
{
unsigned long i;
- mb(); /*Full memory barrier used before so that CLFLUSH is ordered*/
for (i = 0; i < num_pages; i++)
drm_clflush_page(*pages++);
- mb(); /*Also used after CLFLUSH so that all cache is flushed*/
}
#endif
@@ -126,10 +134,8 @@ drm_clflush_sg(struct sg_table *st)
if (static_cpu_has(X86_FEATURE_CLFLUSH)) {
struct sg_page_iter sg_iter;
- mb(); /*CLFLUSH is ordered only by using memory barriers*/
for_each_sgtable_page(st, &sg_iter, 0)
drm_clflush_page(sg_page_iter_page(&sg_iter));
- mb(); /*Make sure that all cache line entry is flushed*/
return;
}
@@ -156,15 +162,7 @@ drm_clflush_virt_range(void *addr, unsigned long length)
{
#if defined(CONFIG_X86)
if (static_cpu_has(X86_FEATURE_CLFLUSH)) {
- const int size = boot_cpu_data.x86_clflush_size;
- void *end = addr + length;
-
- addr = (void *)(((unsigned long)addr) & -size);
- mb(); /*CLFLUSH is only ordered with a full memory barrier*/
- for (; addr < end; addr += size)
- clflushopt(addr);
- clflushopt(end - 1); /* force serialisation */
- mb(); /*Ensure that evry data cache line entry is flushed*/
+ __clflush_virt_range(addr, length);
return;
}
--
2.20.1
More information about the Intel-gfx-trybot
mailing list