[PATCH 1/3] drm/nouveau: wait for moving fence after pinning
Christian König
ckoenig.leichtzumerken at gmail.com
Tue Jun 22 09:29:41 UTC 2021
Am 22.06.21 um 11:20 schrieb Daniel Vetter:
> On Mon, Jun 21, 2021 at 5:53 PM Daniel Vetter <daniel at ffwll.ch> wrote:
>> On Mon, Jun 21, 2021 at 5:49 PM Christian König
>> <ckoenig.leichtzumerken at gmail.com> wrote:
>>> Am 21.06.21 um 16:54 schrieb Daniel Vetter:
>>>> On Mon, Jun 21, 2021 at 03:03:26PM +0200, Christian König wrote:
>>>>> We actually need to wait for the moving fence after pinning
>>>>> the BO to make sure that the pin is completed.
>>>>>
>>>>> Signed-off-by: Christian König <christian.koenig at amd.com>
>>>>> CC: stable at kernel.org
>>>>> ---
>>>>> drivers/gpu/drm/nouveau/nouveau_prime.c | 8 +++++++-
>>>>> 1 file changed, 7 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c
>>>>> index 347488685f74..591738545eba 100644
>>>>> --- a/drivers/gpu/drm/nouveau/nouveau_prime.c
>>>>> +++ b/drivers/gpu/drm/nouveau/nouveau_prime.c
>>>>> @@ -93,7 +93,13 @@ int nouveau_gem_prime_pin(struct drm_gem_object *obj)
>>>>> if (ret)
>>>>> return -EINVAL;
>>>>>
>>>>> - return 0;
>>>>> + if (nvbo->bo.moving) {
>>>> Don't we need to hold the dma_resv to read this? We can grab a reference
>>>> and then unlock, but I think just unlocked wait can go boom pretty easily
>>>> (since we don't hold a reference or lock so someone else can jump in and
>>>> free the moving fence).
>>> The moving fence is only modified while the BO is moved and since we
>>> have just successfully pinned it....
>> Yeah ... so probably correct, but really tricky. Just wrapping a
>> ttm_bo_reserve/unreserve around the code you add should be enough and
>> get the job done?
> I think you distracted me a bit with the "it can't move", so yes
> there's a guarantee that no other fence can show up in ttm_bo->moving
> and confuse us. But it could get set to NULL because someone realized
> it signalled. We're not doing that systematically, but relying on
> fences never getting garbage-collected for correctness isn't great.
Yeah, that's what I essentially meant with it would be better in general
to take the lock.
>
> Sot the ttm_bo_reserve/unreserve is definitely needed here around this
> bit of code. You don't need to merge it with the reserve/unreserve in
> the pin function though, it's just to protect against the
> use-after-free.
Ah, yes good point. That means I don't need to change the pin/unpin
functions in nouveau at all.
BTW: What do you think of making dma_fence_is_signaled() and
dma_fence_wait_timeout() save to passing in NULL as fence?
I think we have a lot of cases where we check "!fence ||
dma_fence_is_signaled(fence)" or similar.
Christian.
> -Daniel
>
>>> But in general I agree that it would be better to avoid this. I just
>>> didn't wanted to open a bigger can of worms by changing nouveau so much.
>> Yeah, but I'm kinda thinking of some helpers to wait for the move
>> fence (so that later on we can switch from having the exclusive fence
>> to the move fence do that, maybe). And then locking checks in there
>> would be nice.
>>
>> Also avoids the case of explaining why lockless here is fine, but
>> lockless wait for the exclusive fence in e.g. a dynami dma-buf
>> importer is very much not fine at all. Just all around less trouble.
>> -Daniel
>>
>>> Christian.
>>>
>>>> -Daniel
>>>>
>>>>> + ret = dma_fence_wait(nvbo->bo.moving, true);
>>>>> + if (ret)
>>>>> + nouveau_bo_unpin(nvbo);
>>>>> + }
>>>>> +
>>>>> + return ret;
>>>>> }
>>>>>
>>>>> void nouveau_gem_prime_unpin(struct drm_gem_object *obj)
>>>>> --
>>>>> 2.25.1
>>>>>
>>
>> --
>> Daniel Vetter
>> Software Engineer, Intel Corporation
>> http://blog.ffwll.ch
>
>
More information about the dri-devel
mailing list