diff mbox

dma-buf/fence-array: get signaled state when signaling is disabled

Message ID 1474457767-26195-1-git-send-email-gustavo@padovan.org (mailing list archive)
State New, archived
Headers show

Commit Message

Gustavo Padovan Sept. 21, 2016, 11:36 a.m. UTC
From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

If the fences in the fence_array signal on the fence_array does not have
signalling enabled num_pending will not be updated accordingly.

So when signaling is disabled check the signal of every fence with
fence_is_signaled() and then compare with num_pending to learn if the
fence_array was signalled or not.

If we want to keep the poll_does_not_wait optimization I think we need
something like this. It keeps the same behaviour if signalling is enabled
but tries to calculated the state otherwise.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/dma-buf/fence-array.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

Comments

Christian König Sept. 21, 2016, 6:47 p.m. UTC | #1
Am 21.09.2016 um 13:36 schrieb Gustavo Padovan:
> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
>
> If the fences in the fence_array signal on the fence_array does not have
> signalling enabled num_pending will not be updated accordingly.
>
> So when signaling is disabled check the signal of every fence with
> fence_is_signaled() and then compare with num_pending to learn if the
> fence_array was signalled or not.
>
> If we want to keep the poll_does_not_wait optimization I think we need
> something like this. It keeps the same behaviour if signalling is enabled
> but tries to calculated the state otherwise.
>
> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>

First of all the patch is horrible wrong because fence_array_signaled() 
is called without any locks held. So you can run into a race condition 
between checking the fences here and enable signaling.

Additional to that I'm not sure if that is such a good idea or not, 
cause fence_array_signaled() should be light weight and without calling 
enable_signaling there is not guarantee that fences will ever signal.

Regards,
Christian.

> ---
>   drivers/dma-buf/fence-array.c | 19 ++++++++++++++++++-
>   1 file changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dma-buf/fence-array.c b/drivers/dma-buf/fence-array.c
> index f1989fc..1eec271 100644
> --- a/drivers/dma-buf/fence-array.c
> +++ b/drivers/dma-buf/fence-array.c
> @@ -75,8 +75,25 @@ static bool fence_array_enable_signaling(struct fence *fence)
>   static bool fence_array_signaled(struct fence *fence)
>   {
>   	struct fence_array *array = to_fence_array(fence);
> +	int i, num_pending;
> +
> +	num_pending = atomic_read(&array->num_pending);
> +
> +	/*
> +	 * Before signaling is enabled, num_pending is static (set during array
> +	 * construction as a count of all fences or set to 1 if signal_on_any
> +	 * flag is passed. To ensure forward progress, i.e. a while
> +	 * (!fence_is_signaled()) ; busy-loop eventually proceeds, we need to
> +	 * check the current status of our fences.
> +	 */
> +	if (!test_bit(FENCE_FLAG_ENABLE_SIGNAL_BIT, &fence->flags)) {
> +		for (i = 0 ; i < array->num_fences; ++i) {
> +			if (fence_is_signaled(array->fences[i]))
> +				num_pending--;
> +		}
> +	}
>   
> -	return atomic_read(&array->num_pending) <= 0;
> +	return num_pending <= 0;
>   }
>   
>   static void fence_array_release(struct fence *fence)
Chunming Zhou Sept. 22, 2016, 1:59 a.m. UTC | #2
On 2016年09月21日 19:36, Gustavo Padovan wrote:
> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
>
> If the fences in the fence_array signal on the fence_array does not have
> signalling enabled num_pending will not be updated accordingly.
>
> So when signaling is disabled check the signal of every fence with
> fence_is_signaled() and then compare with num_pending to learn if the
> fence_array was signalled or not.
>
> If we want to keep the poll_does_not_wait optimization I think we need
> something like this. It keeps the same behaviour if signalling is enabled
> but tries to calculated the state otherwise.
>
> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Chunming Zhou <david1.zhou@amd.com>

Regards,
David Zhou
> ---
>   drivers/dma-buf/fence-array.c | 19 ++++++++++++++++++-
>   1 file changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dma-buf/fence-array.c b/drivers/dma-buf/fence-array.c
> index f1989fc..1eec271 100644
> --- a/drivers/dma-buf/fence-array.c
> +++ b/drivers/dma-buf/fence-array.c
> @@ -75,8 +75,25 @@ static bool fence_array_enable_signaling(struct fence *fence)
>   static bool fence_array_signaled(struct fence *fence)
>   {
>   	struct fence_array *array = to_fence_array(fence);
> +	int i, num_pending;
> +
> +	num_pending = atomic_read(&array->num_pending);
> +
> +	/*
> +	 * Before signaling is enabled, num_pending is static (set during array
> +	 * construction as a count of all fences or set to 1 if signal_on_any
> +	 * flag is passed. To ensure forward progress, i.e. a while
> +	 * (!fence_is_signaled()) ; busy-loop eventually proceeds, we need to
> +	 * check the current status of our fences.
> +	 */
> +	if (!test_bit(FENCE_FLAG_ENABLE_SIGNAL_BIT, &fence->flags)) {
> +		for (i = 0 ; i < array->num_fences; ++i) {
> +			if (fence_is_signaled(array->fences[i]))
> +				num_pending--;
> +		}
> +	}
>   
> -	return atomic_read(&array->num_pending) <= 0;
> +	return num_pending <= 0;
>   }
>   
>   static void fence_array_release(struct fence *fence)
Gustavo Padovan Sept. 22, 2016, 7:44 a.m. UTC | #3
Hi Christian,

2016-09-21 Christian König <christian.koenig@amd.com>:

> Am 21.09.2016 um 13:36 schrieb Gustavo Padovan:
> > From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> > 
> > If the fences in the fence_array signal on the fence_array does not have
> > signalling enabled num_pending will not be updated accordingly.
> > 
> > So when signaling is disabled check the signal of every fence with
> > fence_is_signaled() and then compare with num_pending to learn if the
> > fence_array was signalled or not.
> > 
> > If we want to keep the poll_does_not_wait optimization I think we need
> > something like this. It keeps the same behaviour if signalling is enabled
> > but tries to calculated the state otherwise.
> > 
> > Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> > Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
> 
> First of all the patch is horrible wrong because fence_array_signaled() is
> called without any locks held. So you can run into a race condition between
> checking the fences here and enable signaling.

Yes. it can, but I don't think the race condition is actually a problem.
Maybe you have some use case that we are not seeing?
 
> Additional to that I'm not sure if that is such a good idea or not, cause
> fence_array_signaled() should be light weight and without calling
> enable_signaling there is not guarantee that fences will ever signal.

It is still lightweight for the case when signaling is enabled and
fences can signal with signaling enabled or disabled so I don't see that
as problem too.

Gustavo
Christian König Sept. 22, 2016, 8:05 a.m. UTC | #4
Am 22.09.2016 um 09:44 schrieb Gustavo Padovan:
> Hi Christian,
>
> 2016-09-21 Christian König <christian.koenig@amd.com>:
>
>> Am 21.09.2016 um 13:36 schrieb Gustavo Padovan:
>>> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
>>>
>>> If the fences in the fence_array signal on the fence_array does not have
>>> signalling enabled num_pending will not be updated accordingly.
>>>
>>> So when signaling is disabled check the signal of every fence with
>>> fence_is_signaled() and then compare with num_pending to learn if the
>>> fence_array was signalled or not.
>>>
>>> If we want to keep the poll_does_not_wait optimization I think we need
>>> something like this. It keeps the same behaviour if signalling is enabled
>>> but tries to calculated the state otherwise.
>>>
>>> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
>>> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
>> First of all the patch is horrible wrong because fence_array_signaled() is
>> called without any locks held. So you can run into a race condition between
>> checking the fences here and enable signaling.
> Yes. it can, but I don't think the race condition is actually a problem.
> Maybe you have some use case that we are not seeing?

I'm not sure if that can really race, but if it does the check would 
return true while not all necessary fences are signaled yet.

That would be really really bad for things like TTM where we just do a 
quick check in the page fault handler for example.

I need to double check if that really could be a problem.

>> Additional to that I'm not sure if that is such a good idea or not, cause
>> fence_array_signaled() should be light weight and without calling
>> enable_signaling there is not guarantee that fences will ever signal.
> It is still lightweight for the case when signaling is enabled and
> fences can signal with signaling enabled or disabled
Nope that's not correct. The signaled callback is only optional.

See the comment on the fence_is_signaled function:
>  * Returns true if the fence was already signaled, false if not. Since 
> this
>  * function doesn't enable signaling, it is not guaranteed to ever return
>  * true if fence_add_callback, fence_wait or fence_enable_sw_signaling
>  * haven't been called before.

E.g. for example it is illegal to do something like 
"while(!fence_is_signaled(f)) sleep();" without enabling signaling 
before doing this.

Could just be a misunderstanding, but the comments on your patch 
actually sounds a bit like somebody is trying to do exactly that.

Regards,
Christian.

>   so I don't see that
> as problem too.
>
> Gustavo
>
Gustavo Padovan Sept. 22, 2016, 10:40 a.m. UTC | #5
2016-09-22 Christian König <christian.koenig@amd.com>:

> Am 22.09.2016 um 09:44 schrieb Gustavo Padovan:
> > Hi Christian,
> > 
> > 2016-09-21 Christian König <christian.koenig@amd.com>:
> > 
> > > Am 21.09.2016 um 13:36 schrieb Gustavo Padovan:
> > > > From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> > > > 
> > > > If the fences in the fence_array signal on the fence_array does not have
> > > > signalling enabled num_pending will not be updated accordingly.
> > > > 
> > > > So when signaling is disabled check the signal of every fence with
> > > > fence_is_signaled() and then compare with num_pending to learn if the
> > > > fence_array was signalled or not.
> > > > 
> > > > If we want to keep the poll_does_not_wait optimization I think we need
> > > > something like this. It keeps the same behaviour if signalling is enabled
> > > > but tries to calculated the state otherwise.
> > > > 
> > > > Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> > > > Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
> > > First of all the patch is horrible wrong because fence_array_signaled() is
> > > called without any locks held. So you can run into a race condition between
> > > checking the fences here and enable signaling.
> > Yes. it can, but I don't think the race condition is actually a problem.
> > Maybe you have some use case that we are not seeing?
> 
> I'm not sure if that can really race, but if it does the check would return
> true while not all necessary fences are signaled yet.

How? If signaling is disabled num_pending is equal to the number of
fences (or 1 if signal_on_any) then we just check all fences. If all of
them are signaled then num_pending will be zero.

> 
> That would be really really bad for things like TTM where we just do a quick
> check in the page fault handler for example.
> 
> I need to double check if that really could be a problem.
> 
> > > Additional to that I'm not sure if that is such a good idea or not, cause
> > > fence_array_signaled() should be light weight and without calling
> > > enable_signaling there is not guarantee that fences will ever signal.
> > It is still lightweight for the case when signaling is enabled and
> > fences can signal with signaling enabled or disabled
> Nope that's not correct. The signaled callback is only optional.
> 
> See the comment on the fence_is_signaled function:
> >  * Returns true if the fence was already signaled, false if not. Since
> > this
> >  * function doesn't enable signaling, it is not guaranteed to ever return
> >  * true if fence_add_callback, fence_wait or fence_enable_sw_signaling
> >  * haven't been called before.

Right, I was with explicit fencing in mind, we only enable signaling
there if userspace polls.

> E.g. for example it is illegal to do something like
> "while(!fence_is_signaled(f)) sleep();" without enabling signaling before
> doing this.
> 
> Could just be a misunderstanding, but the comments on your patch actually
> sounds a bit like somebody is trying to do exactly that.

I think the usecase in mind here is poll(fd, timeout=0)

Gustavo
Christian König Sept. 22, 2016, 11 a.m. UTC | #6
Dropping the rest of the patch, cause that really doesn't make sense any 
more.

Am 22.09.2016 um 12:40 schrieb Gustavo Padovan:
>> E.g. for example it is illegal to do something like
>> >"while(!fence_is_signaled(f)) sleep();" without enabling signaling before
>> >doing this.
>> >
>> >Could just be a misunderstanding, but the comments on your patch actually
>> >sounds a bit like somebody is trying to do exactly that.
> I think the usecase in mind here is poll(fd, timeout=0)

Exactly as I feared. Even if userspace polls with timeout=0 you still 
need to call enable_signaling().

Otherwise you can run into a situation where userspace only uses 
timeout=0 and so never activates the signaling check in the driver.

This would in turn result in an endless loop on implementations where 
the driver never signals fences on their own.

Regards,
Christian.
Gustavo Padovan Sept. 22, 2016, 11:16 a.m. UTC | #7
2016-09-22 Christian König <christian.koenig@amd.com>:

> Dropping the rest of the patch, cause that really doesn't make sense any
> more.
> 
> Am 22.09.2016 um 12:40 schrieb Gustavo Padovan:
> > > E.g. for example it is illegal to do something like
> > > >"while(!fence_is_signaled(f)) sleep();" without enabling signaling before
> > > >doing this.
> > > >
> > > >Could just be a misunderstanding, but the comments on your patch actually
> > > >sounds a bit like somebody is trying to do exactly that.
> > I think the usecase in mind here is poll(fd, timeout=0)
> 
> Exactly as I feared. Even if userspace polls with timeout=0 you still need
> to call enable_signaling().
> 
> Otherwise you can run into a situation where userspace only uses timeout=0
> and so never activates the signaling check in the driver.
> 
> This would in turn result in an endless loop on implementations where the
> driver never signals fences on their own.

Polling is optional, userspace may never call it. And DRM/KMS or GPU            
drivers will be doing fence_wait() themselves so signaling is enabled at        
some point. 

Gustavo
Christian König Sept. 22, 2016, 2:11 p.m. UTC | #8
Am 22.09.2016 um 13:16 schrieb Gustavo Padovan:
> 2016-09-22 Christian König <christian.koenig@amd.com>:
>
>> Dropping the rest of the patch, cause that really doesn't make sense any
>> more.
>>
>> Am 22.09.2016 um 12:40 schrieb Gustavo Padovan:
>>>> E.g. for example it is illegal to do something like
>>>>> "while(!fence_is_signaled(f)) sleep();" without enabling signaling before
>>>>> doing this.
>>>>>
>>>>> Could just be a misunderstanding, but the comments on your patch actually
>>>>> sounds a bit like somebody is trying to do exactly that.
>>> I think the usecase in mind here is poll(fd, timeout=0)
>> Exactly as I feared. Even if userspace polls with timeout=0 you still need
>> to call enable_signaling().
>>
>> Otherwise you can run into a situation where userspace only uses timeout=0
>> and so never activates the signaling check in the driver.
>>
>> This would in turn result in an endless loop on implementations where the
>> driver never signals fences on their own.
> Polling is optional, userspace may never call it. And DRM/KMS or GPU
> drivers will be doing fence_wait() themselves so signaling is enabled at
> some point.

No they won't. We have an use case where we clearly want to avoid that 
as much as possible because and so the driver never calls 
enable_signaling() on it's own.

Exposing this poll function to userspace without enabling signaling is a 
clear NAK from my side.

Christian.

>
> Gustavo
>
Christian König Sept. 22, 2016, 2:12 p.m. UTC | #9
Am 22.09.2016 um 16:11 schrieb Christian König:
> Am 22.09.2016 um 13:16 schrieb Gustavo Padovan:
>> 2016-09-22 Christian König <christian.koenig@amd.com>:
>>
>>> Dropping the rest of the patch, cause that really doesn't make sense 
>>> any
>>> more.
>>>
>>> Am 22.09.2016 um 12:40 schrieb Gustavo Padovan:
>>>>> E.g. for example it is illegal to do something like
>>>>>> "while(!fence_is_signaled(f)) sleep();" without enabling 
>>>>>> signaling before
>>>>>> doing this.
>>>>>>
>>>>>> Could just be a misunderstanding, but the comments on your patch 
>>>>>> actually
>>>>>> sounds a bit like somebody is trying to do exactly that.
>>>> I think the usecase in mind here is poll(fd, timeout=0)
>>> Exactly as I feared. Even if userspace polls with timeout=0 you 
>>> still need
>>> to call enable_signaling().
>>>
>>> Otherwise you can run into a situation where userspace only uses 
>>> timeout=0
>>> and so never activates the signaling check in the driver.
>>>
>>> This would in turn result in an endless loop on implementations 
>>> where the
>>> driver never signals fences on their own.
>> Polling is optional, userspace may never call it. And DRM/KMS or GPU
>> drivers will be doing fence_wait() themselves so signaling is enabled at
>> some point.
>
> No they won't. We have an use case where we clearly want to avoid that 
> as much as possible because and so the driver never calls 
> enable_signaling() on it's own.

Sorry hitting send to soon. That should read "because of the extreme 
overhead".

Christian.

>
> Exposing this poll function to userspace without enabling signaling is 
> a clear NAK from my side.
>
> Christian.
>
>>
>> Gustavo
>>
>
Gustavo Padovan Sept. 23, 2016, 11:30 a.m. UTC | #10
2016-09-22 Christian König <christian.koenig@amd.com>:

> Am 22.09.2016 um 13:16 schrieb Gustavo Padovan:
> > 2016-09-22 Christian König <christian.koenig@amd.com>:
> > 
> > > Dropping the rest of the patch, cause that really doesn't make sense any
> > > more.
> > > 
> > > Am 22.09.2016 um 12:40 schrieb Gustavo Padovan:
> > > > > E.g. for example it is illegal to do something like
> > > > > > "while(!fence_is_signaled(f)) sleep();" without enabling signaling before
> > > > > > doing this.
> > > > > > 
> > > > > > Could just be a misunderstanding, but the comments on your patch actually
> > > > > > sounds a bit like somebody is trying to do exactly that.
> > > > I think the usecase in mind here is poll(fd, timeout=0)
> > > Exactly as I feared. Even if userspace polls with timeout=0 you still need
> > > to call enable_signaling().
> > > 
> > > Otherwise you can run into a situation where userspace only uses timeout=0
> > > and so never activates the signaling check in the driver.
> > > 
> > > This would in turn result in an endless loop on implementations where the
> > > driver never signals fences on their own.
> > Polling is optional, userspace may never call it. And DRM/KMS or GPU
> > drivers will be doing fence_wait() themselves so signaling is enabled at
> > some point.
> 
> No they won't. We have an use case where we clearly want to avoid that as
> much as possible because and so the driver never calls enable_signaling() on
> it's own.
> 
> Exposing this poll function to userspace without enabling signaling is a
> clear NAK from my side.

Okay. So you are NAK'ing the does_not_pool_wait change. Should we revert
that one then? It is already broken.

Gustavo
Christian König Sept. 23, 2016, 1:47 p.m. UTC | #11
Am 23.09.2016 um 13:30 schrieb Gustavo Padovan:
> 2016-09-22 Christian König <christian.koenig@amd.com>:
>
>> Am 22.09.2016 um 13:16 schrieb Gustavo Padovan:
>>> 2016-09-22 Christian König <christian.koenig@amd.com>:
>>>
>>>> Dropping the rest of the patch, cause that really doesn't make sense any
>>>> more.
>>>>
>>>> Am 22.09.2016 um 12:40 schrieb Gustavo Padovan:
>>>>>> E.g. for example it is illegal to do something like
>>>>>>> "while(!fence_is_signaled(f)) sleep();" without enabling signaling before
>>>>>>> doing this.
>>>>>>>
>>>>>>> Could just be a misunderstanding, but the comments on your patch actually
>>>>>>> sounds a bit like somebody is trying to do exactly that.
>>>>> I think the usecase in mind here is poll(fd, timeout=0)
>>>> Exactly as I feared. Even if userspace polls with timeout=0 you still need
>>>> to call enable_signaling().
>>>>
>>>> Otherwise you can run into a situation where userspace only uses timeout=0
>>>> and so never activates the signaling check in the driver.
>>>>
>>>> This would in turn result in an endless loop on implementations where the
>>>> driver never signals fences on their own.
>>> Polling is optional, userspace may never call it. And DRM/KMS or GPU
>>> drivers will be doing fence_wait() themselves so signaling is enabled at
>>> some point.
>> No they won't. We have an use case where we clearly want to avoid that as
>> much as possible because and so the driver never calls enable_signaling() on
>> it's own.
>>
>> Exposing this poll function to userspace without enabling signaling is a
>> clear NAK from my side.
> Okay. So you are NAK'ing the does_not_pool_wait change. Should we revert
> that one then? It is already broken.

Yeah, that would probably a good idea. The AMD driver changes which 
really rely on this aren't upstream yet, so if you point me to the 
commit hash I could revert that as well when we send that out.

On the other hand the idea behind fence_is_signaled() is really that you 
check the status multiple times after enabling signaling. So I would 
prefer if you would revert this change preliminary.

Double checking this patch (and thinking about it a bit more) reveals 
that it is most likely correct. So feel free to commit this one if it is 
still needed for something.

Regards,
Christian.

>
> Gustavo
>
Gustavo Padovan Sept. 25, 2016, 8:43 p.m. UTC | #12
2016-09-23 Christian König <christian.koenig@amd.com>:

> Am 23.09.2016 um 13:30 schrieb Gustavo Padovan:
> > 2016-09-22 Christian König <christian.koenig@amd.com>:
> > 
> > > Am 22.09.2016 um 13:16 schrieb Gustavo Padovan:
> > > > 2016-09-22 Christian König <christian.koenig@amd.com>:
> > > > 
> > > > > Dropping the rest of the patch, cause that really doesn't make sense any
> > > > > more.
> > > > > 
> > > > > Am 22.09.2016 um 12:40 schrieb Gustavo Padovan:
> > > > > > > E.g. for example it is illegal to do something like
> > > > > > > > "while(!fence_is_signaled(f)) sleep();" without enabling signaling before
> > > > > > > > doing this.
> > > > > > > > 
> > > > > > > > Could just be a misunderstanding, but the comments on your patch actually
> > > > > > > > sounds a bit like somebody is trying to do exactly that.
> > > > > > I think the usecase in mind here is poll(fd, timeout=0)
> > > > > Exactly as I feared. Even if userspace polls with timeout=0 you still need
> > > > > to call enable_signaling().
> > > > > 
> > > > > Otherwise you can run into a situation where userspace only uses timeout=0
> > > > > and so never activates the signaling check in the driver.
> > > > > 
> > > > > This would in turn result in an endless loop on implementations where the
> > > > > driver never signals fences on their own.
> > > > Polling is optional, userspace may never call it. And DRM/KMS or GPU
> > > > drivers will be doing fence_wait() themselves so signaling is enabled at
> > > > some point.
> > > No they won't. We have an use case where we clearly want to avoid that as
> > > much as possible because and so the driver never calls enable_signaling() on
> > > it's own.
> > > 
> > > Exposing this poll function to userspace without enabling signaling is a
> > > clear NAK from my side.
> > Okay. So you are NAK'ing the does_not_pool_wait change. Should we revert
> > that one then? It is already broken.
> 
> Yeah, that would probably a good idea. The AMD driver changes which really
> rely on this aren't upstream yet, so if you point me to the commit hash I
> could revert that as well when we send that out.
> 
> On the other hand the idea behind fence_is_signaled() is really that you
> check the status multiple times after enabling signaling. So I would prefer
> if you would revert this change preliminary.
> 
> Double checking this patch (and thinking about it a bit more) reveals that
> it is most likely correct. So feel free to commit this one if it is still
> needed for something.

It is this patch:

ecebca7 dma-buf/sync-file: Avoid enable fence signaling if poll(.timeout=0)

But if we revert it as you are a proposing we don't need my patch here
anymore. However we would need to revert it now because it is broken.
Shall I send a revert part?

Gustavo
diff mbox

Patch

diff --git a/drivers/dma-buf/fence-array.c b/drivers/dma-buf/fence-array.c
index f1989fc..1eec271 100644
--- a/drivers/dma-buf/fence-array.c
+++ b/drivers/dma-buf/fence-array.c
@@ -75,8 +75,25 @@  static bool fence_array_enable_signaling(struct fence *fence)
 static bool fence_array_signaled(struct fence *fence)
 {
 	struct fence_array *array = to_fence_array(fence);
+	int i, num_pending;
+
+	num_pending = atomic_read(&array->num_pending);
+
+	/*
+	 * Before signaling is enabled, num_pending is static (set during array
+	 * construction as a count of all fences or set to 1 if signal_on_any
+	 * flag is passed. To ensure forward progress, i.e. a while
+	 * (!fence_is_signaled()) ; busy-loop eventually proceeds, we need to
+	 * check the current status of our fences.
+	 */
+	if (!test_bit(FENCE_FLAG_ENABLE_SIGNAL_BIT, &fence->flags)) {
+		for (i = 0 ; i < array->num_fences; ++i) {
+			if (fence_is_signaled(array->fences[i]))
+				num_pending--;
+		}
+	}
 
-	return atomic_read(&array->num_pending) <= 0;
+	return num_pending <= 0;
 }
 
 static void fence_array_release(struct fence *fence)