aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0917-drm-amdgpu-stop-reserving-the-BO-in-the-MMU-callback.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0917-drm-amdgpu-stop-reserving-the-BO-in-the-MMU-callback.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0917-drm-amdgpu-stop-reserving-the-BO-in-the-MMU-callback.patch206
1 files changed, 206 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0917-drm-amdgpu-stop-reserving-the-BO-in-the-MMU-callback.patch b/meta-amd-bsp/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-amd-bsp/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
+