Commit f255c1e9 authored by Chris Wilson's avatar Chris Wilson

drm/i915/fence: Separate timeout mechanism for awaiting on dma-fences

As the timeout mechanism has grown more and more complicated, using
multiple deferred tasks and more than doubling the size of our struct,
split the two implementations to streamline the simpler no-timeout
callback variant.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Reviewed-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180115090643.26696-2-chris@chris-wilson.co.uk
parent c32164b1
......@@ -365,18 +365,31 @@ int i915_sw_fence_await_sw_fence_gfp(struct i915_sw_fence *fence,
struct i915_sw_dma_fence_cb {
struct dma_fence_cb base;
struct i915_sw_fence *fence;
};
struct i915_sw_dma_fence_cb_timer {
struct i915_sw_dma_fence_cb base;
struct dma_fence *dma;
struct timer_list timer;
struct irq_work work;
struct rcu_head rcu;
};
static void dma_i915_sw_fence_wake(struct dma_fence *dma,
struct dma_fence_cb *data)
{
struct i915_sw_dma_fence_cb *cb = container_of(data, typeof(*cb), base);
i915_sw_fence_complete(cb->fence);
kfree(cb);
}
static void timer_i915_sw_fence_wake(struct timer_list *t)
{
struct i915_sw_dma_fence_cb *cb = from_timer(cb, t, timer);
struct i915_sw_dma_fence_cb_timer *cb = from_timer(cb, t, timer);
struct i915_sw_fence *fence;
fence = xchg(&cb->fence, NULL);
fence = xchg(&cb->base.fence, NULL);
if (!fence)
return;
......@@ -388,27 +401,24 @@ static void timer_i915_sw_fence_wake(struct timer_list *t)
i915_sw_fence_complete(fence);
}
static void dma_i915_sw_fence_wake(struct dma_fence *dma,
struct dma_fence_cb *data)
static void dma_i915_sw_fence_wake_timer(struct dma_fence *dma,
struct dma_fence_cb *data)
{
struct i915_sw_dma_fence_cb *cb = container_of(data, typeof(*cb), base);
struct i915_sw_dma_fence_cb_timer *cb =
container_of(data, typeof(*cb), base.base);
struct i915_sw_fence *fence;
fence = xchg(&cb->fence, NULL);
fence = xchg(&cb->base.fence, NULL);
if (fence)
i915_sw_fence_complete(fence);
if (cb->dma) {
irq_work_queue(&cb->work);
return;
}
kfree(cb);
irq_work_queue(&cb->work);
}
static void irq_i915_sw_fence_work(struct irq_work *wrk)
{
struct i915_sw_dma_fence_cb *cb = container_of(wrk, typeof(*cb), work);
struct i915_sw_dma_fence_cb_timer *cb =
container_of(wrk, typeof(*cb), work);
del_timer_sync(&cb->timer);
dma_fence_put(cb->dma);
......@@ -422,6 +432,7 @@ int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence,
gfp_t gfp)
{
struct i915_sw_dma_fence_cb *cb;
dma_fence_func_t func;
int ret;
debug_fence_assert(fence);
......@@ -430,7 +441,10 @@ int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence,
if (dma_fence_is_signaled(dma))
return 0;
cb = kmalloc(sizeof(*cb), gfp);
cb = kmalloc(timeout ?
sizeof(struct i915_sw_dma_fence_cb_timer) :
sizeof(struct i915_sw_dma_fence_cb),
gfp);
if (!cb) {
if (!gfpflags_allow_blocking(gfp))
return -ENOMEM;
......@@ -441,21 +455,26 @@ int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence,
cb->fence = fence;
i915_sw_fence_await(fence);
cb->dma = NULL;
func = dma_i915_sw_fence_wake;
if (timeout) {
cb->dma = dma_fence_get(dma);
init_irq_work(&cb->work, irq_i915_sw_fence_work);
struct i915_sw_dma_fence_cb_timer *timer =
container_of(cb, typeof(*timer), base);
timer_setup(&cb->timer,
timer->dma = dma_fence_get(dma);
init_irq_work(&timer->work, irq_i915_sw_fence_work);
timer_setup(&timer->timer,
timer_i915_sw_fence_wake, TIMER_IRQSAFE);
mod_timer(&cb->timer, round_jiffies_up(jiffies + timeout));
mod_timer(&timer->timer, round_jiffies_up(jiffies + timeout));
func = dma_i915_sw_fence_wake_timer;
}
ret = dma_fence_add_callback(dma, &cb->base, dma_i915_sw_fence_wake);
ret = dma_fence_add_callback(dma, &cb->base, func);
if (ret == 0) {
ret = 1;
} else {
dma_i915_sw_fence_wake(dma, &cb->base);
func(dma, &cb->base);
if (ret == -ENOENT) /* fence already signaled */
ret = 0;
}
......
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