From: "Yang, Philip" <Philip.Yang-5C7GfCeVMHo@public.gmane.org>
To: "amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org"
<amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org>
Cc: "Yang, Philip" <Philip.Yang-5C7GfCeVMHo@public.gmane.org>
Subject: [PATCH] drm/amdgpu: use new HMM APIs and helpers
Date: Thu, 30 May 2019 14:41:14 +0000 [thread overview]
Message-ID: <20190530144049.1996-1-Philip.Yang@amd.com> (raw)
HMM provides new APIs and helps in kernel 5.2-rc1 to simplify driver
path. The old hmm APIs are deprecated and will be removed in future.
Below are changes in driver:
1. Change hmm_vma_fault to hmm_range_register and hmm_range_fault which
supports range with multiple vmas, remove the multiple vmas handle path
and data structure.
2. Change hmm_vma_range_done to hmm_range_unregister.
3. Use default flags to avoid pre-fill pfn arrays.
4. Use new hmm_device_ helpers.
Change-Id: I1a00f88459f3b96c9536933e9a17eb1ebaa78113
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c | 1 -
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 140 +++++++++---------------
2 files changed, 53 insertions(+), 88 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
index 41ccee49a224..e0bb47ce570b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
@@ -519,7 +519,6 @@ void amdgpu_hmm_init_range(struct hmm_range *range)
range->flags = hmm_range_flags;
range->values = hmm_range_values;
range->pfn_shift = PAGE_SHIFT;
- range->pfns = NULL;
INIT_LIST_HEAD(&range->list);
}
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 7138dc1dd1f4..25a9fcb409c6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -711,8 +711,7 @@ struct amdgpu_ttm_tt {
struct task_struct *usertask;
uint32_t userflags;
#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
- struct hmm_range *ranges;
- int nr_ranges;
+ struct hmm_range *range;
#endif
};
@@ -725,57 +724,33 @@ struct amdgpu_ttm_tt {
*/
#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
-/* Support Userptr pages cross max 16 vmas */
-#define MAX_NR_VMAS (16)
-
int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
{
struct amdgpu_ttm_tt *gtt = (void *)ttm;
struct mm_struct *mm = gtt->usertask->mm;
unsigned long start = gtt->userptr;
- unsigned long end = start + ttm->num_pages * PAGE_SIZE;
- struct vm_area_struct *vma = NULL, *vmas[MAX_NR_VMAS];
- struct hmm_range *ranges;
- unsigned long nr_pages, i;
- uint64_t *pfns, f;
+ struct vm_area_struct *vma;
+ struct hmm_range *range;
+ unsigned long i;
+ uint64_t *pfns;
int r = 0;
if (!mm) /* Happens during process shutdown */
return -ESRCH;
- down_read(&mm->mmap_sem);
-
- /* user pages may cross multiple VMAs */
- gtt->nr_ranges = 0;
- do {
- unsigned long vm_start;
-
- if (gtt->nr_ranges >= MAX_NR_VMAS) {
- DRM_ERROR("Too many VMAs in userptr range\n");
- r = -EFAULT;
- goto out;
- }
-
- vm_start = vma ? vma->vm_end : start;
- vma = find_vma(mm, vm_start);
- if (unlikely(!vma || vm_start < vma->vm_start)) {
- r = -EFAULT;
- goto out;
- }
- vmas[gtt->nr_ranges++] = vma;
- } while (end > vma->vm_end);
-
- DRM_DEBUG_DRIVER("0x%lx nr_ranges %d pages 0x%lx\n",
- start, gtt->nr_ranges, ttm->num_pages);
-
+ vma = find_vma(mm, start);
+ if (unlikely(!vma || start < vma->vm_start)) {
+ r = -EFAULT;
+ goto out;
+ }
if (unlikely((gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) &&
- vmas[0]->vm_file)) {
+ vma->vm_file)) {
r = -EPERM;
goto out;
}
- ranges = kvmalloc_array(gtt->nr_ranges, sizeof(*ranges), GFP_KERNEL);
- if (unlikely(!ranges)) {
+ range = kvmalloc(sizeof(*range), GFP_KERNEL | __GFP_ZERO);
+ if (unlikely(!range)) {
r = -ENOMEM;
goto out;
}
@@ -786,61 +761,52 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
goto out_free_ranges;
}
- for (i = 0; i < gtt->nr_ranges; i++)
- amdgpu_hmm_init_range(&ranges[i]);
+ amdgpu_hmm_init_range(range);
+ range->default_flags = range->flags[HMM_PFN_VALID];
+ range->default_flags |= amdgpu_ttm_tt_is_readonly(ttm) ?
+ 0 : range->flags[HMM_PFN_WRITE];
+ range->pfn_flags_mask = 0;
+ range->pfns = pfns;
+ hmm_range_register(range, mm, start,
+ start + ttm->num_pages * PAGE_SIZE, PAGE_SHIFT);
- f = ranges[0].flags[HMM_PFN_VALID];
- f |= amdgpu_ttm_tt_is_readonly(ttm) ?
- 0 : ranges[0].flags[HMM_PFN_WRITE];
- memset64(pfns, f, ttm->num_pages);
-
- for (nr_pages = 0, i = 0; i < gtt->nr_ranges; i++) {
- ranges[i].vma = vmas[i];
- ranges[i].start = max(start, vmas[i]->vm_start);
- ranges[i].end = min(end, vmas[i]->vm_end);
- ranges[i].pfns = pfns + nr_pages;
- nr_pages += (ranges[i].end - ranges[i].start) / PAGE_SIZE;
+ /*
+ * Just wait for range to be valid, safe to ignore return value as we
+ * will use the return value of hmm_range_fault() below under the
+ * mmap_sem to ascertain the validity of the range.
+ */
+ hmm_range_wait_until_valid(range, HMM_RANGE_DEFAULT_TIMEOUT);
- r = hmm_vma_fault(&ranges[i], true);
- if (unlikely(r))
- break;
- }
- if (unlikely(r)) {
- while (i--)
- hmm_vma_range_done(&ranges[i]);
+ down_read(&mm->mmap_sem);
- goto out_free_pfns;
- }
+ r = hmm_range_fault(range, true);
up_read(&mm->mmap_sem);
+ if (unlikely(r < 0))
+ goto out_free_pfns;
+
for (i = 0; i < ttm->num_pages; i++) {
- pages[i] = hmm_pfn_to_page(&ranges[0], pfns[i]);
- if (!pages[i]) {
+ pages[i] = hmm_device_entry_to_page(range, pfns[i]);
+ if (unlikely(!pages[i])) {
pr_err("Page fault failed for pfn[%lu] = 0x%llx\n",
i, pfns[i]);
- goto out_invalid_pfn;
+ r = -ENOMEM;
+
+ goto out_free_pfns;
}
}
- gtt->ranges = ranges;
+ gtt->range = range;
return 0;
out_free_pfns:
+ hmm_range_unregister(range);
kvfree(pfns);
out_free_ranges:
- kvfree(ranges);
+ kvfree(range);
out:
- up_read(&mm->mmap_sem);
-
return r;
-
-out_invalid_pfn:
- for (i = 0; i < gtt->nr_ranges; i++)
- hmm_vma_range_done(&ranges[i]);
- kvfree(pfns);
- kvfree(ranges);
- return -ENOMEM;
}
/**
@@ -853,23 +819,23 @@ bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm)
{
struct amdgpu_ttm_tt *gtt = (void *)ttm;
bool r = false;
- int i;
if (!gtt || !gtt->userptr)
return false;
- DRM_DEBUG_DRIVER("user_pages_done 0x%llx nr_ranges %d pages 0x%lx\n",
- gtt->userptr, gtt->nr_ranges, ttm->num_pages);
+ DRM_DEBUG_DRIVER("user_pages_done 0x%llx pages 0x%lx\n",
+ gtt->userptr, ttm->num_pages);
- WARN_ONCE(!gtt->ranges || !gtt->ranges[0].pfns,
+ WARN_ONCE(!gtt->range || !gtt->range->pfns,
"No user pages to check\n");
- if (gtt->ranges) {
- for (i = 0; i < gtt->nr_ranges; i++)
- r |= hmm_vma_range_done(>t->ranges[i]);
- kvfree(gtt->ranges[0].pfns);
- kvfree(gtt->ranges);
- gtt->ranges = NULL;
+ if (gtt->range) {
+ r = hmm_range_valid(gtt->range);
+ hmm_range_unregister(gtt->range);
+
+ kvfree(gtt->range->pfns);
+ kvfree(gtt->range);
+ gtt->range = NULL;
}
return r;
@@ -953,9 +919,9 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
sg_free_table(ttm->sg);
#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
- if (gtt->ranges &&
- ttm->pages[0] == hmm_pfn_to_page(>t->ranges[0],
- gtt->ranges[0].pfns[0]))
+ if (gtt->range &&
+ ttm->pages[0] == hmm_device_entry_to_page(gtt->range,
+ gtt->range->pfns[0]))
WARN_ONCE(1, "Missing get_user_page_done\n");
#endif
}
--
2.17.1
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
next reply other threads:[~2019-05-30 14:41 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-30 14:41 Yang, Philip [this message]
[not found] ` <20190530144049.1996-1-Philip.Yang-5C7GfCeVMHo@public.gmane.org>
2019-05-30 22:36 ` [PATCH] drm/amdgpu: use new HMM APIs and helpers Kuehling, Felix
[not found] ` <704410a5-be01-f423-11ef-01a640cd469c-5C7GfCeVMHo@public.gmane.org>
2019-05-31 17:28 ` Yang, Philip
[not found] ` <bd8f1fd6-f6c4-66fc-c0b9-c8ed36cd6027-5C7GfCeVMHo@public.gmane.org>
2019-05-31 19:42 ` Kuehling, Felix
[not found] ` <befbe7fa-0bd3-ffcf-d2eb-36f15053d1a5-5C7GfCeVMHo@public.gmane.org>
2019-05-31 21:32 ` Yang, Philip
[not found] ` <9ae26883-4326-c60f-9a8e-d95d0d458e31-5C7GfCeVMHo@public.gmane.org>
2019-05-31 22:01 ` Kuehling, Felix
[not found] ` <9f5f4060-5f8f-b688-2cc2-39aca92c7505-5C7GfCeVMHo@public.gmane.org>
2019-06-03 10:17 ` Christian König
[not found] ` <972ef129-3dae-d5eb-100f-b9be83d0afcc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2019-06-03 11:23 ` Christian König
[not found] ` <c20fba4e-f303-75b9-4bba-bdede43237aa-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2019-06-03 15:38 ` Yang, Philip
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=20190530144049.1996-1-Philip.Yang@amd.com \
--to=philip.yang-5c7gfcevmho@public.gmane.org \
--cc=amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.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