drm/i915: Allow fence allocations to fail
authorChris Wilson <chris@chris-wilson.co.uk>
Tue, 12 Dec 2017 18:06:51 +0000 (18:06 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Wed, 13 Dec 2017 13:17:44 +0000 (13:17 +0000)
If a fence allocation fails in a blocking context, we will sleep on the
fence as a last resort. We can therefore allow ourselves to fail and
sleep on the fence instead of triggering a system-wide oom. This allows
us to throttle malicious clients that are consuming lots of system
resources by capping the amount of memory used by fences.

Testcase: igt/gem_shrink/execbufX
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20171212180652.22061-2-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/i915_gem_clflush.c
drivers/gpu/drm/i915/i915_gem_context.c
drivers/gpu/drm/i915/i915_gem_request.c
drivers/gpu/drm/i915/i915_gem_request.h

index f663cd9197954e0e24590b7374391566df2eb899..b9b53ac141766bd941d5fcb677801f5ce14e37db 100644 (file)
@@ -167,7 +167,7 @@ bool i915_gem_clflush_object(struct drm_i915_gem_object *obj,
                i915_sw_fence_await_reservation(&clflush->wait,
                                                obj->resv, NULL,
                                                true, I915_FENCE_TIMEOUT,
-                                               GFP_KERNEL);
+                                               I915_FENCE_GFP);
 
                reservation_object_lock(obj->resv, NULL);
                reservation_object_add_excl_fence(obj->resv, &clflush->dma);
index 21ce374d9924fbbaa5a67297a3bec8a8806ada5a..648e7536ff51e0eae1365971293ab150f72d9956 100644 (file)
@@ -617,7 +617,7 @@ int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv)
                        if (prev)
                                i915_sw_fence_await_sw_fence_gfp(&req->submit,
                                                                 &prev->submit,
-                                                                GFP_KERNEL);
+                                                                I915_FENCE_GFP);
                }
 
                /*
index c28a4ceb016df2daa949db31805213aec2620182..4d5e2b7143826498db4f210d7daa40bcf0195e5b 100644 (file)
@@ -782,7 +782,7 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to,
        if (to->engine == from->engine) {
                ret = i915_sw_fence_await_sw_fence_gfp(&to->submit,
                                                       &from->submit,
-                                                      GFP_KERNEL);
+                                                      I915_FENCE_GFP);
                return ret < 0 ? ret : 0;
        }
 
@@ -810,7 +810,7 @@ i915_gem_request_await_request(struct drm_i915_gem_request *to,
 await_dma_fence:
        ret = i915_sw_fence_await_dma_fence(&to->submit,
                                            &from->fence, 0,
-                                           GFP_KERNEL);
+                                           I915_FENCE_GFP);
        return ret < 0 ? ret : 0;
 }
 
@@ -861,7 +861,7 @@ i915_gem_request_await_dma_fence(struct drm_i915_gem_request *req,
                else
                        ret = i915_sw_fence_await_dma_fence(&req->submit, fence,
                                                            I915_FENCE_TIMEOUT,
-                                                           GFP_KERNEL);
+                                                           I915_FENCE_GFP);
                if (ret < 0)
                        return ret;
 
index 26249f39de67eb84c144703c83540ec853ac9969..0d6d39f19506d9cc71d9c228b34708bcef8567be 100644 (file)
@@ -204,6 +204,8 @@ struct drm_i915_gem_request {
        struct list_head client_link;
 };
 
+#define I915_FENCE_GFP (GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN)
+
 extern const struct dma_fence_ops i915_fence_ops;
 
 static inline bool dma_fence_is_i915(const struct dma_fence *fence)