drm/nouveau: Provide a means to have arbitrary work run on fence completion.
Signed-off-by: Francisco Jerez <currojerez@riseup.net> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
2730723bbc
commit
8ac3891b48
|
@ -1243,6 +1243,9 @@ extern void nouveau_fence_update(struct nouveau_channel *);
|
||||||
extern int nouveau_fence_new(struct nouveau_channel *, struct nouveau_fence **,
|
extern int nouveau_fence_new(struct nouveau_channel *, struct nouveau_fence **,
|
||||||
bool emit);
|
bool emit);
|
||||||
extern int nouveau_fence_emit(struct nouveau_fence *);
|
extern int nouveau_fence_emit(struct nouveau_fence *);
|
||||||
|
extern void nouveau_fence_work(struct nouveau_fence *fence,
|
||||||
|
void (*work)(void *priv, bool signalled),
|
||||||
|
void *priv);
|
||||||
struct nouveau_channel *nouveau_fence_channel(struct nouveau_fence *);
|
struct nouveau_channel *nouveau_fence_channel(struct nouveau_fence *);
|
||||||
extern bool nouveau_fence_signalled(void *obj, void *arg);
|
extern bool nouveau_fence_signalled(void *obj, void *arg);
|
||||||
extern int nouveau_fence_wait(void *obj, void *arg, bool lazy, bool intr);
|
extern int nouveau_fence_wait(void *obj, void *arg, bool lazy, bool intr);
|
||||||
|
|
|
@ -39,6 +39,9 @@ struct nouveau_fence {
|
||||||
|
|
||||||
uint32_t sequence;
|
uint32_t sequence;
|
||||||
bool signalled;
|
bool signalled;
|
||||||
|
|
||||||
|
void (*work)(void *priv, bool signalled);
|
||||||
|
void *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct nouveau_fence *
|
static inline struct nouveau_fence *
|
||||||
|
@ -78,6 +81,10 @@ nouveau_fence_update(struct nouveau_channel *chan)
|
||||||
sequence = fence->sequence;
|
sequence = fence->sequence;
|
||||||
fence->signalled = true;
|
fence->signalled = true;
|
||||||
list_del(&fence->entry);
|
list_del(&fence->entry);
|
||||||
|
|
||||||
|
if (unlikely(fence->work))
|
||||||
|
fence->work(fence->priv, true);
|
||||||
|
|
||||||
kref_put(&fence->refcount, nouveau_fence_del);
|
kref_put(&fence->refcount, nouveau_fence_del);
|
||||||
|
|
||||||
if (sequence == chan->fence.sequence_ack)
|
if (sequence == chan->fence.sequence_ack)
|
||||||
|
@ -147,6 +154,25 @@ nouveau_fence_emit(struct nouveau_fence *fence)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nouveau_fence_work(struct nouveau_fence *fence,
|
||||||
|
void (*work)(void *priv, bool signalled),
|
||||||
|
void *priv)
|
||||||
|
{
|
||||||
|
BUG_ON(fence->work);
|
||||||
|
|
||||||
|
spin_lock(&fence->channel->fence.lock);
|
||||||
|
|
||||||
|
if (fence->signalled) {
|
||||||
|
work(priv, true);
|
||||||
|
} else {
|
||||||
|
fence->work = work;
|
||||||
|
fence->priv = priv;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock(&fence->channel->fence.lock);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nouveau_fence_unref(void **sync_obj)
|
nouveau_fence_unref(void **sync_obj)
|
||||||
{
|
{
|
||||||
|
@ -268,6 +294,10 @@ nouveau_fence_channel_fini(struct nouveau_channel *chan)
|
||||||
list_for_each_entry_safe(fence, tmp, &chan->fence.pending, entry) {
|
list_for_each_entry_safe(fence, tmp, &chan->fence.pending, entry) {
|
||||||
fence->signalled = true;
|
fence->signalled = true;
|
||||||
list_del(&fence->entry);
|
list_del(&fence->entry);
|
||||||
|
|
||||||
|
if (unlikely(fence->work))
|
||||||
|
fence->work(fence->priv, false);
|
||||||
|
|
||||||
kref_put(&fence->refcount, nouveau_fence_del);
|
kref_put(&fence->refcount, nouveau_fence_del);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue