Quoting Chris Wilson (2019-08-15 20:03:13) > Quoting Daniel Vetter (2019-08-15 19:48:42) > > On Thu, Aug 15, 2019 at 8:46 PM Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> wrote: > > > Quoting Daniel Vetter (2019-08-14 18:20:53) > > > > On Sun, Aug 11, 2019 at 10:15:23AM +0100, Chris Wilson wrote: > > > > > Now that dma_fence_signal always takes the spinlock to flush the > > > > > cb_list, simply take the spinlock and call dma_fence_signal_locked() to > > > > > avoid code repetition. > > > > > > > > > > Suggested-by: Christian König <christian.koenig@xxxxxxx> > > > > > Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> > > > > > Cc: Christian König <christian.koenig@xxxxxxx> > > > > > > > > Hm, I think this largely defeats the point of having the lockless signal > > > > enabling trickery in dma_fence. Maybe that part isn't needed by anyone, > > > > but feels like a thing that needs a notch more thought. And if we need it, > > > > maybe a bit more cleanup. > > > > > > You mean dma_fence_enable_sw_signaling(). The only user appears to be to > > > flush fences, which is actually the intent of always notifying the signal > > > cb. By always doing the callbacks, we can avoid installing the interrupt > > > and completely saturating CPUs with irqs, instead doing a batch in a > > > leisurely timer callback if not flushed naturally. > > > > Yeah I'm not against ditching this, > > I was just thinking aloud working out what the current use case in ttm > was for. > > > but can't we ditch a lot more if > > we just always take the spinlock in those paths now anyways? Kinda not > > worth having the complexity anymore. > > You would be able to drop the was_set from dma_fence_add_callback. Say > > diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c > index 59ac96ec7ba8..e566445134a2 100644 > --- a/drivers/dma-buf/dma-fence.c > +++ b/drivers/dma-buf/dma-fence.c > @@ -345,38 +345,31 @@ int dma_fence_add_callback(struct dma_fence *fence, struct dma_fence_cb *cb, > dma_fence_func_t func) > { > unsigned long flags; > - int ret = 0; > - bool was_set; > + int ret = -ENOENT; > > if (WARN_ON(!fence || !func)) > return -EINVAL; > > - if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) { > - INIT_LIST_HEAD(&cb->node); > + INIT_LIST_HEAD(&cb->node); > + cb->func = func; > + > + if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) > return -ENOENT; > - } > > spin_lock_irqsave(fence->lock, flags); > - > - was_set = test_and_set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, > - &fence->flags); > - > - if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) > - ret = -ENOENT; > - else if (!was_set && fence->ops->enable_signaling) { > + if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags) && > + !test_and_set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, > + &fence->flags)) { > trace_dma_fence_enable_signal(fence); > > - if (!fence->ops->enable_signaling(fence)) { > + if (!fence->ops->enable_signaling || > + fence->ops->enable_signaling(fence)) { > + list_add_tail(&cb->node, &fence->cb_list); > + ret = 0; > + } else { > dma_fence_signal_locked(fence); > - ret = -ENOENT; > } > } > - > - if (!ret) { > - cb->func = func; > - list_add_tail(&cb->node, &fence->cb_list); > - } else > - INIT_LIST_HEAD(&cb->node); > spin_unlock_irqrestore(fence->lock, flags); > > return ret; > > Not a whole lot changes in terms of branches and serialising > instructions. One less baffling sequence to worry about. Fwiw, Function old new delta dma_fence_add_callback 338 302 -36 Almost certainly more shaving if you stare. -Chris _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel