Merge tag 'for-linus-hmm' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
Pull hmm updates from Jason Gunthorpe: "This series adds a selftest for hmm_range_fault() and several of the DEVICE_PRIVATE migration related actions, and another simplification for hmm_range_fault()'s API. - Simplify hmm_range_fault() with a simpler return code, no HMM_PFN_SPECIAL, and no customizable output PFN format - Add a selftest for hmm_range_fault() and DEVICE_PRIVATE related functionality" * tag 'for-linus-hmm' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: MAINTAINERS: add HMM selftests mm/hmm/test: add selftests for HMM mm/hmm/test: add selftest driver for HMM mm/hmm: remove the customizable pfn format from hmm_range_fault mm/hmm: remove HMM_PFN_SPECIAL drm/amdgpu: remove dead code after hmm_range_fault() mm/hmm: make hmm_range_fault return 0 or -1
This commit is contained in:
@@ -766,18 +766,6 @@ struct amdgpu_ttm_tt {
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DRM_AMDGPU_USERPTR
|
||||
/* flags used by HMM internal, not related to CPU/GPU PTE flags */
|
||||
static const uint64_t hmm_range_flags[HMM_PFN_FLAG_MAX] = {
|
||||
(1 << 0), /* HMM_PFN_VALID */
|
||||
(1 << 1), /* HMM_PFN_WRITE */
|
||||
};
|
||||
|
||||
static const uint64_t hmm_range_values[HMM_PFN_VALUE_MAX] = {
|
||||
0xfffffffffffffffeUL, /* HMM_PFN_ERROR */
|
||||
0, /* HMM_PFN_NONE */
|
||||
0xfffffffffffffffcUL /* HMM_PFN_SPECIAL */
|
||||
};
|
||||
|
||||
/**
|
||||
* amdgpu_ttm_tt_get_user_pages - get device accessible pages that back user
|
||||
* memory and start HMM tracking CPU page table update
|
||||
@@ -816,18 +804,15 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
|
||||
goto out;
|
||||
}
|
||||
range->notifier = &bo->notifier;
|
||||
range->flags = hmm_range_flags;
|
||||
range->values = hmm_range_values;
|
||||
range->pfn_shift = PAGE_SHIFT;
|
||||
range->start = bo->notifier.interval_tree.start;
|
||||
range->end = bo->notifier.interval_tree.last + 1;
|
||||
range->default_flags = hmm_range_flags[HMM_PFN_VALID];
|
||||
range->default_flags = HMM_PFN_REQ_FAULT;
|
||||
if (!amdgpu_ttm_tt_is_readonly(ttm))
|
||||
range->default_flags |= range->flags[HMM_PFN_WRITE];
|
||||
range->default_flags |= HMM_PFN_REQ_WRITE;
|
||||
|
||||
range->pfns = kvmalloc_array(ttm->num_pages, sizeof(*range->pfns),
|
||||
GFP_KERNEL);
|
||||
if (unlikely(!range->pfns)) {
|
||||
range->hmm_pfns = kvmalloc_array(ttm->num_pages,
|
||||
sizeof(*range->hmm_pfns), GFP_KERNEL);
|
||||
if (unlikely(!range->hmm_pfns)) {
|
||||
r = -ENOMEM;
|
||||
goto out_free_ranges;
|
||||
}
|
||||
@@ -852,27 +837,23 @@ retry:
|
||||
down_read(&mm->mmap_sem);
|
||||
r = hmm_range_fault(range);
|
||||
up_read(&mm->mmap_sem);
|
||||
if (unlikely(r <= 0)) {
|
||||
if (unlikely(r)) {
|
||||
/*
|
||||
* FIXME: This timeout should encompass the retry from
|
||||
* mmu_interval_read_retry() as well.
|
||||
*/
|
||||
if ((r == 0 || r == -EBUSY) && !time_after(jiffies, timeout))
|
||||
if (r == -EBUSY && !time_after(jiffies, timeout))
|
||||
goto retry;
|
||||
goto out_free_pfns;
|
||||
}
|
||||
|
||||
for (i = 0; i < ttm->num_pages; i++) {
|
||||
/* FIXME: The pages cannot be touched outside the notifier_lock */
|
||||
pages[i] = hmm_device_entry_to_page(range, range->pfns[i]);
|
||||
if (unlikely(!pages[i])) {
|
||||
pr_err("Page fault failed for pfn[%lu] = 0x%llx\n",
|
||||
i, range->pfns[i]);
|
||||
r = -ENOMEM;
|
||||
|
||||
goto out_free_pfns;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Due to default_flags, all pages are HMM_PFN_VALID or
|
||||
* hmm_range_fault() fails. FIXME: The pages cannot be touched outside
|
||||
* the notifier_lock, and mmu_interval_read_retry() must be done first.
|
||||
*/
|
||||
for (i = 0; i < ttm->num_pages; i++)
|
||||
pages[i] = hmm_pfn_to_page(range->hmm_pfns[i]);
|
||||
|
||||
gtt->range = range;
|
||||
mmput(mm);
|
||||
@@ -882,7 +863,7 @@ retry:
|
||||
out_unlock:
|
||||
up_read(&mm->mmap_sem);
|
||||
out_free_pfns:
|
||||
kvfree(range->pfns);
|
||||
kvfree(range->hmm_pfns);
|
||||
out_free_ranges:
|
||||
kfree(range);
|
||||
out:
|
||||
@@ -907,7 +888,7 @@ bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm)
|
||||
DRM_DEBUG_DRIVER("user_pages_done 0x%llx pages 0x%lx\n",
|
||||
gtt->userptr, ttm->num_pages);
|
||||
|
||||
WARN_ONCE(!gtt->range || !gtt->range->pfns,
|
||||
WARN_ONCE(!gtt->range || !gtt->range->hmm_pfns,
|
||||
"No user pages to check\n");
|
||||
|
||||
if (gtt->range) {
|
||||
@@ -917,7 +898,7 @@ bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm)
|
||||
*/
|
||||
r = mmu_interval_read_retry(gtt->range->notifier,
|
||||
gtt->range->notifier_seq);
|
||||
kvfree(gtt->range->pfns);
|
||||
kvfree(gtt->range->hmm_pfns);
|
||||
kfree(gtt->range);
|
||||
gtt->range = NULL;
|
||||
}
|
||||
@@ -1008,8 +989,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
|
||||
|
||||
for (i = 0; i < ttm->num_pages; i++) {
|
||||
if (ttm->pages[i] !=
|
||||
hmm_device_entry_to_page(gtt->range,
|
||||
gtt->range->pfns[i]))
|
||||
hmm_pfn_to_page(gtt->range->hmm_pfns[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user