[PATCH] guc-wb-copy

Chris Wilson chris at chris-wilson.co.uk
Tue Jan 23 09:04:42 UTC 2018


Cc: Changbin Du <changbin.du at intel.com>
Cc: Sagar Arun Kamble <sagar.a.kamble at intel.com>
---
Is what you were meant to write.
-Chris
---
 drivers/gpu/drm/i915/intel_guc_log.c | 33 +++++++++++++++++++--------------
 1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_guc_log.c b/drivers/gpu/drm/i915/intel_guc_log.c
index 2ffc966aa196..da57045e6cbd 100644
--- a/drivers/gpu/drm/i915/intel_guc_log.c
+++ b/drivers/gpu/drm/i915/intel_guc_log.c
@@ -250,6 +250,14 @@ static unsigned int guc_get_log_buffer_size(enum guc_log_buffer_type type)
 	return 0;
 }
 
+static void guc_copy_log_buffer(void *dst, void *src, unsigned long len)
+{
+	if (!i915_memcpy_from_wc(dst, src, len)) {
+		drm_clflush_virt_range(src, len);
+		memcpy(dst, src, len);
+	}
+}
+
 static void guc_read_update_log_buffer(struct intel_guc *guc)
 {
 	unsigned int buffer_size, read_offset, write_offset, bytes_to_copy, full_cnt;
@@ -323,12 +331,12 @@ static void guc_read_update_log_buffer(struct intel_guc *guc)
 
 		/* Just copy the newly written data */
 		if (read_offset > write_offset) {
-			i915_memcpy_from_wc(dst_data, src_data, write_offset);
+			guc_copy_log_buffer(dst_data, src_data, write_offset);
 			bytes_to_copy = buffer_size - read_offset;
 		} else {
 			bytes_to_copy = write_offset - read_offset;
 		}
-		i915_memcpy_from_wc(dst_data + read_offset,
+		guc_copy_log_buffer(dst_data + read_offset,
 				    src_data + read_offset, bytes_to_copy);
 
 		src_data += buffer_size;
@@ -365,6 +373,7 @@ static int guc_log_runtime_create(struct intel_guc *guc)
 	void *vaddr;
 	struct rchan *guc_log_relay_chan;
 	size_t n_subbufs, subbuf_size;
+	enum i915_map_type type;
 	int ret;
 
 	lockdep_assert_held(&dev_priv->drm.struct_mutex);
@@ -375,11 +384,16 @@ static int guc_log_runtime_create(struct intel_guc *guc)
 	if (ret)
 		return ret;
 
-	/* Create a WC (Uncached for read) vmalloc mapping of log
+	/*
+	 * Try create a WC (Uncached for read) vmalloc mapping of log
 	 * buffer pages, so that we can directly get the data
-	 * (up-to-date) from memory.
+	 * (up-to-date) from memory. Or else we will fallback to using
+	 * clflush and a WB mapping.
 	 */
-	vaddr = i915_gem_object_pin_map(guc->log.vma->obj, I915_MAP_WC);
+	type = I915_MAP_WC;
+	if (!i915_has_memcpy_from_wc())
+		type = I915_MAP_WB;
+	vaddr = i915_gem_object_pin_map(guc->log.vma->obj, type);
 	if (IS_ERR(vaddr)) {
 		DRM_ERROR("Couldn't map log buffer pages %d\n", ret);
 		return PTR_ERR(vaddr);
@@ -520,15 +534,6 @@ int intel_guc_log_create(struct intel_guc *guc)
 		GUC_LOG_ISR_PAGES + 1 +
 		GUC_LOG_CRASH_PAGES + 1) << PAGE_SHIFT;
 
-	/* We require SSE 4.1 for fast reads from the GuC log buffer and
-	 * it should be present on the chipsets supporting GuC based
-	 * submisssions.
-	 */
-	if (WARN_ON(!i915_has_memcpy_from_wc())) {
-		ret = -EINVAL;
-		goto err;
-	}
-
 	vma = intel_guc_allocate_vma(guc, size);
 	if (IS_ERR(vma)) {
 		ret = PTR_ERR(vma);
-- 
2.15.1



More information about the Intel-gfx-trybot mailing list