Quoting Tvrtko Ursulin (2018-02-05 13:23:54)
>
> On 03/02/2018 10:19, Chris Wilson wrote:
> > @@ -656,41 +705,21 @@ static int intel_breadcrumbs_signaler(void *arg)
> > * a new client.
> > */
> > rcu_read_lock();
> > - request = rcu_dereference(b->first_signal);
> > - if (request)
> > - request = i915_gem_request_get_rcu(request);
> > + request = get_first_signal_rcu(b);
> > rcu_read_unlock();
> > if (signal_complete(request)) {
> > - local_bh_disable();
> > - dma_fence_signal(&request->fence);
> > - local_bh_enable(); /* kick start the tasklets */
> > -
> > - spin_lock_irq(&b->rb_lock);
> > -
> > - /* Wake up all other completed waiters and select the
> > - * next bottom-half for the next user interrupt.
> > - */
> > - __intel_engine_remove_wait(engine,
> > - &request->signaling.wait);
> > -
> > - /* Find the next oldest signal. Note that as we have
> > - * not been holding the lock, another client may
> > - * have installed an even older signal than the one
> > - * we just completed - so double check we are still
> > - * the oldest before picking the next one.
> > - */
> > - if (request == rcu_access_pointer(b->first_signal)) {
> > - struct rb_node *rb =
> > - rb_next(&request->signaling.node);
> > - rcu_assign_pointer(b->first_signal,
> > - rb ? to_signaler(rb) :
> > NULL);
> > + if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
> > + &request->fence.flags)) {
> > + local_bh_disable();
> > + dma_fence_signal(&request->fence);
> > + local_bh_enable(); /* kick start the tasklets
> > */
> > }
> > - rb_erase(&request->signaling.node, &b->signals);
> > - RB_CLEAR_NODE(&request->signaling.node);
> > -
> > - spin_unlock_irq(&b->rb_lock);
> >
> > - i915_gem_request_put(request);
> > + if (READ_ONCE(request->signaling.wait.seqno)) {
> > + spin_lock_irq(&b->rb_lock);
> > + __intel_engine_remove_signal(engine, request);
> > + spin_unlock_irq(&b->rb_lock);
> > + }
>
> How would you view taking the request->lock over this block in the
> signaler and then being able to call simply
> intel_engine_cancel_signaling - ending up with very similar code as in
> i915_gem_request_retire?
I am not keen on the conflation here (maybe it's just a hatred of bool
parameters). But at first glance it's just the commonality of
remove_signal, which is already a common routine?
> Only difference would be the tasklet kicking, but maybe still it would
> be possible to consolidate the two in one helper.
>
> __i915_gem_request_retire_signaling(req, bool kick_tasklets)
> {
> if (!DMA_FENCE_FLAG_SIGNALED_BIT) {
> dma_fence_signal_locked(...);
> if (kick_tasklets) {
> local_bh_disable();
> local_bh_enable();
> }
We can't kick the tasklet inside a spinlock. Especially not a lockclass
as nested as request.lock :(
-Chris
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx