FAILED: patch "[PATCH] drm/i915: Late request cancellations are harmful" failed to apply to 4.6-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 4.6-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
aa9b78104fe3210758fa9e6c644e9a108d371e8bMon Sep 17 00:00:00 2001
From: Chris Wilson <[email protected]>
Date: Wed, 13 Apr 2016 17:35:15 +0100
Subject: [PATCH] drm/i915: Late request cancellations are harmful
Conceptually, each request is a record of a hardware transaction - we build up a list of pending commands and then either commit them to hardware, or cancel them. However, whilst building up the list of pending commands, we may modify state outside of the request and make references to the pending request. If we do so and then cancel that request, external objects then point to the deleted request leading to both graphical and memory corruption.
The easiest example is to consider object/VMA tracking. When we mark an object as active in a request, we store a pointer to this, the most recent request, in the object. Then we want to free that object, we wait for the most recent request to be idle before proceeding (otherwise the hardware will write to pages now owned by the system, or we will attempt to read from those pages before the hardware is finished writing). If the request was cancelled instead, that wait completes immediately. As a result, all requests must be committed and not cancelled if the external state is unknown.
All that remains of i915_gem_request_cancel() users are just a couple of extremely unlikely allocation failures, so remove the API entirely.
A consequence of committing all incomplete requests is that we generate excess breadcrumbs and fill the ring much more often with dummy work. We have completely undone the outstanding_last_seqno optimisation.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93907
drivers/gpu/drm/i915/i915_drv.h +0 -2
@@ -2331,7 +2331,6 @@ struct drm_i915_gem_request {struct drm_i915_gem_request *__must_check i915_gem_request_alloc (struct intel_engine_cs *engine,struct intel_context *ctx); -void i915_gem_request_cancel (struct drm_i915_gem_request *req);void i915_gem_request_free (struct kref *req_ref);int i915_gem_request_add_to_client (struct drm_i915_gem_request *req,struct drm_file *file);
@@ -2888,7 +2887,6 @@ int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);void i915_gem_execbuffer_move_to_active (struct list_head *vmas,struct drm_i915_gem_request *req); -void i915_gem_execbuffer_retire_commands (struct i915_execbuffer_params *params);int i915_gem_ringbuffer_submission (struct i915_execbuffer_params *params,struct drm_i915_gem_execbuffer2 *args,struct list_head *vmas);
drivers/gpu/drm/i915/i915_gem.c +20 -30
86 lines not on this page · raw message
drivers/gpu/drm/i915/i915_gem_execbuffer.c +4 -11
@@ -1137,7 +1137,7 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas, } } -void +static void i915_gem_execbuffer_retire_commands (struct i915_execbuffer_params *params) {/* Unconditionally force add_request to emit a full flush. */
@@ -1322,7 +1322,6 @@ i915_gem_ringbuffer_submission(struct i915_execbuffer_params *params,trace_i915_gem_ring_dispatch (params->request, params->dispatch_flags);i915_gem_execbuffer_move_to_active (vmas, params->request); -i915_gem_execbuffer_retire_commands (params);return 0 ; }
@@ -1624,7 +1623,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, ret =i915_gem_request_add_to_client (req, file);if (ret) - goto err_batch_unpin; + goto err_request;/* * Save assorted stuff away to pass through to *_submission().
@@ -1641,6 +1640,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, params->request = req; ret = dev_priv->gt.execbuf_submit (params, args, &eb->vmas); +err_request: +i915_gem_execbuffer_retire_commands (params); err_batch_unpin:/*
@@ -1657,14 +1658,6 @@ err:i915_gem_context_unreference (ctx);eb_destroy (eb); -/* -* If the request was created but not successfully submitted then it -* must be freed again. If it was submitted then it is being tracked -* on the active request list and no clean up is required here. -*/ -if (ret && !IS_ERR_OR_NULL (req)) -i915_gem_request_cancel (req); -mutex_unlock (&dev->struct_mutex); pre_mutex_err:
drivers/gpu/drm/i915/intel_display.c +1 -1
@@ -11664,7 +11664,7 @@ cleanup_unpin:intel_unpin_fb_obj (fb, crtc->primary->state->rotation); cleanup_pending:if (!IS_ERR_OR_NULL (request)) -i915_gem_request_cancel (request); +i915_add_request_no_flush (request);atomic_dec (&intel_crtc->unpin_work_count);mutex_unlock (&dev->struct_mutex); cleanup:
drivers/gpu/drm/i915/intel_lrc.c +1 -3
@@ -1007,7 +1007,6 @@ int intel_execlists_submission(struct i915_execbuffer_params *params,trace_i915_gem_ring_dispatch (params->request, params->dispatch_flags);i915_gem_execbuffer_move_to_active (vmas, params->request); -i915_gem_execbuffer_retire_commands (params);return 0 ; }
@@ -2700,13 +2699,12 @@ int intel_lr_context_deferred_alloc(struct intel_context *ctx, } ret = engine->init_context (req); +i915_add_request_no_flush (req);if (ret) {DRM_ERROR ("ring init context: %d\n" , ret); -i915_gem_request_cancel (req); goto error_ringbuf; } -i915_add_request_no_flush (req); }return 0 ;
drivers/gpu/drm/i915/intel_overlay.c +4 -4
@@ -247,7 +247,7 @@ static int intel_overlay_on(struct intel_overlay *overlay) ret =intel_ring_begin (req,4 );if (ret) { -i915_gem_request_cancel (req); +i915_add_request_no_flush (req);return ret; }
@@ -290,7 +290,7 @@ static int intel_overlay_continue(struct intel_overlay *overlay, ret =intel_ring_begin (req,2 );if (ret) { -i915_gem_request_cancel (req); +i915_add_request_no_flush (req);return ret; }
@@ -356,7 +356,7 @@ static int intel_overlay_off(struct intel_overlay *overlay) ret =intel_ring_begin (req,6 );if (ret) { -i915_gem_request_cancel (req); +i915_add_request_no_flush (req);return ret; }
@@ -431,7 +431,7 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay) ret =intel_ring_begin (req,2 );if (ret) { -i915_gem_request_cancel (req); +i915_add_request_no_flush (req);return ret; }