From: "Thomas Hellström" <thomas.hellstrom@linux.intel.com>
To: Matthew Auld <matthew.auld@intel.com>,
intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org
Subject: Re: [PATCH v3 2/6] drm/i915: Add support for asynchronous moving fence waiting
Date: Mon, 15 Nov 2021 14:29:49 +0100 [thread overview]
Message-ID: <0cad8a60-6518-9b3a-4d4a-08e1e26174c5@linux.intel.com> (raw)
In-Reply-To: <2bfe4b1f-3643-161c-b23c-ac4cd60f73f1@intel.com>
On 11/15/21 14:13, Matthew Auld wrote:
> On 15/11/2021 12:42, Thomas Hellström wrote:
>>
>> On 11/15/21 13:36, Matthew Auld wrote:
>>> On 14/11/2021 11:12, Thomas Hellström wrote:
>>>> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>>>>
>>>> For now, we will only allow async migration when TTM is used,
>>>> so the paths we care about are related to TTM.
>>>>
>>>> The mmap path is handled by having the fence in ttm_bo->moving,
>>>> when pinning, the binding only becomes available after the moving
>>>> fence is signaled, and pinning a cpu map will only work after
>>>> the moving fence signals.
>>>>
>>>> This should close all holes where userspace can read a buffer
>>>> before it's fully migrated.
>>>>
>>>> v2:
>>>> - Fix a couple of SPARSE warnings
>>>> v3:
>>>> - Fix a NULL pointer dereference
>>>>
>>>> Co-developed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
>>>> Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
>>>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>>>> ---
>>>> drivers/gpu/drm/i915/display/intel_fbdev.c | 7 ++--
>>>> drivers/gpu/drm/i915/display/intel_overlay.c | 2 +-
>>>> drivers/gpu/drm/i915/gem/i915_gem_pages.c | 6 +++
>>>> .../i915/gem/selftests/i915_gem_coherency.c | 4 +-
>>>> .../drm/i915/gem/selftests/i915_gem_mman.c | 22 ++++++-----
>>>> drivers/gpu/drm/i915/i915_vma.c | 39
>>>> ++++++++++++++++++-
>>>> drivers/gpu/drm/i915/i915_vma.h | 3 ++
>>>> drivers/gpu/drm/i915/selftests/i915_vma.c | 4 +-
>>>> 8 files changed, 69 insertions(+), 18 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c
>>>> b/drivers/gpu/drm/i915/display/intel_fbdev.c
>>>> index adc3a81be9f7..5902ad0c2bd8 100644
>>>> --- a/drivers/gpu/drm/i915/display/intel_fbdev.c
>>>> +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
>>>> @@ -265,11 +265,12 @@ static int intelfb_create(struct
>>>> drm_fb_helper *helper,
>>>> info->fix.smem_len = vma->node.size;
>>>> }
>>>> - vaddr = i915_vma_pin_iomap(vma);
>>>> + vaddr = i915_vma_pin_iomap_unlocked(vma);
>>>> if (IS_ERR(vaddr)) {
>>>> - drm_err(&dev_priv->drm,
>>>> - "Failed to remap framebuffer into virtual memory\n");
>>>> ret = PTR_ERR(vaddr);
>>>> + if (ret != -EINTR && ret != -ERESTARTSYS)
>>>> + drm_err(&dev_priv->drm,
>>>> + "Failed to remap framebuffer into virtual memory\n");
>>>> goto out_unpin;
>>>> }
>>>> info->screen_base = vaddr;
>>>> diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c
>>>> b/drivers/gpu/drm/i915/display/intel_overlay.c
>>>> index 7e3f5c6ca484..21593f3f2664 100644
>>>> --- a/drivers/gpu/drm/i915/display/intel_overlay.c
>>>> +++ b/drivers/gpu/drm/i915/display/intel_overlay.c
>>>> @@ -1357,7 +1357,7 @@ static int get_registers(struct intel_overlay
>>>> *overlay, bool use_phys)
>>>> overlay->flip_addr = sg_dma_address(obj->mm.pages->sgl);
>>>> else
>>>> overlay->flip_addr = i915_ggtt_offset(vma);
>>>> - overlay->regs = i915_vma_pin_iomap(vma);
>>>> + overlay->regs = i915_vma_pin_iomap_unlocked(vma);
>>>> i915_vma_unpin(vma);
>>>> if (IS_ERR(overlay->regs)) {
>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
>>>> b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
>>>> index c4f684b7cc51..49c6e55c68ce 100644
>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
>>>> @@ -418,6 +418,12 @@ void *i915_gem_object_pin_map(struct
>>>> drm_i915_gem_object *obj,
>>>> }
>>>> if (!ptr) {
>>>> + err = i915_gem_object_wait_moving_fence(obj, true);
>>>> + if (err) {
>>>> + ptr = ERR_PTR(err);
>>>> + goto err_unpin;
>>>> + }
>>>> +
>>>> if (GEM_WARN_ON(type == I915_MAP_WC &&
>>>> !static_cpu_has(X86_FEATURE_PAT)))
>>>> ptr = ERR_PTR(-ENODEV);
>>>> diff --git
>>>> a/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c
>>>> b/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c
>>>> index 13b088cc787e..067c512961ba 100644
>>>> --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c
>>>> +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_coherency.c
>>>> @@ -101,7 +101,7 @@ static int gtt_set(struct context *ctx,
>>>> unsigned long offset, u32 v)
>>>> intel_gt_pm_get(vma->vm->gt);
>>>> - map = i915_vma_pin_iomap(vma);
>>>> + map = i915_vma_pin_iomap_unlocked(vma);
>>>> i915_vma_unpin(vma);
>>>> if (IS_ERR(map)) {
>>>> err = PTR_ERR(map);
>>>> @@ -134,7 +134,7 @@ static int gtt_get(struct context *ctx,
>>>> unsigned long offset, u32 *v)
>>>> intel_gt_pm_get(vma->vm->gt);
>>>> - map = i915_vma_pin_iomap(vma);
>>>> + map = i915_vma_pin_iomap_unlocked(vma);
>>>> i915_vma_unpin(vma);
>>>> if (IS_ERR(map)) {
>>>> err = PTR_ERR(map);
>>>> diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
>>>> b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
>>>> index 6d30cdfa80f3..5d54181c2145 100644
>>>> --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
>>>> +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c
>>>> @@ -125,12 +125,13 @@ static int check_partial_mapping(struct
>>>> drm_i915_gem_object *obj,
>>>> n = page - view.partial.offset;
>>>> GEM_BUG_ON(n >= view.partial.size);
>>>> - io = i915_vma_pin_iomap(vma);
>>>> + io = i915_vma_pin_iomap_unlocked(vma);
>>>> i915_vma_unpin(vma);
>>>> if (IS_ERR(io)) {
>>>> - pr_err("Failed to iomap partial view: offset=%lu; err=%d\n",
>>>> - page, (int)PTR_ERR(io));
>>>> err = PTR_ERR(io);
>>>> + if (err != -EINTR && err != -ERESTARTSYS)
>>>> + pr_err("Failed to iomap partial view: offset=%lu;
>>>> err=%d\n",
>>>> + page, err);
>>>> goto out;
>>>> }
>>>> @@ -219,12 +220,15 @@ static int check_partial_mappings(struct
>>>> drm_i915_gem_object *obj,
>>>> n = page - view.partial.offset;
>>>> GEM_BUG_ON(n >= view.partial.size);
>>>> - io = i915_vma_pin_iomap(vma);
>>>> + io = i915_vma_pin_iomap_unlocked(vma);
>>>> i915_vma_unpin(vma);
>>>> if (IS_ERR(io)) {
>>>> - pr_err("Failed to iomap partial view: offset=%lu;
>>>> err=%d\n",
>>>> - page, (int)PTR_ERR(io));
>>>> - return PTR_ERR(io);
>>>> + int err = PTR_ERR(io);
>>>> +
>>>> + if (err != -EINTR && err != -ERESTARTSYS)
>>>> + pr_err("Failed to iomap partial view: offset=%lu;
>>>> err=%d\n",
>>>> + page, err);
>>>> + return err;
>>>> }
>>>> iowrite32(page, io + n * PAGE_SIZE / sizeof(*io));
>>>> @@ -773,7 +777,7 @@ static int gtt_set(struct drm_i915_gem_object
>>>> *obj)
>>>> return PTR_ERR(vma);
>>>> intel_gt_pm_get(vma->vm->gt);
>>>> - map = i915_vma_pin_iomap(vma);
>>>> + map = i915_vma_pin_iomap_unlocked(vma);
>>>> i915_vma_unpin(vma);
>>>> if (IS_ERR(map)) {
>>>> err = PTR_ERR(map);
>>>> @@ -799,7 +803,7 @@ static int gtt_check(struct drm_i915_gem_object
>>>> *obj)
>>>> return PTR_ERR(vma);
>>>> intel_gt_pm_get(vma->vm->gt);
>>>> - map = i915_vma_pin_iomap(vma);
>>>> + map = i915_vma_pin_iomap_unlocked(vma);
>>>> i915_vma_unpin(vma);
>>>> if (IS_ERR(map)) {
>>>> err = PTR_ERR(map);
>>>> diff --git a/drivers/gpu/drm/i915/i915_vma.c
>>>> b/drivers/gpu/drm/i915/i915_vma.c
>>>> index 8781c4f61952..069f22b3cd48 100644
>>>> --- a/drivers/gpu/drm/i915/i915_vma.c
>>>> +++ b/drivers/gpu/drm/i915/i915_vma.c
>>>> @@ -431,6 +431,13 @@ int i915_vma_bind(struct i915_vma *vma,
>>>> work->pinned = i915_gem_object_get(vma->obj);
>>>> }
>>>> } else {
>>>> + if (vma->obj) {
>>>> + int ret;
>>>> +
>>>> + ret = i915_gem_object_wait_moving_fence(vma->obj, true);
>>>> + if (ret)
>>>> + return ret;
>>>> + }
>>>> vma->ops->bind_vma(vma->vm, NULL, vma, cache_level,
>>>> bind_flags);
>>>> }
>>>> @@ -455,6 +462,10 @@ void __iomem *i915_vma_pin_iomap(struct
>>>> i915_vma *vma)
>>>> ptr = READ_ONCE(vma->iomap);
>>>> if (ptr == NULL) {
>>>> + err = i915_gem_object_wait_moving_fence(vma->obj, true);
>>>> + if (err)
>>>> + goto err;
>>>> +
>>>> /*
>>>> * TODO: consider just using i915_gem_object_pin_map()
>>>> for lmem
>>>> * instead, which already supports mapping non-contiguous
>>>> chunks
>>>> @@ -496,6 +507,25 @@ void __iomem *i915_vma_pin_iomap(struct
>>>> i915_vma *vma)
>>>> return IO_ERR_PTR(err);
>>>> }
>>>> +void __iomem *i915_vma_pin_iomap_unlocked(struct i915_vma *vma)
>>>> +{
>>>> + struct i915_gem_ww_ctx ww;
>>>> + void __iomem *map;
>>>> + int err;
>>>> +
>>>> + for_i915_gem_ww(&ww, err, true) {
>>>> + err = i915_gem_object_lock(vma->obj, &ww);
>>>> + if (err)
>>>> + continue;
>>>> +
>>>> + map = i915_vma_pin_iomap(vma);
>>>> + }
>>>> + if (err)
>>>> + map = IO_ERR_PTR(err);
>>>> +
>>>> + return map;
>>>> +}
>>>
>>> What is the reason for this change? Is this strictly related to this
>>> series/commit?
>>
>> Yes, it's because pulling out the moving fence requires the dma_resv
>> lock.
>
> Ok, I was thinking that vma_pin_iomap is only ever called on an
> already bound GGTT vma, for which we do a syncronous wait_for_bind,
> but maybe that's not always true?
>
Hmm, Good point. We should probably replace that vma_pin_iomap stuff
with an assert that the
binding fence is indeed signaled and error free? Because if binding
succeeded, no need to check the moving fence.
/Thomas
> Reviewed-by: Matthew Auld <matthew.auld@intel.com>
>
>>
>> /Thomas
>>
>>
next prev parent reply other threads:[~2021-11-15 13:29 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-14 11:12 [PATCH v3 0/6] drm/i915/ttm: Async migration Thomas Hellström
2021-11-14 11:12 ` [PATCH v3 1/6] drm/i915: Add functions to set/get moving fence Thomas Hellström
2021-11-15 12:39 ` Matthew Auld
2021-11-15 12:44 ` Thomas Hellström
2021-11-14 11:12 ` [PATCH v3 2/6] drm/i915: Add support for asynchronous moving fence waiting Thomas Hellström
2021-11-15 12:36 ` Matthew Auld
2021-11-15 12:42 ` Thomas Hellström
2021-11-15 13:13 ` Matthew Auld
2021-11-15 13:29 ` Thomas Hellström [this message]
2021-11-14 11:12 ` [PATCH v3 3/6] drm/i915/ttm: Move the i915_gem_obj_copy_ttm() function Thomas Hellström
2021-11-15 10:42 ` Matthew Auld
2021-11-14 11:12 ` [PATCH v3 4/6] drm/i915/ttm: Break refcounting loops at device region unref time Thomas Hellström
2021-11-15 10:49 ` Matthew Auld
2021-11-14 11:12 ` [PATCH v3 5/6] drm/i915/ttm: Implement asynchronous TTM moves Thomas Hellström
2021-11-15 17:16 ` Matthew Auld
2021-11-16 7:20 ` Thomas Hellström
2021-11-18 7:13 ` Thomas Hellström
2021-11-14 11:12 ` [PATCH v3 6/6] drm/i915/ttm: Update i915_gem_obj_copy_ttm() to be asynchronous Thomas Hellström
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=0cad8a60-6518-9b3a-4d4a-08e1e26174c5@linux.intel.com \
--to=thomas.hellstrom@linux.intel.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=intel-gfx@lists.freedesktop.org \
--cc=matthew.auld@intel.com \
/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