[Mesa-dev] [PATCH] i965: Set the batch threshold based on the GTT size

Chris Wilson chris at chris-wilson.co.uk
Sat May 26 16:47:53 UTC 2018


The limit to the working set of a single batch is the amount we can fit
into the GTT. The GTT is a per-context address space, so query the
context rather than use an estimate based on the legacy global aperture.
Futhermore, we can fine tune our soft-limit based on the knowledge of
whether we are sharing the GTT with other clients.
---
 src/mesa/drivers/dri/i965/intel_screen.c | 55 +++++++++++++++++++++---
 1 file changed, 49 insertions(+), 6 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c
index e6d49b94268..a7e0c20c9ca 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -1420,15 +1420,58 @@ static const __DRIimageExtension intelImageExtension = {
     .queryDmaBufFormatModifierAttribs   = intel_query_format_modifier_attribs,
 };
 
+static int
+gem_param(int fd, int name)
+{
+   int v = -1; /* No param uses (yet) the sign bit, reserve it for errors */
+
+   struct drm_i915_getparam gp = { .param = name, .value = &v };
+   if (drmIoctl(fd, DRM_IOCTL_I915_GETPARAM, &gp))
+      return -1;
+
+   return v;
+}
+
+static int
+gem_context_getparam(int fd, uint32_t context, uint64_t param, uint64_t *value)
+{
+   struct drm_i915_gem_context_param gp = {
+      .ctx_id = context,
+      .param = param,
+   };
+
+   if (drmIoctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, &gp))
+      return -1;
+
+   *value = gp.value;
+
+   return 0;
+}
+
 static uint64_t
-get_aperture_size(int fd)
+get_batch_threshold(int fd)
 {
-   struct drm_i915_gem_get_aperture aperture;
+   uint64_t gtt_size;
+
+   /* I915_CONTEXT_PARAM_GTT_SIZE was introduced in kernel v4.5. Prior to that
+    * be cautious and assume that we only have the smallest 256MiB GTT.
+    * This is a soft-limit we use to flush the batch before it grows too large
+    * and tries to claim the entire system for itself. (It is still allowed
+    * to use as much as it requires of the GTT for a single primitive call,
+    * with the caveat that it may fail if we cannot fit it all in.)
+    */
+   if (gem_context_getparam(fd, 0, I915_CONTEXT_PARAM_GTT_SIZE, &gtt_size))
+      gtt_size = 256 << 20;
 
-   if (drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture) != 0)
-      return 0;
+   /* If we have to share the GTT with other clients, be conservative and
+    * set ourselves a lower soft-limit so we emit batches more often to avoid
+    * having multiple clients compete for hogging the entire system to
+    * themselves.
+    */
+   if (gem_param(fd, I915_PARAM_HAS_ALIASING_PPGTT) < 2)
+      gtt_size /= 2;
 
-   return aperture.aper_size;
+   return 3 * gtt_size / 4;
 }
 
 static int
@@ -2482,7 +2525,7 @@ __DRIconfig **intelInitScreen2(__DRIscreen *dri_screen)
       screen->max_gtt_map_object_size = gtt_size / 4;
    }
 
-   screen->aperture_threshold = get_aperture_size(dri_screen->fd) * 3 / 4;
+   screen->aperture_threshold = get_batch_threshold(dri_screen->fd);
 
    screen->hw_has_swizzling = intel_detect_swizzling(screen);
    screen->hw_has_timestamp = intel_detect_timestamp(screen);
-- 
2.17.0



More information about the mesa-dev mailing list