From: "Christian König" <christian.koenig@amd.com>
To: Danilo Krummrich <dakr@redhat.com>,
airlied@gmail.com, daniel@ffwll.ch, tzimmermann@suse.de,
mripard@kernel.org, corbet@lwn.net, bskeggs@redhat.com,
Liam.Howlett@oracle.com, matthew.brost@intel.com,
boris.brezillon@collabora.com, alexdeucher@gmail.com,
ogabbay@kernel.org, bagasdotme@gmail.com, willy@infradead.org,
jason@jlekstrand.net, donald.robson@imgtec.com
Cc: dri-devel@lists.freedesktop.org, nouveau@lists.freedesktop.org,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH drm-misc-next v9 06/11] drm/nouveau: fence: separate fence alloc and emit
Date: Tue, 8 Aug 2023 08:06:46 +0200 [thread overview]
Message-ID: <fa6e771f-39fa-5e1e-b062-a9a4c3182852@amd.com> (raw)
In-Reply-To: <619cbc61-d40f-a19f-179d-1ae35a1a17d4@redhat.com>
Am 07.08.23 um 20:54 schrieb Danilo Krummrich:
> Hi Christian,
>
> On 8/7/23 20:07, Christian König wrote:
>> Am 03.08.23 um 18:52 schrieb Danilo Krummrich:
>>> The new (VM_BIND) UAPI exports DMA fences through DRM syncobjs. Hence,
>>> in order to emit fences within DMA fence signalling critical sections
>>> (e.g. as typically done in the DRM GPU schedulers run_job()
>>> callback) we
>>> need to separate fence allocation and fence emitting.
>>
>> At least from the description that sounds like it might be illegal.
>> Daniel can you take a look as well.
>>
>> What exactly are you doing here?
>
> I'm basically doing exactly the same as amdgpu_fence_emit() does in
> amdgpu_ib_schedule() called by amdgpu_job_run().
>
> The difference - and this is what this patch is for - is that I
> separate the fence allocation from emitting the fence, such that the
> fence structure is allocated before the job is submitted to the GPU
> scheduler. amdgpu solves this with GFP_ATOMIC within
> amdgpu_fence_emit() to allocate the fence structure in this case.
Yeah, that use case is perfectly valid. Maybe update the commit message
a bit to better describe that.
Something like "Separate fence allocation and emitting to avoid
allocation within DMA fence signalling critical sections inside the DRM
scheduler. This helps implementing the new UAPI....".
Regards,
Christian.
>
> - Danilo
>
>>
>> Regards,
>> Christian.
>>
>>>
>>> Signed-off-by: Danilo Krummrich <dakr@redhat.com>
>>> ---
>>> drivers/gpu/drm/nouveau/dispnv04/crtc.c | 9 ++++-
>>> drivers/gpu/drm/nouveau/nouveau_bo.c | 52
>>> +++++++++++++++----------
>>> drivers/gpu/drm/nouveau/nouveau_chan.c | 6 ++-
>>> drivers/gpu/drm/nouveau/nouveau_dmem.c | 9 +++--
>>> drivers/gpu/drm/nouveau/nouveau_fence.c | 16 +++-----
>>> drivers/gpu/drm/nouveau/nouveau_fence.h | 3 +-
>>> drivers/gpu/drm/nouveau/nouveau_gem.c | 5 ++-
>>> 7 files changed, 59 insertions(+), 41 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c
>>> b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
>>> index a6f2e681bde9..a34924523133 100644
>>> --- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c
>>> +++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
>>> @@ -1122,11 +1122,18 @@ nv04_page_flip_emit(struct nouveau_channel
>>> *chan,
>>> PUSH_NVSQ(push, NV_SW, NV_SW_PAGE_FLIP, 0x00000000);
>>> PUSH_KICK(push);
>>> - ret = nouveau_fence_new(chan, false, pfence);
>>> + ret = nouveau_fence_new(pfence);
>>> if (ret)
>>> goto fail;
>>> + ret = nouveau_fence_emit(*pfence, chan);
>>> + if (ret)
>>> + goto fail_fence_unref;
>>> +
>>> return 0;
>>> +
>>> +fail_fence_unref:
>>> + nouveau_fence_unref(pfence);
>>> fail:
>>> spin_lock_irqsave(&dev->event_lock, flags);
>>> list_del(&s->head);
>>> diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c
>>> b/drivers/gpu/drm/nouveau/nouveau_bo.c
>>> index 057bc995f19b..e9cbbf594e6f 100644
>>> --- a/drivers/gpu/drm/nouveau/nouveau_bo.c
>>> +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
>>> @@ -820,29 +820,39 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object
>>> *bo, int evict,
>>> mutex_lock(&cli->mutex);
>>> else
>>> mutex_lock_nested(&cli->mutex, SINGLE_DEPTH_NESTING);
>>> +
>>> ret = nouveau_fence_sync(nouveau_bo(bo), chan, true,
>>> ctx->interruptible);
>>> - if (ret == 0) {
>>> - ret = drm->ttm.move(chan, bo, bo->resource, new_reg);
>>> - if (ret == 0) {
>>> - ret = nouveau_fence_new(chan, false, &fence);
>>> - if (ret == 0) {
>>> - /* TODO: figure out a better solution here
>>> - *
>>> - * wait on the fence here explicitly as going through
>>> - * ttm_bo_move_accel_cleanup somehow doesn't seem
>>> to do it.
>>> - *
>>> - * Without this the operation can timeout and we'll
>>> fallback to a
>>> - * software copy, which might take several minutes
>>> to finish.
>>> - */
>>> - nouveau_fence_wait(fence, false, false);
>>> - ret = ttm_bo_move_accel_cleanup(bo,
>>> - &fence->base,
>>> - evict, false,
>>> - new_reg);
>>> - nouveau_fence_unref(&fence);
>>> - }
>>> - }
>>> + if (ret)
>>> + goto out_unlock;
>>> +
>>> + ret = drm->ttm.move(chan, bo, bo->resource, new_reg);
>>> + if (ret)
>>> + goto out_unlock;
>>> +
>>> + ret = nouveau_fence_new(&fence);
>>> + if (ret)
>>> + goto out_unlock;
>>> +
>>> + ret = nouveau_fence_emit(fence, chan);
>>> + if (ret) {
>>> + nouveau_fence_unref(&fence);
>>> + goto out_unlock;
>>> }
>>> +
>>> + /* TODO: figure out a better solution here
>>> + *
>>> + * wait on the fence here explicitly as going through
>>> + * ttm_bo_move_accel_cleanup somehow doesn't seem to do it.
>>> + *
>>> + * Without this the operation can timeout and we'll fallback to a
>>> + * software copy, which might take several minutes to finish.
>>> + */
>>> + nouveau_fence_wait(fence, false, false);
>>> + ret = ttm_bo_move_accel_cleanup(bo, &fence->base, evict, false,
>>> + new_reg);
>>> + nouveau_fence_unref(&fence);
>>> +
>>> +out_unlock:
>>> mutex_unlock(&cli->mutex);
>>> return ret;
>>> }
>>> diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c
>>> b/drivers/gpu/drm/nouveau/nouveau_chan.c
>>> index 6d639314250a..f69be4c8f9f2 100644
>>> --- a/drivers/gpu/drm/nouveau/nouveau_chan.c
>>> +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c
>>> @@ -62,9 +62,11 @@ nouveau_channel_idle(struct nouveau_channel *chan)
>>> struct nouveau_fence *fence = NULL;
>>> int ret;
>>> - ret = nouveau_fence_new(chan, false, &fence);
>>> + ret = nouveau_fence_new(&fence);
>>> if (!ret) {
>>> - ret = nouveau_fence_wait(fence, false, false);
>>> + ret = nouveau_fence_emit(fence, chan);
>>> + if (!ret)
>>> + ret = nouveau_fence_wait(fence, false, false);
>>> nouveau_fence_unref(&fence);
>>> }
>>> diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c
>>> b/drivers/gpu/drm/nouveau/nouveau_dmem.c
>>> index 789857faa048..4ad40e42cae1 100644
>>> --- a/drivers/gpu/drm/nouveau/nouveau_dmem.c
>>> +++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c
>>> @@ -209,7 +209,8 @@ static vm_fault_t
>>> nouveau_dmem_migrate_to_ram(struct vm_fault *vmf)
>>> goto done;
>>> }
>>> - nouveau_fence_new(dmem->migrate.chan, false, &fence);
>>> + if (!nouveau_fence_new(&fence))
>>> + nouveau_fence_emit(fence, dmem->migrate.chan);
>>> migrate_vma_pages(&args);
>>> nouveau_dmem_fence_done(&fence);
>>> dma_unmap_page(drm->dev->dev, dma_addr, PAGE_SIZE,
>>> DMA_BIDIRECTIONAL);
>>> @@ -402,7 +403,8 @@ nouveau_dmem_evict_chunk(struct
>>> nouveau_dmem_chunk *chunk)
>>> }
>>> }
>>> - nouveau_fence_new(chunk->drm->dmem->migrate.chan, false, &fence);
>>> + if (!nouveau_fence_new(&fence))
>>> + nouveau_fence_emit(fence, chunk->drm->dmem->migrate.chan);
>>> migrate_device_pages(src_pfns, dst_pfns, npages);
>>> nouveau_dmem_fence_done(&fence);
>>> migrate_device_finalize(src_pfns, dst_pfns, npages);
>>> @@ -675,7 +677,8 @@ static void nouveau_dmem_migrate_chunk(struct
>>> nouveau_drm *drm,
>>> addr += PAGE_SIZE;
>>> }
>>> - nouveau_fence_new(drm->dmem->migrate.chan, false, &fence);
>>> + if (!nouveau_fence_new(&fence))
>>> + nouveau_fence_emit(fence, chunk->drm->dmem->migrate.chan);
>>> migrate_vma_pages(args);
>>> nouveau_dmem_fence_done(&fence);
>>> nouveau_pfns_map(svmm, args->vma->vm_mm, args->start, pfns, i);
>>> diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c
>>> b/drivers/gpu/drm/nouveau/nouveau_fence.c
>>> index ee5e9d40c166..e946408f945b 100644
>>> --- a/drivers/gpu/drm/nouveau/nouveau_fence.c
>>> +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
>>> @@ -210,6 +210,9 @@ nouveau_fence_emit(struct nouveau_fence *fence,
>>> struct nouveau_channel *chan)
>>> struct nouveau_fence_priv *priv = (void*)chan->drm->fence;
>>> int ret;
>>> + if (unlikely(!chan->fence))
>>> + return -ENODEV;
>>> +
>>> fence->channel = chan;
>>> fence->timeout = jiffies + (15 * HZ);
>>> @@ -396,25 +399,16 @@ nouveau_fence_unref(struct nouveau_fence
>>> **pfence)
>>> }
>>> int
>>> -nouveau_fence_new(struct nouveau_channel *chan, bool sysmem,
>>> - struct nouveau_fence **pfence)
>>> +nouveau_fence_new(struct nouveau_fence **pfence)
>>> {
>>> struct nouveau_fence *fence;
>>> - int ret = 0;
>>> -
>>> - if (unlikely(!chan->fence))
>>> - return -ENODEV;
>>> fence = kzalloc(sizeof(*fence), GFP_KERNEL);
>>> if (!fence)
>>> return -ENOMEM;
>>> - ret = nouveau_fence_emit(fence, chan);
>>> - if (ret)
>>> - nouveau_fence_unref(&fence);
>>> -
>>> *pfence = fence;
>>> - return ret;
>>> + return 0;
>>> }
>>> static const char *nouveau_fence_get_get_driver_name(struct
>>> dma_fence *fence)
>>> diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h
>>> b/drivers/gpu/drm/nouveau/nouveau_fence.h
>>> index 0ca2bc85adf6..7c73c7c9834a 100644
>>> --- a/drivers/gpu/drm/nouveau/nouveau_fence.h
>>> +++ b/drivers/gpu/drm/nouveau/nouveau_fence.h
>>> @@ -17,8 +17,7 @@ struct nouveau_fence {
>>> unsigned long timeout;
>>> };
>>> -int nouveau_fence_new(struct nouveau_channel *, bool sysmem,
>>> - struct nouveau_fence **);
>>> +int nouveau_fence_new(struct nouveau_fence **);
>>> void nouveau_fence_unref(struct nouveau_fence **);
>>> int nouveau_fence_emit(struct nouveau_fence *, struct
>>> nouveau_channel *);
>>> diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c
>>> b/drivers/gpu/drm/nouveau/nouveau_gem.c
>>> index a48f42aaeab9..9c8d1b911a01 100644
>>> --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
>>> +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
>>> @@ -873,8 +873,11 @@ nouveau_gem_ioctl_pushbuf(struct drm_device
>>> *dev, void *data,
>>> }
>>> }
>>> - ret = nouveau_fence_new(chan, false, &fence);
>>> + ret = nouveau_fence_new(&fence);
>>> + if (!ret)
>>> + ret = nouveau_fence_emit(fence, chan);
>>> if (ret) {
>>> + nouveau_fence_unref(&fence);
>>> NV_PRINTK(err, cli, "error fencing pushbuf: %d\n", ret);
>>> WIND_RING(chan);
>>> goto out;
>>
>
next prev parent reply other threads:[~2023-08-08 16:20 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-03 16:52 [PATCH drm-misc-next v9 00/11] Nouveau VM_BIND UAPI & DRM GPUVA Manager (merged) Danilo Krummrich
2023-08-03 16:52 ` [PATCH drm-misc-next v9 01/11] drm/gem: fix lockdep check for dma-resv lock Danilo Krummrich
2023-08-08 7:21 ` Boris Brezillon
2023-08-09 22:40 ` Danilo Krummrich
2023-08-03 16:52 ` [PATCH drm-misc-next v9 02/11] drm/nouveau: new VM_BIND uapi interfaces Danilo Krummrich
2023-08-03 16:52 ` [PATCH drm-misc-next v9 03/11] drm/nouveau: get vmm via nouveau_cli_vmm() Danilo Krummrich
2023-08-03 16:52 ` [PATCH drm-misc-next v9 04/11] drm/nouveau: bo: initialize GEM GPU VA interface Danilo Krummrich
2023-08-03 16:52 ` [PATCH drm-misc-next v9 05/11] drm/nouveau: move usercopy helpers to nouveau_drv.h Danilo Krummrich
2023-08-03 16:52 ` [PATCH drm-misc-next v9 06/11] drm/nouveau: fence: separate fence alloc and emit Danilo Krummrich
2023-08-07 18:07 ` Christian König
2023-08-07 18:54 ` Danilo Krummrich
2023-08-08 6:06 ` Christian König [this message]
2023-08-03 16:52 ` [PATCH drm-misc-next v9 07/11] drm/nouveau: fence: fail to emit when fence context is killed Danilo Krummrich
2023-08-03 16:52 ` [PATCH drm-misc-next v9 08/11] drm/nouveau: chan: provide nouveau_channel_kill() Danilo Krummrich
2023-08-03 16:52 ` [PATCH drm-misc-next v9 09/11] drm/nouveau: nvkm/vmm: implement raw ops to manage uvmm Danilo Krummrich
2023-08-03 16:52 ` [PATCH drm-misc-next v9 10/11] drm/nouveau: implement new VM_BIND uAPI Danilo Krummrich
2023-08-03 16:52 ` [PATCH drm-misc-next v9 11/11] drm/nouveau: debugfs: implement DRM GPU VA debugfs Danilo Krummrich
2023-08-03 21:44 ` [PATCH drm-misc-next v9 00/11] Nouveau VM_BIND UAPI & DRM GPUVA Manager (merged) Dave Airlie
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=fa6e771f-39fa-5e1e-b062-a9a4c3182852@amd.com \
--to=christian.koenig@amd.com \
--cc=Liam.Howlett@oracle.com \
--cc=airlied@gmail.com \
--cc=alexdeucher@gmail.com \
--cc=bagasdotme@gmail.com \
--cc=boris.brezillon@collabora.com \
--cc=bskeggs@redhat.com \
--cc=corbet@lwn.net \
--cc=dakr@redhat.com \
--cc=daniel@ffwll.ch \
--cc=donald.robson@imgtec.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=jason@jlekstrand.net \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=matthew.brost@intel.com \
--cc=mripard@kernel.org \
--cc=nouveau@lists.freedesktop.org \
--cc=ogabbay@kernel.org \
--cc=tzimmermann@suse.de \
--cc=willy@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®