hc
2024-05-16 8d2a02b24d66aa359e83eebc1ed3c0f85367a1cb
kernel/drivers/gpu/arm/bifrost/mali_kbase_ctx_sched.c
....@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
22 /*
33 *
4
- * (C) COPYRIGHT 2017-2021 ARM Limited. All rights reserved.
4
+ * (C) COPYRIGHT 2017-2023 ARM Limited. All rights reserved.
55 *
66 * This program is free software and is provided to you under the terms of the
77 * GNU General Public License version 2 as published by the Free Software
....@@ -23,6 +23,11 @@
2323 #include <mali_kbase_defs.h>
2424 #include "mali_kbase_ctx_sched.h"
2525 #include "tl/mali_kbase_tracepoints.h"
26
+#if MALI_USE_CSF
27
+#include "mali_kbase_reset_gpu.h"
28
+#else
29
+#include <mali_kbase_hwaccess_jm.h>
30
+#endif
2631
2732 /* Helper for ktrace */
2833 #if KBASE_KTRACE_ENABLE
....@@ -62,6 +67,12 @@
6267 WARN_ON(kbdev->as_to_kctx[i] != NULL);
6368 WARN_ON(!(kbdev->as_free & (1u << i)));
6469 }
70
+}
71
+
72
+void kbase_ctx_sched_init_ctx(struct kbase_context *kctx)
73
+{
74
+ kctx->as_nr = KBASEP_AS_NR_INVALID;
75
+ atomic_set(&kctx->refcount, 0);
6576 }
6677
6778 /* kbasep_ctx_sched_find_as_for_ctx - Find a free address space
....@@ -108,7 +119,7 @@
108119 if (atomic_inc_return(&kctx->refcount) == 1) {
109120 int const free_as = kbasep_ctx_sched_find_as_for_ctx(kctx);
110121
111
- if (free_as != KBASEP_AS_NR_INVALID) {
122
+ if (free_as >= 0) {
112123 kbdev->as_free &= ~(1u << free_as);
113124 /* Only program the MMU if the context has not been
114125 * assigned the same address space before.
....@@ -124,7 +135,6 @@
124135 kbdev, prev_kctx->id);
125136 prev_kctx->as_nr = KBASEP_AS_NR_INVALID;
126137 }
127
-
128138 kctx->as_nr = free_as;
129139 kbdev->as_to_kctx[free_as] = kctx;
130140 KBASE_TLSTREAM_TL_KBASE_CTX_ASSIGN_AS(
....@@ -150,9 +160,23 @@
150160 struct kbase_device *const kbdev = kctx->kbdev;
151161
152162 lockdep_assert_held(&kbdev->hwaccess_lock);
153
- WARN_ON(atomic_read(&kctx->refcount) == 0);
154
- WARN_ON(kctx->as_nr == KBASEP_AS_NR_INVALID);
155
- WARN_ON(kbdev->as_to_kctx[kctx->as_nr] != kctx);
163
+#if MALI_USE_CSF
164
+ /* We expect the context to be active when this function is called,
165
+ * except for the case where a page fault is reported for it during
166
+ * the GPU reset sequence, in which case we can expect the refcount
167
+ * to be 0.
168
+ */
169
+ WARN_ON(!atomic_read(&kctx->refcount) && !kbase_reset_gpu_is_active(kbdev));
170
+#else
171
+ /* We expect the context to be active (and thus refcount should be non-zero)
172
+ * when this function is called
173
+ */
174
+ WARN_ON(!atomic_read(&kctx->refcount));
175
+#endif
176
+ if (likely((kctx->as_nr >= 0) && (kctx->as_nr < BASE_MAX_NR_AS)))
177
+ WARN_ON(kbdev->as_to_kctx[kctx->as_nr] != kctx);
178
+ else
179
+ WARN(true, "Invalid as_nr(%d)", kctx->as_nr);
156180
157181 atomic_inc(&kctx->refcount);
158182 }
....@@ -166,13 +190,17 @@
166190
167191 new_ref_count = atomic_dec_return(&kctx->refcount);
168192 if (new_ref_count == 0) {
169
- kbdev->as_free |= (1u << kctx->as_nr);
170
- if (kbase_ctx_flag(kctx, KCTX_AS_DISABLED_ON_FAULT)) {
171
- KBASE_TLSTREAM_TL_KBASE_CTX_UNASSIGN_AS(
172
- kbdev, kctx->id);
173
- kbdev->as_to_kctx[kctx->as_nr] = NULL;
174
- kctx->as_nr = KBASEP_AS_NR_INVALID;
175
- kbase_ctx_flag_clear(kctx, KCTX_AS_DISABLED_ON_FAULT);
193
+ if (likely((kctx->as_nr >= 0) && (kctx->as_nr < BASE_MAX_NR_AS))) {
194
+ kbdev->as_free |= (1u << kctx->as_nr);
195
+ if (kbase_ctx_flag(kctx, KCTX_AS_DISABLED_ON_FAULT)) {
196
+ KBASE_TLSTREAM_TL_KBASE_CTX_UNASSIGN_AS(kbdev, kctx->id);
197
+ kbdev->as_to_kctx[kctx->as_nr] = NULL;
198
+ kctx->as_nr = KBASEP_AS_NR_INVALID;
199
+ kbase_ctx_flag_clear(kctx, KCTX_AS_DISABLED_ON_FAULT);
200
+#if !MALI_USE_CSF
201
+ kbase_backend_slot_kctx_purge_locked(kbdev, kctx);
202
+#endif
203
+ }
176204 }
177205 }
178206
....@@ -182,13 +210,14 @@
182210 void kbase_ctx_sched_remove_ctx(struct kbase_context *kctx)
183211 {
184212 struct kbase_device *const kbdev = kctx->kbdev;
213
+ unsigned long flags;
185214
186
- lockdep_assert_held(&kbdev->mmu_hw_mutex);
187
- lockdep_assert_held(&kbdev->hwaccess_lock);
215
+ mutex_lock(&kbdev->mmu_hw_mutex);
216
+ spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
188217
189218 WARN_ON(atomic_read(&kctx->refcount) != 0);
190219
191
- if (kctx->as_nr != KBASEP_AS_NR_INVALID) {
220
+ if ((kctx->as_nr >= 0) && (kctx->as_nr < BASE_MAX_NR_AS)) {
192221 if (kbdev->pm.backend.gpu_powered)
193222 kbase_mmu_disable(kctx);
194223
....@@ -196,6 +225,9 @@
196225 kbdev->as_to_kctx[kctx->as_nr] = NULL;
197226 kctx->as_nr = KBASEP_AS_NR_INVALID;
198227 }
228
+
229
+ spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
230
+ mutex_unlock(&kbdev->mmu_hw_mutex);
199231 }
200232
201233 void kbase_ctx_sched_restore_all_as(struct kbase_device *kbdev)
....@@ -210,6 +242,7 @@
210242 for (i = 0; i != kbdev->nr_hw_address_spaces; ++i) {
211243 struct kbase_context *kctx;
212244
245
+ kbdev->as[i].is_unresponsive = false;
213246 #if MALI_USE_CSF
214247 if ((i == MCU_AS_NR) && kbdev->csf.firmware_inited) {
215248 kbase_mmu_update(kbdev, &kbdev->csf.mcu_mmu,
....@@ -308,16 +341,14 @@
308341 bool kbase_ctx_sched_inc_refcount_nolock(struct kbase_context *kctx)
309342 {
310343 bool result = false;
311
- int as_nr;
312344
313345 if (WARN_ON(kctx == NULL))
314346 return result;
315347
316348 lockdep_assert_held(&kctx->kbdev->hwaccess_lock);
317349
318
- as_nr = kctx->as_nr;
319350 if (atomic_read(&kctx->refcount) > 0) {
320
- KBASE_DEBUG_ASSERT(as_nr >= 0);
351
+ KBASE_DEBUG_ASSERT(kctx->as_nr >= 0);
321352
322353 kbase_ctx_sched_retain_ctx_refcount(kctx);
323354 KBASE_KTRACE_ADD(kctx->kbdev, SCHED_RETAIN_CTX_NOLOCK, kctx,