diff options
author | Maarten Lankhorst <maarten.lankhorst@linux.intel.com> | 2015-08-18 07:40:06 -0400 |
---|---|---|
committer | Maarten Lankhorst <maarten.lankhorst@linux.intel.com> | 2015-11-02 09:50:31 -0500 |
commit | 7580d774b0466fff28aab19db4f36dac37a3d1a9 (patch) | |
tree | 9b5024b8be800450c9bd1f26d9691b165faba675 /drivers/gpu/drm/i915/intel_display.c | |
parent | f935675f0c07f87da2facc4c144d511e6da48240 (diff) |
drm/i915: Wait for object idle without locks in atomic_commit, v2.
Make pinning and waiting a separate step, and wait for object idle
without struct_mutex held.
Changes since v1:
- Do not wait when a reset is in progress.
- Remove call to i915_gem_object_wait_rendering for
intel_overlay_do_put_image (Chris Wilson)
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 82 |
1 files changed, 69 insertions, 13 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8393759782d0..2e5164265250 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -2320,9 +2320,7 @@ static unsigned int intel_linear_alignment(struct drm_i915_private *dev_priv) | |||
2320 | int | 2320 | int |
2321 | intel_pin_and_fence_fb_obj(struct drm_plane *plane, | 2321 | intel_pin_and_fence_fb_obj(struct drm_plane *plane, |
2322 | struct drm_framebuffer *fb, | 2322 | struct drm_framebuffer *fb, |
2323 | const struct drm_plane_state *plane_state, | 2323 | const struct drm_plane_state *plane_state) |
2324 | struct intel_engine_cs *pipelined, | ||
2325 | struct drm_i915_gem_request **pipelined_request) | ||
2326 | { | 2324 | { |
2327 | struct drm_device *dev = fb->dev; | 2325 | struct drm_device *dev = fb->dev; |
2328 | struct drm_i915_private *dev_priv = dev->dev_private; | 2326 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -2378,8 +2376,8 @@ intel_pin_and_fence_fb_obj(struct drm_plane *plane, | |||
2378 | */ | 2376 | */ |
2379 | intel_runtime_pm_get(dev_priv); | 2377 | intel_runtime_pm_get(dev_priv); |
2380 | 2378 | ||
2381 | ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined, | 2379 | ret = i915_gem_object_pin_to_display_plane(obj, alignment, |
2382 | pipelined_request, &view); | 2380 | &view); |
2383 | if (ret) | 2381 | if (ret) |
2384 | goto err_pm; | 2382 | goto err_pm; |
2385 | 2383 | ||
@@ -11426,9 +11424,14 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
11426 | * synchronisation, so all we want here is to pin the framebuffer | 11424 | * synchronisation, so all we want here is to pin the framebuffer |
11427 | * into the display plane and skip any waits. | 11425 | * into the display plane and skip any waits. |
11428 | */ | 11426 | */ |
11427 | if (!mmio_flip) { | ||
11428 | ret = i915_gem_object_sync(obj, ring, &request); | ||
11429 | if (ret) | ||
11430 | goto cleanup_pending; | ||
11431 | } | ||
11432 | |||
11429 | ret = intel_pin_and_fence_fb_obj(crtc->primary, fb, | 11433 | ret = intel_pin_and_fence_fb_obj(crtc->primary, fb, |
11430 | crtc->primary->state, | 11434 | crtc->primary->state); |
11431 | mmio_flip ? i915_gem_request_get_ring(obj->last_write_req) : ring, &request); | ||
11432 | if (ret) | 11435 | if (ret) |
11433 | goto cleanup_pending; | 11436 | goto cleanup_pending; |
11434 | 11437 | ||
@@ -13150,7 +13153,10 @@ static int intel_atomic_prepare_commit(struct drm_device *dev, | |||
13150 | struct drm_atomic_state *state, | 13153 | struct drm_atomic_state *state, |
13151 | bool async) | 13154 | bool async) |
13152 | { | 13155 | { |
13156 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
13157 | struct drm_plane_state *plane_state; | ||
13153 | struct drm_crtc_state *crtc_state; | 13158 | struct drm_crtc_state *crtc_state; |
13159 | struct drm_plane *plane; | ||
13154 | struct drm_crtc *crtc; | 13160 | struct drm_crtc *crtc; |
13155 | int i, ret; | 13161 | int i, ret; |
13156 | 13162 | ||
@@ -13163,6 +13169,9 @@ static int intel_atomic_prepare_commit(struct drm_device *dev, | |||
13163 | ret = intel_crtc_wait_for_pending_flips(crtc); | 13169 | ret = intel_crtc_wait_for_pending_flips(crtc); |
13164 | if (ret) | 13170 | if (ret) |
13165 | return ret; | 13171 | return ret; |
13172 | |||
13173 | if (atomic_read(&to_intel_crtc(crtc)->unpin_work_count) >= 2) | ||
13174 | flush_workqueue(dev_priv->wq); | ||
13166 | } | 13175 | } |
13167 | 13176 | ||
13168 | ret = mutex_lock_interruptible(&dev->struct_mutex); | 13177 | ret = mutex_lock_interruptible(&dev->struct_mutex); |
@@ -13170,6 +13179,37 @@ static int intel_atomic_prepare_commit(struct drm_device *dev, | |||
13170 | return ret; | 13179 | return ret; |
13171 | 13180 | ||
13172 | ret = drm_atomic_helper_prepare_planes(dev, state); | 13181 | ret = drm_atomic_helper_prepare_planes(dev, state); |
13182 | if (!ret && !async && !i915_reset_in_progress(&dev_priv->gpu_error)) { | ||
13183 | u32 reset_counter; | ||
13184 | |||
13185 | reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter); | ||
13186 | mutex_unlock(&dev->struct_mutex); | ||
13187 | |||
13188 | for_each_plane_in_state(state, plane, plane_state, i) { | ||
13189 | struct intel_plane_state *intel_plane_state = | ||
13190 | to_intel_plane_state(plane_state); | ||
13191 | |||
13192 | if (!intel_plane_state->wait_req) | ||
13193 | continue; | ||
13194 | |||
13195 | ret = __i915_wait_request(intel_plane_state->wait_req, | ||
13196 | reset_counter, true, | ||
13197 | NULL, NULL); | ||
13198 | |||
13199 | /* Swallow -EIO errors to allow updates during hw lockup. */ | ||
13200 | if (ret == -EIO) | ||
13201 | ret = 0; | ||
13202 | |||
13203 | if (ret) | ||
13204 | break; | ||
13205 | } | ||
13206 | |||
13207 | if (!ret) | ||
13208 | return 0; | ||
13209 | |||
13210 | mutex_lock(&dev->struct_mutex); | ||
13211 | drm_atomic_helper_cleanup_planes(dev, state); | ||
13212 | } | ||
13173 | 13213 | ||
13174 | mutex_unlock(&dev->struct_mutex); | 13214 | mutex_unlock(&dev->struct_mutex); |
13175 | return ret; | 13215 | return ret; |
@@ -13196,15 +13236,17 @@ static int intel_atomic_commit(struct drm_device *dev, | |||
13196 | bool async) | 13236 | bool async) |
13197 | { | 13237 | { |
13198 | struct drm_i915_private *dev_priv = dev->dev_private; | 13238 | struct drm_i915_private *dev_priv = dev->dev_private; |
13199 | struct drm_crtc *crtc; | ||
13200 | struct drm_crtc_state *crtc_state; | 13239 | struct drm_crtc_state *crtc_state; |
13240 | struct drm_crtc *crtc; | ||
13201 | int ret = 0; | 13241 | int ret = 0; |
13202 | int i; | 13242 | int i; |
13203 | bool any_ms = false; | 13243 | bool any_ms = false; |
13204 | 13244 | ||
13205 | ret = intel_atomic_prepare_commit(dev, state, async); | 13245 | ret = intel_atomic_prepare_commit(dev, state, async); |
13206 | if (ret) | 13246 | if (ret) { |
13247 | DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret); | ||
13207 | return ret; | 13248 | return ret; |
13249 | } | ||
13208 | 13250 | ||
13209 | drm_atomic_helper_swap_state(dev, state); | 13251 | drm_atomic_helper_swap_state(dev, state); |
13210 | dev_priv->wm.config = to_intel_atomic_state(state)->wm_config; | 13252 | dev_priv->wm.config = to_intel_atomic_state(state)->wm_config; |
@@ -13495,11 +13537,20 @@ intel_prepare_plane_fb(struct drm_plane *plane, | |||
13495 | if (ret) | 13537 | if (ret) |
13496 | DRM_DEBUG_KMS("failed to attach phys object\n"); | 13538 | DRM_DEBUG_KMS("failed to attach phys object\n"); |
13497 | } else { | 13539 | } else { |
13498 | ret = intel_pin_and_fence_fb_obj(plane, fb, new_state, NULL, NULL); | 13540 | ret = intel_pin_and_fence_fb_obj(plane, fb, new_state); |
13499 | } | 13541 | } |
13500 | 13542 | ||
13501 | if (ret == 0) | 13543 | if (ret == 0) { |
13544 | if (obj) { | ||
13545 | struct intel_plane_state *plane_state = | ||
13546 | to_intel_plane_state(new_state); | ||
13547 | |||
13548 | i915_gem_request_assign(&plane_state->wait_req, | ||
13549 | obj->last_write_req); | ||
13550 | } | ||
13551 | |||
13502 | i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit); | 13552 | i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit); |
13553 | } | ||
13503 | 13554 | ||
13504 | return ret; | 13555 | return ret; |
13505 | } | 13556 | } |
@@ -13519,9 +13570,12 @@ intel_cleanup_plane_fb(struct drm_plane *plane, | |||
13519 | { | 13570 | { |
13520 | struct drm_device *dev = plane->dev; | 13571 | struct drm_device *dev = plane->dev; |
13521 | struct intel_plane *intel_plane = to_intel_plane(plane); | 13572 | struct intel_plane *intel_plane = to_intel_plane(plane); |
13573 | struct intel_plane_state *old_intel_state; | ||
13522 | struct drm_i915_gem_object *old_obj = intel_fb_obj(old_state->fb); | 13574 | struct drm_i915_gem_object *old_obj = intel_fb_obj(old_state->fb); |
13523 | struct drm_i915_gem_object *obj = intel_fb_obj(plane->state->fb); | 13575 | struct drm_i915_gem_object *obj = intel_fb_obj(plane->state->fb); |
13524 | 13576 | ||
13577 | old_intel_state = to_intel_plane_state(old_state); | ||
13578 | |||
13525 | if (!obj && !old_obj) | 13579 | if (!obj && !old_obj) |
13526 | return; | 13580 | return; |
13527 | 13581 | ||
@@ -13533,6 +13587,9 @@ intel_cleanup_plane_fb(struct drm_plane *plane, | |||
13533 | if ((old_obj && (old_obj->frontbuffer_bits & intel_plane->frontbuffer_bit)) || | 13587 | if ((old_obj && (old_obj->frontbuffer_bits & intel_plane->frontbuffer_bit)) || |
13534 | (obj && !(obj->frontbuffer_bits & intel_plane->frontbuffer_bit))) | 13588 | (obj && !(obj->frontbuffer_bits & intel_plane->frontbuffer_bit))) |
13535 | i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit); | 13589 | i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit); |
13590 | |||
13591 | i915_gem_request_assign(&old_intel_state->wait_req, NULL); | ||
13592 | |||
13536 | } | 13593 | } |
13537 | 13594 | ||
13538 | int | 13595 | int |
@@ -15498,8 +15555,7 @@ void intel_modeset_gem_init(struct drm_device *dev) | |||
15498 | mutex_lock(&dev->struct_mutex); | 15555 | mutex_lock(&dev->struct_mutex); |
15499 | ret = intel_pin_and_fence_fb_obj(c->primary, | 15556 | ret = intel_pin_and_fence_fb_obj(c->primary, |
15500 | c->primary->fb, | 15557 | c->primary->fb, |
15501 | c->primary->state, | 15558 | c->primary->state); |
15502 | NULL, NULL); | ||
15503 | mutex_unlock(&dev->struct_mutex); | 15559 | mutex_unlock(&dev->struct_mutex); |
15504 | if (ret) { | 15560 | if (ret) { |
15505 | DRM_ERROR("failed to pin boot fb on pipe %d\n", | 15561 | DRM_ERROR("failed to pin boot fb on pipe %d\n", |