Commit 38f73db7 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-fixes-2017-12-14' of...

Merge tag 'drm-intel-fixes-2017-12-14' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes

drm/i915 fixes for v4.15-rc4

* tag 'drm-intel-fixes-2017-12-14' of git://anongit.freedesktop.org/drm/drm-intel:
  drm/i915/fence: Use rcu to defer freeing of irq_work
  drm/i915: Stop listening to request resubmission from the signaler kthread
  drm/i915: Drop fb reference on load_detect_pipe failure path
  drm/i915: Flush pending GTT writes before unbinding
parents fa5cf901 2cf654db
...@@ -330,17 +330,10 @@ int i915_gem_object_unbind(struct drm_i915_gem_object *obj) ...@@ -330,17 +330,10 @@ int i915_gem_object_unbind(struct drm_i915_gem_object *obj)
* must wait for all rendering to complete to the object (as unbinding * must wait for all rendering to complete to the object (as unbinding
* must anyway), and retire the requests. * must anyway), and retire the requests.
*/ */
ret = i915_gem_object_wait(obj, ret = i915_gem_object_set_to_cpu_domain(obj, false);
I915_WAIT_INTERRUPTIBLE |
I915_WAIT_LOCKED |
I915_WAIT_ALL,
MAX_SCHEDULE_TIMEOUT,
NULL);
if (ret) if (ret)
return ret; return ret;
i915_gem_retire_requests(to_i915(obj->base.dev));
while ((vma = list_first_entry_or_null(&obj->vma_list, while ((vma = list_first_entry_or_null(&obj->vma_list,
struct i915_vma, struct i915_vma,
obj_link))) { obj_link))) {
......
...@@ -367,6 +367,7 @@ struct i915_sw_dma_fence_cb { ...@@ -367,6 +367,7 @@ struct i915_sw_dma_fence_cb {
struct dma_fence *dma; struct dma_fence *dma;
struct timer_list timer; struct timer_list timer;
struct irq_work work; struct irq_work work;
struct rcu_head rcu;
}; };
static void timer_i915_sw_fence_wake(struct timer_list *t) static void timer_i915_sw_fence_wake(struct timer_list *t)
...@@ -406,7 +407,7 @@ static void irq_i915_sw_fence_work(struct irq_work *wrk) ...@@ -406,7 +407,7 @@ static void irq_i915_sw_fence_work(struct irq_work *wrk)
del_timer_sync(&cb->timer); del_timer_sync(&cb->timer);
dma_fence_put(cb->dma); dma_fence_put(cb->dma);
kfree(cb); kfree_rcu(cb, rcu);
} }
int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence, int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence,
......
...@@ -186,7 +186,7 @@ void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine) ...@@ -186,7 +186,7 @@ void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine)
struct intel_wait *wait, *n, *first; struct intel_wait *wait, *n, *first;
if (!b->irq_armed) if (!b->irq_armed)
return; goto wakeup_signaler;
/* We only disarm the irq when we are idle (all requests completed), /* We only disarm the irq when we are idle (all requests completed),
* so if the bottom-half remains asleep, it missed the request * so if the bottom-half remains asleep, it missed the request
...@@ -208,6 +208,14 @@ void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine) ...@@ -208,6 +208,14 @@ void intel_engine_disarm_breadcrumbs(struct intel_engine_cs *engine)
b->waiters = RB_ROOT; b->waiters = RB_ROOT;
spin_unlock_irq(&b->rb_lock); spin_unlock_irq(&b->rb_lock);
/*
* The signaling thread may be asleep holding a reference to a request,
* that had its signaling cancelled prior to being preempted. We need
* to kick the signaler, just in case, to release any such reference.
*/
wakeup_signaler:
wake_up_process(b->signaler);
} }
static bool use_fake_irq(const struct intel_breadcrumbs *b) static bool use_fake_irq(const struct intel_breadcrumbs *b)
...@@ -651,23 +659,15 @@ static int intel_breadcrumbs_signaler(void *arg) ...@@ -651,23 +659,15 @@ static int intel_breadcrumbs_signaler(void *arg)
} }
if (unlikely(do_schedule)) { if (unlikely(do_schedule)) {
DEFINE_WAIT(exec);
if (kthread_should_park()) if (kthread_should_park())
kthread_parkme(); kthread_parkme();
if (kthread_should_stop()) { if (unlikely(kthread_should_stop())) {
GEM_BUG_ON(request); i915_gem_request_put(request);
break; break;
} }
if (request)
add_wait_queue(&request->execute, &exec);
schedule(); schedule();
if (request)
remove_wait_queue(&request->execute, &exec);
} }
i915_gem_request_put(request); i915_gem_request_put(request);
} while (1); } while (1);
......
...@@ -9944,11 +9944,10 @@ int intel_get_load_detect_pipe(struct drm_connector *connector, ...@@ -9944,11 +9944,10 @@ int intel_get_load_detect_pipe(struct drm_connector *connector,
} }
ret = intel_modeset_setup_plane_state(state, crtc, mode, fb, 0, 0); ret = intel_modeset_setup_plane_state(state, crtc, mode, fb, 0, 0);
drm_framebuffer_put(fb);
if (ret) if (ret)
goto fail; goto fail;
drm_framebuffer_put(fb);
ret = drm_atomic_set_mode_for_crtc(&crtc_state->base, mode); ret = drm_atomic_set_mode_for_crtc(&crtc_state->base, mode);
if (ret) if (ret)
goto fail; goto fail;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment