aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0920-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/0920-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/0920-drm-amdgpu-keep-the-MMU-lock-until-the-update-ends-v.patch147
1 files changed, 147 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0920-drm-amdgpu-keep-the-MMU-lock-until-the-update-ends-v.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0920-drm-amdgpu-keep-the-MMU-lock-until-the-update-ends-v.patch
new file mode 100644
index 00000000..63039938
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/0920-drm-amdgpu-keep-the-MMU-lock-until-the-update-ends-v.patch
@@ -0,0 +1,147 @@
+From a19f5011670341975abb182247038c378baf4234 Mon Sep 17 00:00:00 2001
+From: Christian Koenig <christian.koenig@amd.com>
+Date: Mon, 11 Sep 2017 18:24:37 -0400
+Subject: [PATCH 0920/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>
+Signed-off-by: Kalyan Alle <kalyan.alle@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 | 55 +++++++++++++++++++++++++++++++++-
+ 2 files changed, 56 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+index 3c7a9bf..547fc1a 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+@@ -1221,11 +1221,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 da6ffaa..89d45aa 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
+@@ -52,6 +52,8 @@ struct amdgpu_mn {
+ /* objects protected by lock */
+ struct rw_semaphore lock;
+ struct rb_root_cached objects;
++ struct mutex read_lock;
++ atomic_t recursion;
+ };
+
+ struct amdgpu_mn_node {
+@@ -126,6 +128,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
+@@ -176,7 +206,7 @@ static void amdgpu_mn_invalidate_range_start(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) {
+@@ -191,9 +221,30 @@ static void amdgpu_mn_invalidate_range_start(struct mmu_notifier *mn,
+ up_read(&rmn->lock);
+ }
+
++/**
++ * 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);
++
++ amdgpu_mn_read_unlock(rmn);
++}
++
+ static const struct mmu_notifier_ops amdgpu_mn_ops = {
+ .release = amdgpu_mn_release,
+ .invalidate_range_start = amdgpu_mn_invalidate_range_start,
++ .invalidate_range_end = amdgpu_mn_invalidate_range_end,
+ };
+
+ /**
+@@ -231,6 +282,8 @@ struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev,
+ rmn->mn.ops = &amdgpu_mn_ops;
+ init_rwsem(&rmn->lock);
+ rmn->objects = RB_ROOT_CACHED;
++ mutex_init(&rmn->read_lock);
++ atomic_set(&rmn->recursion, 0);
+
+ r = __mmu_notifier_register(&rmn->mn, mm);
+ if (r)
+--
+2.7.4
+