diff options
author | Christian König <christian.koenig@amd.com> | 2016-02-08 04:57:22 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-02-10 14:16:43 -0500 |
commit | d7006964d46d76930a44e14f1aae401ccb1797da (patch) | |
tree | 5688e0d3eaed9d4fdf404dfe6bfbe5a1c2a9be19 | |
parent | 10c1b6183a163aca59ba92b88f2b4c4cecd20d4c (diff) |
drm/amdgpu: fix issue with overlapping userptrs
Otherwise we could try to evict overlapping userptr BOs in get_user_pages(),
leading to a possible circular locking dependency.
Signed-off-by: Christian König <christian.koenig@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 19 |
3 files changed, 23 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 82edf95b7740..d0fee29ebeba 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -2360,6 +2360,8 @@ bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo); | |||
2360 | int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, | 2360 | int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, |
2361 | uint32_t flags); | 2361 | uint32_t flags); |
2362 | bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm); | 2362 | bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm); |
2363 | bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, | ||
2364 | unsigned long end); | ||
2363 | bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm); | 2365 | bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm); |
2364 | uint32_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm, | 2366 | uint32_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm, |
2365 | struct ttm_mem_reg *mem); | 2367 | struct ttm_mem_reg *mem); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c index b1969f2b2038..d4e2780c0796 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c | |||
@@ -142,7 +142,8 @@ static void amdgpu_mn_invalidate_range_start(struct mmu_notifier *mn, | |||
142 | 142 | ||
143 | list_for_each_entry(bo, &node->bos, mn_list) { | 143 | list_for_each_entry(bo, &node->bos, mn_list) { |
144 | 144 | ||
145 | if (!bo->tbo.ttm || bo->tbo.ttm->state != tt_bound) | 145 | if (!amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm, start, |
146 | end)) | ||
146 | continue; | 147 | continue; |
147 | 148 | ||
148 | r = amdgpu_bo_reserve(bo, true); | 149 | r = amdgpu_bo_reserve(bo, true); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 55cf05e1c81c..6442a06d6fdc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | |||
@@ -783,6 +783,25 @@ bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm) | |||
783 | return !!gtt->userptr; | 783 | return !!gtt->userptr; |
784 | } | 784 | } |
785 | 785 | ||
786 | bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, | ||
787 | unsigned long end) | ||
788 | { | ||
789 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | ||
790 | unsigned long size; | ||
791 | |||
792 | if (gtt == NULL) | ||
793 | return false; | ||
794 | |||
795 | if (gtt->ttm.ttm.state != tt_bound || !gtt->userptr) | ||
796 | return false; | ||
797 | |||
798 | size = (unsigned long)gtt->ttm.ttm.num_pages * PAGE_SIZE; | ||
799 | if (gtt->userptr > end || gtt->userptr + size <= start) | ||
800 | return false; | ||
801 | |||
802 | return true; | ||
803 | } | ||
804 | |||
786 | bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm) | 805 | bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm) |
787 | { | 806 | { |
788 | struct amdgpu_ttm_tt *gtt = (void *)ttm; | 807 | struct amdgpu_ttm_tt *gtt = (void *)ttm; |