[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