mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
drm/amdgpu: fix amdgpu_hmm_range_get_pages
The notifier sequence must only be read once or otherwise we could work with invalid pages. While at it also fix the coding style, e.g. drop the pre-initialized return value and use the common define for 2G range. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Vitaly Prosyak <vitaly.prosyak@amd.com> Tested-by: Vitaly Prosyak <vitaly.prosyak@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
82502db448
commit
c08972f555
|
|
@ -51,8 +51,6 @@
|
||||||
#include "amdgpu_amdkfd.h"
|
#include "amdgpu_amdkfd.h"
|
||||||
#include "amdgpu_hmm.h"
|
#include "amdgpu_hmm.h"
|
||||||
|
|
||||||
#define MAX_WALK_BYTE (2UL << 30)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* amdgpu_hmm_invalidate_gfx - callback to notify about mm change
|
* amdgpu_hmm_invalidate_gfx - callback to notify about mm change
|
||||||
*
|
*
|
||||||
|
|
@ -170,11 +168,13 @@ int amdgpu_hmm_range_get_pages(struct mmu_interval_notifier *notifier,
|
||||||
void *owner,
|
void *owner,
|
||||||
struct amdgpu_hmm_range *range)
|
struct amdgpu_hmm_range *range)
|
||||||
{
|
{
|
||||||
unsigned long end;
|
const u64 max_bytes = SZ_2G;
|
||||||
|
|
||||||
|
struct hmm_range *hmm_range = &range->hmm_range;
|
||||||
unsigned long timeout;
|
unsigned long timeout;
|
||||||
unsigned long *pfns;
|
unsigned long *pfns;
|
||||||
int r = 0;
|
unsigned long end;
|
||||||
struct hmm_range *hmm_range = &range->hmm_range;
|
int r;
|
||||||
|
|
||||||
pfns = kvmalloc_array(npages, sizeof(*pfns), GFP_KERNEL);
|
pfns = kvmalloc_array(npages, sizeof(*pfns), GFP_KERNEL);
|
||||||
if (unlikely(!pfns)) {
|
if (unlikely(!pfns)) {
|
||||||
|
|
@ -191,8 +191,9 @@ int amdgpu_hmm_range_get_pages(struct mmu_interval_notifier *notifier,
|
||||||
end = start + npages * PAGE_SIZE;
|
end = start + npages * PAGE_SIZE;
|
||||||
hmm_range->dev_private_owner = owner;
|
hmm_range->dev_private_owner = owner;
|
||||||
|
|
||||||
|
hmm_range->notifier_seq = mmu_interval_read_begin(notifier);
|
||||||
do {
|
do {
|
||||||
hmm_range->end = min(hmm_range->start + MAX_WALK_BYTE, end);
|
hmm_range->end = min(hmm_range->start + max_bytes, end);
|
||||||
|
|
||||||
pr_debug("hmm range: start = 0x%lx, end = 0x%lx",
|
pr_debug("hmm range: start = 0x%lx, end = 0x%lx",
|
||||||
hmm_range->start, hmm_range->end);
|
hmm_range->start, hmm_range->end);
|
||||||
|
|
@ -200,7 +201,6 @@ int amdgpu_hmm_range_get_pages(struct mmu_interval_notifier *notifier,
|
||||||
timeout = jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
|
timeout = jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
hmm_range->notifier_seq = mmu_interval_read_begin(notifier);
|
|
||||||
r = hmm_range_fault(hmm_range);
|
r = hmm_range_fault(hmm_range);
|
||||||
if (unlikely(r)) {
|
if (unlikely(r)) {
|
||||||
if (r == -EBUSY && !time_after(jiffies, timeout))
|
if (r == -EBUSY && !time_after(jiffies, timeout))
|
||||||
|
|
@ -210,7 +210,7 @@ int amdgpu_hmm_range_get_pages(struct mmu_interval_notifier *notifier,
|
||||||
|
|
||||||
if (hmm_range->end == end)
|
if (hmm_range->end == end)
|
||||||
break;
|
break;
|
||||||
hmm_range->hmm_pfns += MAX_WALK_BYTE >> PAGE_SHIFT;
|
hmm_range->hmm_pfns += max_bytes >> PAGE_SHIFT;
|
||||||
hmm_range->start = hmm_range->end;
|
hmm_range->start = hmm_range->end;
|
||||||
} while (hmm_range->end < end);
|
} while (hmm_range->end < end);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user