aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1805-drm-amdgpu-keep-the-MMU-lock-until-the-update-ends-v.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1805-drm-amdgpu-keep-the-MMU-lock-until-the-update-ends-v.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1805-drm-amdgpu-keep-the-MMU-lock-until-the-update-ends-v.patch156
1 files changed, 156 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1805-drm-amdgpu-keep-the-MMU-lock-until-the-update-ends-v.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1805-drm-amdgpu-keep-the-MMU-lock-until-the-update-ends-v.patch
new file mode 100644
index 00000000..5fafbad3
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/1805-drm-amdgpu-keep-the-MMU-lock-until-the-update-ends-v.patch
@@ -0,0 +1,156 @@
+From cbce205156a7873406e007a7b5bf6103a926e337 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Mon, 11 Sep 2017 18:24:37 -0400
+Subject: [PATCH 1805/4131] drm/amdgpu: keep the MMU lock until the update ends
+ v4
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This is quite controversial because it adds another lock which is held during
+page table updates, but I don't see much other option.
+
+v2: allow multiple updates to be in flight at the same time
+v3: simplify the patch, take the read side only once
+v4: correctly fix rebase conflict
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
+
+ Conflicts:
+ drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
+
+Change-Id: I932e17b4e1564a3974004b501b26e00d8259782a
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 +--
+ drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c | 56 ++++++++++++++++++++++++++++++++--
+ 2 files changed, 56 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+index 5bf1051..85a557c 100755
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+@@ -1230,11 +1230,11 @@ void amdgpu_test_moves(struct amdgpu_device *adev);
+ * MMU Notifier
+ */
+ #if defined(CONFIG_MMU_NOTIFIER)
++void amdgpu_mn_lock(struct amdgpu_mn *mn);
++void amdgpu_mn_unlock(struct amdgpu_mn *mn);
+ 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) {}
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
+index d0e42b0..f8093c8 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
+@@ -59,6 +59,8 @@ struct amdgpu_mn {
+ /* objects protected by lock */
+ struct rw_semaphore lock;
+ struct rb_root objects;
++ struct mutex read_lock;
++ atomic_t recursion;
+ };
+
+ struct amdgpu_mn_node {
+@@ -133,6 +135,34 @@ void amdgpu_mn_unlock(struct amdgpu_mn *mn)
+ }
+
+ /**
++ * amdgpu_mn_read_lock - take the rmn read lock
++ *
++ * @rmn: our notifier
++ *
++ * Take the rmn read side lock.
++ */
++static void amdgpu_mn_read_lock(struct amdgpu_mn *rmn)
++{
++ mutex_lock(&rmn->read_lock);
++ if (atomic_inc_return(&rmn->recursion) == 1)
++ down_read_non_owner(&rmn->lock);
++ mutex_unlock(&rmn->read_lock);
++}
++
++/**
++ * amdgpu_mn_read_unlock - drop the rmn read lock
++ *
++ * @rmn: our notifier
++ *
++ * Drop the rmn read side lock.
++ */
++static void amdgpu_mn_read_unlock(struct amdgpu_mn *rmn)
++{
++ if (atomic_dec_return(&rmn->recursion) == 0)
++ up_read_non_owner(&rmn->lock);
++}
++
++/**
+ * amdgpu_mn_invalidate_node - unmap all BOs of a node
+ *
+ * @node: the node with the BOs to unmap
+@@ -183,7 +213,7 @@ static void amdgpu_mn_invalidate_range_start_gfx(struct mmu_notifier *mn,
+ /* notification is exclusive, but interval is inclusive */
+ end -= 1;
+
+- down_read(&rmn->lock);
++ amdgpu_mn_read_lock(rmn);
+
+ it = interval_tree_iter_first(&rmn->objects, start, end);
+ while (it) {
+@@ -194,8 +224,26 @@ static void amdgpu_mn_invalidate_range_start_gfx(struct mmu_notifier *mn,
+
+ amdgpu_mn_invalidate_node(node, start, end);
+ }
++}
++
++/**
++ * amdgpu_mn_invalidate_range_end - callback to notify about mm change
++ *
++ * @mn: our notifier
++ * @mn: the mm this callback is about
++ * @start: start of updated range
++ * @end: end of updated range
++ *
++ * Release the lock again to allow new command submissions.
++ */
++static void amdgpu_mn_invalidate_range_end(struct mmu_notifier *mn,
++ struct mm_struct *mm,
++ unsigned long start,
++ unsigned long end)
++{
++ struct amdgpu_mn *rmn = container_of(mn, struct amdgpu_mn, mn);
+
+- up_read(&rmn->lock);
++ amdgpu_mn_read_unlock(rmn);
+ }
+
+ /**
+@@ -247,10 +295,12 @@ static const struct mmu_notifier_ops amdgpu_mn_ops[] = {
+ [AMDGPU_MN_TYPE_GFX] = {
+ .release = amdgpu_mn_release,
+ .invalidate_range_start = amdgpu_mn_invalidate_range_start_gfx,
++ .invalidate_range_end = amdgpu_mn_invalidate_range_end,
+ },
+ [AMDGPU_MN_TYPE_HSA] = {
+ .release = amdgpu_mn_release,
+ .invalidate_range_start = amdgpu_mn_invalidate_range_start_hsa,
++ .invalidate_range_end = amdgpu_mn_invalidate_range_end,
+ },
+ };
+
+@@ -308,6 +358,8 @@ struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev,
+ rmn->mn.ops = &amdgpu_mn_ops[type];
+ init_rwsem(&rmn->lock);
+ rmn->objects = RB_ROOT;
++ mutex_init(&rmn->read_lock);
++ atomic_set(&rmn->recursion, 0);
+
+ r = __mmu_notifier_register(&rmn->mn, mm);
+ if (r)
+--
+2.7.4
+