summaryrefslogtreecommitdiff
path: root/mali_kbase/mali_kbase_ctx_sched.c
diff options
context:
space:
mode:
authorSidath Senanayake <sidaths@google.com>2020-06-18 09:26:13 +0200
committerSidath Senanayake <sidaths@google.com>2020-06-18 09:26:13 +0200
commitbc3c01e61c8ce9783a8ab091053905effcae12de (patch)
tree43f9f48736f7259d8cc996b11eed003dc80d5bef /mali_kbase/mali_kbase_ctx_sched.c
parentb64f568f943e567534694cc993270adca96dcd06 (diff)
downloadgpu-bc3c01e61c8ce9783a8ab091053905effcae12de.tar.gz
Mali Valhall DDK r25p0 KMD
Provenance: 395644cb0 (collaborate/EAC/v_r25p0) VX504X08X-BU-00000-r25p0-01eac0 - Android DDK VX504X08X-BU-60000-r25p0-01eac0 - Android Document Bundle Signed-off-by: Sidath Senanayake <sidaths@google.com> Change-Id: I2cffddb42a554696d45b7f65c7bae8827a71341f
Diffstat (limited to 'mali_kbase/mali_kbase_ctx_sched.c')
-rw-r--r--mali_kbase/mali_kbase_ctx_sched.c142
1 files changed, 139 insertions, 3 deletions
diff --git a/mali_kbase/mali_kbase_ctx_sched.c b/mali_kbase/mali_kbase_ctx_sched.c
index 3922260..cea91bc 100644
--- a/mali_kbase/mali_kbase_ctx_sched.c
+++ b/mali_kbase/mali_kbase_ctx_sched.c
@@ -23,7 +23,23 @@
#include <mali_kbase.h>
#include <mali_kbase_config_defaults.h>
+#include <mali_kbase_defs.h>
#include "mali_kbase_ctx_sched.h"
+#include "tl/mali_kbase_tracepoints.h"
+
+/* Helper for ktrace */
+#if KBASE_KTRACE_ENABLE
+static int kbase_ktrace_get_ctx_refcnt(struct kbase_context *kctx)
+{
+ return atomic_read(&kctx->refcount);
+}
+#else /* KBASE_KTRACE_ENABLE */
+static int kbase_ktrace_get_ctx_refcnt(struct kbase_context *kctx)
+{
+ CSTD_UNUSED(kctx);
+ return 0;
+}
+#endif /* KBASE_KTRACE_ENABLE */
int kbase_ctx_sched_init(struct kbase_device *kbdev)
{
@@ -106,11 +122,15 @@ int kbase_ctx_sched_retain_ctx(struct kbase_context *kctx)
if (prev_kctx) {
WARN_ON(atomic_read(&prev_kctx->refcount) != 0);
kbase_mmu_disable(prev_kctx);
+ KBASE_TLSTREAM_TL_KBASE_CTX_UNASSIGN_AS(
+ kbdev, prev_kctx->id);
prev_kctx->as_nr = KBASEP_AS_NR_INVALID;
}
kctx->as_nr = free_as;
kbdev->as_to_kctx[free_as] = kctx;
+ KBASE_TLSTREAM_TL_KBASE_CTX_ASSIGN_AS(
+ kbdev, kctx->id, free_as);
kbase_mmu_update(kbdev, &kctx->mmu,
kctx->as_nr);
}
@@ -142,17 +162,23 @@ void kbase_ctx_sched_retain_ctx_refcount(struct kbase_context *kctx)
void kbase_ctx_sched_release_ctx(struct kbase_context *kctx)
{
struct kbase_device *const kbdev = kctx->kbdev;
+ int new_ref_count;
lockdep_assert_held(&kbdev->hwaccess_lock);
- if (atomic_dec_return(&kctx->refcount) == 0) {
+ new_ref_count = atomic_dec_return(&kctx->refcount);
+ if (new_ref_count == 0) {
kbdev->as_free |= (1u << kctx->as_nr);
if (kbase_ctx_flag(kctx, KCTX_AS_DISABLED_ON_FAULT)) {
+ KBASE_TLSTREAM_TL_KBASE_CTX_UNASSIGN_AS(
+ kbdev, kctx->id);
kbdev->as_to_kctx[kctx->as_nr] = NULL;
kctx->as_nr = KBASEP_AS_NR_INVALID;
kbase_ctx_flag_clear(kctx, KCTX_AS_DISABLED_ON_FAULT);
}
}
+
+ KBASE_KTRACE_ADD(kbdev, SCHED_RELEASE_CTX, kctx, new_ref_count);
}
void kbase_ctx_sched_remove_ctx(struct kbase_context *kctx)
@@ -168,6 +194,7 @@ void kbase_ctx_sched_remove_ctx(struct kbase_context *kctx)
if (kbdev->pm.backend.gpu_powered)
kbase_mmu_disable(kctx);
+ KBASE_TLSTREAM_TL_KBASE_CTX_UNASSIGN_AS(kbdev, kctx->id);
kbdev->as_to_kctx[kctx->as_nr] = NULL;
kctx->as_nr = KBASEP_AS_NR_INVALID;
}
@@ -198,11 +225,120 @@ void kbase_ctx_sched_restore_all_as(struct kbase_device *kbdev)
/* This context might have been assigned an
* AS before, clear it.
*/
- kbdev->as_to_kctx[kctx->as_nr] = NULL;
- kctx->as_nr = KBASEP_AS_NR_INVALID;
+ if (kctx->as_nr != KBASEP_AS_NR_INVALID) {
+ KBASE_TLSTREAM_TL_KBASE_CTX_UNASSIGN_AS(
+ kbdev, kctx->id);
+ kbdev->as_to_kctx[kctx->as_nr] = NULL;
+ kctx->as_nr = KBASEP_AS_NR_INVALID;
+ }
}
} else {
kbase_mmu_disable_as(kbdev, i);
}
}
}
+
+struct kbase_context *kbase_ctx_sched_as_to_ctx_refcount(
+ struct kbase_device *kbdev, size_t as_nr)
+{
+ unsigned long flags;
+ struct kbase_context *found_kctx = NULL;
+
+ if (WARN_ON(kbdev == NULL))
+ return NULL;
+
+ if (WARN_ON(as_nr >= BASE_MAX_NR_AS))
+ return NULL;
+
+ spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
+
+ found_kctx = kbdev->as_to_kctx[as_nr];
+
+ if (found_kctx != NULL)
+ kbase_ctx_sched_retain_ctx_refcount(found_kctx);
+
+ spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
+
+ return found_kctx;
+}
+
+struct kbase_context *kbase_ctx_sched_as_to_ctx(struct kbase_device *kbdev,
+ size_t as_nr)
+{
+ struct kbase_context *found_kctx;
+
+ if (WARN_ON(kbdev == NULL))
+ return NULL;
+
+ if (WARN_ON(as_nr >= BASE_MAX_NR_AS))
+ return NULL;
+
+ found_kctx = kbdev->as_to_kctx[as_nr];
+
+ if (WARN_ON(!found_kctx))
+ return NULL;
+
+ if (WARN_ON(atomic_read(&found_kctx->refcount) <= 0))
+ return NULL;
+
+ return found_kctx;
+}
+
+bool kbase_ctx_sched_inc_refcount_nolock(struct kbase_context *kctx)
+{
+ bool result = false;
+ int as_nr;
+
+ if (WARN_ON(kctx == NULL))
+ return result;
+
+ lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
+
+ as_nr = kctx->as_nr;
+ if (atomic_read(&kctx->refcount) > 0) {
+ KBASE_DEBUG_ASSERT(as_nr >= 0);
+
+ kbase_ctx_sched_retain_ctx_refcount(kctx);
+ KBASE_KTRACE_ADD(kctx->kbdev, SCHED_RETAIN_CTX_NOLOCK, kctx,
+ kbase_ktrace_get_ctx_refcnt(kctx));
+ result = true;
+ }
+
+ return result;
+}
+
+bool kbase_ctx_sched_inc_refcount(struct kbase_context *kctx)
+{
+ unsigned long flags;
+ bool result = false;
+
+ if (WARN_ON(kctx == NULL))
+ return result;
+
+ if (WARN_ON(kctx->kbdev == NULL))
+ return result;
+
+ mutex_lock(&kctx->kbdev->mmu_hw_mutex);
+ spin_lock_irqsave(&kctx->kbdev->hwaccess_lock, flags);
+ result = kbase_ctx_sched_inc_refcount_nolock(kctx);
+ spin_unlock_irqrestore(&kctx->kbdev->hwaccess_lock, flags);
+ mutex_unlock(&kctx->kbdev->mmu_hw_mutex);
+
+ return result;
+}
+
+void kbase_ctx_sched_release_ctx_lock(struct kbase_context *kctx)
+{
+ unsigned long flags;
+
+ if (WARN_ON(!kctx))
+ return;
+
+ spin_lock_irqsave(&kctx->kbdev->hwaccess_lock, flags);
+
+ if (!WARN_ON(kctx->as_nr == KBASEP_AS_NR_INVALID) &&
+ !WARN_ON(atomic_read(&kctx->refcount) <= 0))
+ kbase_ctx_sched_release_ctx(kctx);
+
+ spin_unlock_irqrestore(&kctx->kbdev->hwaccess_lock, flags);
+}