diff options
Diffstat (limited to 'meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0917-drm-amdgpu-stop-reserving-the-BO-in-the-MMU-callback.patch')
-rw-r--r-- | meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0917-drm-amdgpu-stop-reserving-the-BO-in-the-MMU-callback.patch | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0917-drm-amdgpu-stop-reserving-the-BO-in-the-MMU-callback.patch b/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0917-drm-amdgpu-stop-reserving-the-BO-in-the-MMU-callback.patch new file mode 100644 index 00000000..83534cb7 --- /dev/null +++ b/meta-v1000/recipes-kernel/linux/linux-yocto-4.14.71/0917-drm-amdgpu-stop-reserving-the-BO-in-the-MMU-callback.patch @@ -0,0 +1,206 @@ +From d1b97274771683c8a6e458caf8763260c6d5b919 Mon Sep 17 00:00:00 2001 +From: Christian Koenig <christian.koenig@amd.com> +Date: Mon, 11 Sep 2017 18:23:08 -0400 +Subject: [PATCH 0917/4131] drm/amdgpu: stop reserving the BO in the MMU + callback v3 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Instead take the callback lock during the final parts of CS. + +This should solve the last remaining locking order problems with BO reservations. + +v2: rebase, make dummy functions static inline +v3: add one more missing inline and comments + +Signed-off-by: Christian König <christian.koenig@amd.com> +Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com> +Signed-off-by: Kalyan Alle <kalyan.alle@amd.com> + + Conflicts: + drivers/gpu/drm/amd/amdgpu/amdgpu.h + drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c + +Change-Id: Ibb3b260369279334723d1eab765e3a2e1495c260 +--- + drivers/gpu/drm/amd/amdgpu/amdgpu.h | 11 +++++++++++ + drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 27 ++++++++++++++++++++++----- + drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c | 31 ++++++++++++++++++++++--------- + 3 files changed, 55 insertions(+), 14 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +index a9e3397..bdee4b0 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +@@ -182,6 +182,7 @@ struct amdgpu_cs_parser; + struct amdgpu_job; + struct amdgpu_irq_src; + struct amdgpu_fpriv; ++struct amdgpu_mn; + + enum amdgpu_cp_irq { + AMDGPU_CP_IRQ_GFX_EOP = 0, +@@ -1074,6 +1075,7 @@ struct amdgpu_cs_parser { + /* buffer objects */ + struct ww_acquire_ctx ticket; + struct amdgpu_bo_list *bo_list; ++ struct amdgpu_mn *mn; + struct amdgpu_bo_list_entry vm_pd; + struct list_head validated; + struct dma_fence *fence; +@@ -1218,9 +1220,18 @@ void amdgpu_test_moves(struct amdgpu_device *adev); + * MMU Notifier + */ + #if defined(CONFIG_MMU_NOTIFIER) ++struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev); + int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr); + void amdgpu_mn_unregister(struct amdgpu_bo *bo); ++void amdgpu_mn_lock(struct amdgpu_mn *mn); ++void amdgpu_mn_unlock(struct amdgpu_mn *mn); + #else ++static inline void amdgpu_mn_lock(struct amdgpu_mn *mn) {} ++static inline void amdgpu_mn_unlock(struct amdgpu_mn *mn) {} ++static inline struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev) ++{ ++ return NULL; ++} + static inline int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr) + { + return -ENODEV; +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +index aa7989f..091b4eb 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +@@ -522,6 +522,8 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, + need_mmap_lock = p->bo_list->first_userptr != + p->bo_list->num_entries; + amdgpu_bo_list_get_list(p->bo_list, &p->validated); ++ if (p->bo_list->first_userptr != p->bo_list->num_entries) ++ p->mn = amdgpu_mn_get(p->adev); + } + + INIT_LIST_HEAD(&duplicates); +@@ -736,11 +738,7 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, + { + unsigned i; + +- if (!error) +- ttm_eu_fence_buffer_objects(&parser->ticket, +- &parser->validated, +- parser->fence); +- else if (backoff) ++ if (error && backoff) + ttm_eu_backoff_reservation(&parser->ticket, + &parser->validated); + +@@ -1141,14 +1139,29 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, + struct amdgpu_ring *ring = p->job->ring; + struct amd_sched_entity *entity = &p->ctx->rings[ring->idx].entity; + struct amdgpu_job *job; ++ unsigned i; + int r; + ++ amdgpu_mn_lock(p->mn); ++ if (p->bo_list) { ++ for (i = p->bo_list->first_userptr; ++ i < p->bo_list->num_entries; ++i) { ++ struct amdgpu_bo *bo = p->bo_list->array[i].robj; ++ ++ if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm)) { ++ amdgpu_mn_unlock(p->mn); ++ return -ERESTARTSYS; ++ } ++ } ++ } ++ + job = p->job; + p->job = NULL; + + r = amd_sched_job_init(&job->base, &ring->sched, entity, p->filp); + if (r) { + amdgpu_job_free(job); ++ amdgpu_mn_unlock(p->mn); + return r; + } + +@@ -1164,6 +1177,10 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, + + trace_amdgpu_cs_ioctl(job); + amd_sched_entity_push_job(&job->base); ++ ++ ttm_eu_fence_buffer_objects(&p->ticket, &p->validated, p->fence); ++ amdgpu_mn_unlock(p->mn); ++ + return 0; + } + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c +index 14f313e..da6ffaa 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c +@@ -106,6 +106,25 @@ static void amdgpu_mn_release(struct mmu_notifier *mn, + schedule_work(&rmn->work); + } + ++ ++/** ++ * amdgpu_mn_lock - take the write side lock for this mn ++ */ ++void amdgpu_mn_lock(struct amdgpu_mn *mn) ++{ ++ if (mn) ++ down_write(&mn->lock); ++} ++ ++/** ++ * amdgpu_mn_unlock - drop the write side lock for this mn ++ */ ++void amdgpu_mn_unlock(struct amdgpu_mn *mn) ++{ ++ if (mn) ++ up_write(&mn->lock); ++} ++ + /** + * amdgpu_mn_invalidate_node - unmap all BOs of a node + * +@@ -126,20 +145,12 @@ static void amdgpu_mn_invalidate_node(struct amdgpu_mn_node *node, + if (!amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm, start, end)) + continue; + +- r = amdgpu_bo_reserve(bo, true); +- if (r) { +- DRM_ERROR("(%ld) failed to reserve user bo\n", r); +- continue; +- } +- + r = reservation_object_wait_timeout_rcu(bo->tbo.resv, + true, false, MAX_SCHEDULE_TIMEOUT); + if (r <= 0) + DRM_ERROR("(%ld) failed to wait for user bo\n", r); + + amdgpu_ttm_tt_mark_user_pages(bo->tbo.ttm); +- +- amdgpu_bo_unreserve(bo); + } + } + +@@ -192,7 +203,8 @@ static const struct mmu_notifier_ops amdgpu_mn_ops = { + * + * Creates a notifier context for current->mm. + */ +-static struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev) ++struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev, ++ enum amdgpu_mn_type type) + { + struct mm_struct *mm = current->mm; + struct amdgpu_mn *rmn; +@@ -337,3 +349,4 @@ void amdgpu_mn_unregister(struct amdgpu_bo *bo) + up_write(&rmn->lock); + mutex_unlock(&adev->mn_lock); + } ++ +-- +2.7.4 + |