mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-25 21:54:06 +08:00
gpu: host1x: Remove cancelled waiters immediately
Before this patch, cancelled waiters would only be cleaned up once their threshold value was reached. Make host1x_intr_put_ref process the cancellation immediately to fix this. Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
parent
49a5fb1679
commit
ecfb888ade
@ -242,18 +242,29 @@ int host1x_intr_add_action(struct host1x *host, struct host1x_syncpt *syncpt,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void host1x_intr_put_ref(struct host1x *host, unsigned int id, void *ref)
|
||||
void host1x_intr_put_ref(struct host1x *host, unsigned int id, void *ref,
|
||||
bool flush)
|
||||
{
|
||||
struct host1x_waitlist *waiter = ref;
|
||||
struct host1x_syncpt *syncpt;
|
||||
|
||||
while (atomic_cmpxchg(&waiter->state, WLS_PENDING, WLS_CANCELLED) ==
|
||||
WLS_REMOVED)
|
||||
schedule();
|
||||
atomic_cmpxchg(&waiter->state, WLS_PENDING, WLS_CANCELLED);
|
||||
|
||||
syncpt = host->syncpt + id;
|
||||
(void)process_wait_list(host, syncpt,
|
||||
host1x_syncpt_load(host->syncpt + id));
|
||||
|
||||
spin_lock(&syncpt->intr.lock);
|
||||
if (atomic_cmpxchg(&waiter->state, WLS_CANCELLED, WLS_HANDLED) ==
|
||||
WLS_CANCELLED) {
|
||||
list_del(&waiter->list);
|
||||
kref_put(&waiter->refcount, waiter_release);
|
||||
}
|
||||
spin_unlock(&syncpt->intr.lock);
|
||||
|
||||
if (flush) {
|
||||
/* Wait until any concurrently executing handler has finished. */
|
||||
while (atomic_read(&waiter->state) != WLS_HANDLED)
|
||||
schedule();
|
||||
}
|
||||
|
||||
kref_put(&waiter->refcount, waiter_release);
|
||||
}
|
||||
|
@ -74,8 +74,10 @@ int host1x_intr_add_action(struct host1x *host, struct host1x_syncpt *syncpt,
|
||||
* Unreference an action submitted to host1x_intr_add_action().
|
||||
* You must call this if you passed non-NULL as ref.
|
||||
* @ref the ref returned from host1x_intr_add_action()
|
||||
* @flush wait until any pending handlers have completed before returning.
|
||||
*/
|
||||
void host1x_intr_put_ref(struct host1x *host, unsigned int id, void *ref);
|
||||
void host1x_intr_put_ref(struct host1x *host, unsigned int id, void *ref,
|
||||
bool flush);
|
||||
|
||||
/* Initialize host1x sync point interrupt */
|
||||
int host1x_intr_init(struct host1x *host, unsigned int irq_sync);
|
||||
|
@ -308,7 +308,7 @@ int host1x_syncpt_wait(struct host1x_syncpt *sp, u32 thresh, long timeout,
|
||||
}
|
||||
}
|
||||
|
||||
host1x_intr_put_ref(sp->host, sp->id, ref);
|
||||
host1x_intr_put_ref(sp->host, sp->id, ref, true);
|
||||
|
||||
done:
|
||||
return err;
|
||||
|
Loading…
Reference in New Issue
Block a user