[Intel-gfx] [PATCH] drm/i915: Use the LLC mode on gen6 for everything but display.

Zou, Nanhai nanhai.zou at intel.com
Fri Mar 11 21:47:23 CET 2011


Like we have discussed.
I think set FB uncached, batch buffer and ring buffer LLC cached.
everything else LLC+MLC cached may get the best performance.

Thanks
Zou Nanhai
________________________________________
From: intel-gfx-bounces+nanhai.zou=intel.com at lists.freedesktop.org [intel-gfx-bounces+nanhai.zou=intel.com at lists.freedesktop.org] On Behalf Of Eric Anholt [eric at anholt.net]
Sent: Friday, March 11, 2011 1:11 PM
To: intel-gfx at lists.freedesktop.org
Subject: [Intel-gfx] [PATCH] drm/i915: Use the LLC mode on gen6 for     everything but display.

This provided a 10.4% +/- 1.5% (n=3) performance improvement on
openarena on my laptop.  We have more room to improve with doing LLC
caching for display using GFDT, and in doing LLC+MLC caching, but this
was an easy performance win and incremental improvement toward those
two.

Signed-off-by: Eric Anholt <eric at anholt.net>
---

Just wrote this and tested it this morning.  Testing was rough, as
just starting with 2.6.38-rc8+patfix, I had a bunch of:

[  156.985125] [drm:drm_crtc_helper_set_config] *ERROR* failed to set mode on [CRTC:3]

and thus broken display, though I'm on a preproduction machine still
so I'm less worried than I would otherwise be.

Can anyone think of anything but display and cursors that would be
incoherent with LLC?

 drivers/gpu/drm/i915/i915_gem.c      |   18 +++++++++++-
 drivers/gpu/drm/i915/intel_display.c |   51 ++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 36e66cc..f4f6de3 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3539,7 +3539,23 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
        obj->base.write_domain = I915_GEM_DOMAIN_CPU;
        obj->base.read_domains = I915_GEM_DOMAIN_CPU;

-       obj->agp_type = AGP_USER_MEMORY;
+       if (IS_GEN6(dev)) {
+               /* On Gen6, we can have the GPU use the LLC (the CPU
+                * cache) for about a 10% performance improvement
+                * compared to uncached.  Graphics requests other than
+                * display scanout are coherent with the CPU in
+                * accessing this cache.  This means in this mode we
+                * don't need to clflush on the CPU side, and on the
+                * GPU side we only need to flush internal caches to
+                * get data visible to the CPU.
+                *
+                * For display, see intel_pin_and_fence_fb_obj() for
+                * how we handle changing the caching.
+                */
+               obj->agp_type = AGP_USER_CACHED_MEMORY;
+       } else {
+               obj->agp_type = AGP_USER_MEMORY;
+       }
        obj->base.driver_private = NULL;
        obj->fence_reg = I915_FENCE_REG_NONE;
        INIT_LIST_HEAD(&obj->mm_list);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 49fb54f..0b3096a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1456,6 +1456,45 @@ out_disable:
        }
 }

+/* The display engine is not coherent with the LLC cache on gen6.  As
+ * a result, we make sure that the pinning that is about to occur is
+ * done with uncached PTEs.
+ *
+ * We could do this better in a couple of ways.  The most important
+ * would be to use the GFDT bit instead of uncaching, which would
+ * allow us to flush all the LLC-cached data with that bit in the PTE
+ * to main memory with just one PIPE_CONTROL.  The other would be to
+ * update the PTEs by calling i915_gem_gtt_bind_object() and then
+ * flush any existing CPU cache of the object, instead of unbinding.
+ */
+static int
+i915_set_pte_uncached(struct drm_i915_gem_object *obj)
+{
+       int ret;
+
+       if (obj->agp_type == AGP_USER_MEMORY)
+               return 0;
+
+       obj->agp_type = AGP_USER_MEMORY;
+
+       if (obj->pin_count > 0) {
+               static int once = 0;
+               if (!once) {
+                       DRM_ERROR("Trying to change caching on pinned fb\n");
+                       once = 1;
+               }
+               return -EBUSY;
+       }
+
+       ret = i915_gem_object_unbind(obj);
+       if (ret)
+               return ret;
+
+       obj->agp_type = AGP_USER_MEMORY;
+
+       return 0;
+}
+
 int
 intel_pin_and_fence_fb_obj(struct drm_device *dev,
                           struct drm_i915_gem_object *obj,
@@ -1485,6 +1524,12 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev,
                BUG();
        }

+       if (IS_GEN6(dev)) {
+               ret = i915_set_pte_uncached(obj);
+               if (ret)
+                       return ret;
+       }
+
        ret = i915_gem_object_pin(obj, alignment, true);
        if (ret)
                return ret;
@@ -4740,6 +4785,12 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
                        goto fail_locked;
                }

+               if (IS_GEN6(dev)) {
+                       ret = i915_set_pte_uncached(obj);
+                       if (ret)
+                               goto fail_locked;
+               }
+
                ret = i915_gem_object_pin(obj, PAGE_SIZE, true);
                if (ret) {
                        DRM_ERROR("failed to pin cursor bo\n");
--
1.7.4.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx



More information about the Intel-gfx mailing list