forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/gpu/arm/bifrost/tl/mali_kbase_timeline.c
....@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
22 /*
33 *
4
- * (C) COPYRIGHT 2015-2021 ARM Limited. All rights reserved.
4
+ * (C) COPYRIGHT 2015-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
....@@ -24,9 +24,6 @@
2424 #include "mali_kbase_tracepoints.h"
2525
2626 #include <mali_kbase.h>
27
-#include <mali_kbase_jm.h>
28
-
29
-#include <linux/anon_inodes.h>
3027 #include <linux/atomic.h>
3128 #include <linux/file.h>
3229 #include <linux/mutex.h>
....@@ -35,7 +32,7 @@
3532 #include <linux/stringify.h>
3633 #include <linux/timer.h>
3734 #include <linux/wait.h>
38
-
35
+#include <linux/delay.h>
3936
4037 /* The period of autoflush checker execution in milliseconds. */
4138 #define AUTOFLUSH_INTERVAL 1000 /* ms */
....@@ -184,88 +181,109 @@
184181 }
185182 #endif /* CONFIG_MALI_BIFROST_DEVFREQ */
186183
187
-int kbase_timeline_io_acquire(struct kbase_device *kbdev, u32 flags)
184
+int kbase_timeline_acquire(struct kbase_device *kbdev, u32 flags)
188185 {
189
- int ret = 0;
186
+ int err = 0;
190187 u32 timeline_flags = TLSTREAM_ENABLED | flags;
191
- struct kbase_timeline *timeline = kbdev->timeline;
188
+ struct kbase_timeline *timeline;
189
+ int rcode;
192190
193
- if (!atomic_cmpxchg(timeline->timeline_flags, 0, timeline_flags)) {
194
- int rcode;
191
+ if (WARN_ON(!kbdev) || WARN_ON(flags & ~BASE_TLSTREAM_FLAGS_MASK))
192
+ return -EINVAL;
193
+
194
+ timeline = kbdev->timeline;
195
+ if (WARN_ON(!timeline))
196
+ return -EFAULT;
197
+
198
+ if (atomic_cmpxchg(timeline->timeline_flags, 0, timeline_flags))
199
+ return -EBUSY;
195200
196201 #if MALI_USE_CSF
197
- if (flags & BASE_TLSTREAM_ENABLE_CSFFW_TRACEPOINTS) {
198
- ret = kbase_csf_tl_reader_start(
199
- &timeline->csf_tl_reader, kbdev);
200
- if (ret)
201
- {
202
- atomic_set(timeline->timeline_flags, 0);
203
- return ret;
204
- }
205
- }
206
-#endif
207
- ret = anon_inode_getfd(
208
- "[mali_tlstream]",
209
- &kbasep_tlstream_fops,
210
- timeline,
211
- O_RDONLY | O_CLOEXEC);
212
- if (ret < 0) {
202
+ if (flags & BASE_TLSTREAM_ENABLE_CSFFW_TRACEPOINTS) {
203
+ err = kbase_csf_tl_reader_start(&timeline->csf_tl_reader, kbdev);
204
+ if (err) {
213205 atomic_set(timeline->timeline_flags, 0);
214
-#if MALI_USE_CSF
215
- kbase_csf_tl_reader_stop(&timeline->csf_tl_reader);
216
-#endif
217
- return ret;
206
+ return err;
218207 }
208
+ }
209
+#endif
219210
220
- /* Reset and initialize header streams. */
221
- kbase_tlstream_reset(
222
- &timeline->streams[TL_STREAM_TYPE_OBJ_SUMMARY]);
211
+ /* Reset and initialize header streams. */
212
+ kbase_tlstream_reset(&timeline->streams[TL_STREAM_TYPE_OBJ_SUMMARY]);
223213
224
- timeline->obj_header_btc = obj_desc_header_size;
225
- timeline->aux_header_btc = aux_desc_header_size;
226
-
227
- /* Start autoflush timer. */
228
- atomic_set(&timeline->autoflush_timer_active, 1);
229
- rcode = mod_timer(
230
- &timeline->autoflush_timer,
231
- jiffies + msecs_to_jiffies(AUTOFLUSH_INTERVAL));
232
- CSTD_UNUSED(rcode);
214
+ timeline->obj_header_btc = obj_desc_header_size;
215
+ timeline->aux_header_btc = aux_desc_header_size;
233216
234217 #if !MALI_USE_CSF
235
- /* If job dumping is enabled, readjust the software event's
236
- * timeout as the default value of 3 seconds is often
237
- * insufficient.
238
- */
239
- if (flags & BASE_TLSTREAM_JOB_DUMPING_ENABLED) {
240
- dev_info(kbdev->dev,
241
- "Job dumping is enabled, readjusting the software event's timeout\n");
242
- atomic_set(&kbdev->js_data.soft_job_timeout_ms,
243
- 1800000);
244
- }
218
+ /* If job dumping is enabled, readjust the software event's
219
+ * timeout as the default value of 3 seconds is often
220
+ * insufficient.
221
+ */
222
+ if (flags & BASE_TLSTREAM_JOB_DUMPING_ENABLED) {
223
+ dev_info(kbdev->dev,
224
+ "Job dumping is enabled, readjusting the software event's timeout\n");
225
+ atomic_set(&kbdev->js_data.soft_job_timeout_ms, 1800000);
226
+ }
245227 #endif /* !MALI_USE_CSF */
246228
247
- /* Summary stream was cleared during acquire.
248
- * Create static timeline objects that will be
249
- * read by client.
250
- */
251
- kbase_create_timeline_objects(kbdev);
229
+ /* Summary stream was cleared during acquire.
230
+ * Create static timeline objects that will be
231
+ * read by client.
232
+ */
233
+ kbase_create_timeline_objects(kbdev);
252234
253235 #ifdef CONFIG_MALI_BIFROST_DEVFREQ
254
- /* Devfreq target tracepoints are only fired when the target
255
- * changes, so we won't know the current target unless we
256
- * send it now.
257
- */
258
- kbase_tlstream_current_devfreq_target(kbdev);
236
+ /* Devfreq target tracepoints are only fired when the target
237
+ * changes, so we won't know the current target unless we
238
+ * send it now.
239
+ */
240
+ kbase_tlstream_current_devfreq_target(kbdev);
259241 #endif /* CONFIG_MALI_BIFROST_DEVFREQ */
260242
261
- } else {
262
- ret = -EBUSY;
263
- }
243
+ /* Start the autoflush timer.
244
+ * We must do this after creating timeline objects to ensure we
245
+ * don't auto-flush the streams which will be reset during the
246
+ * summarization process.
247
+ */
248
+ atomic_set(&timeline->autoflush_timer_active, 1);
249
+ rcode = mod_timer(&timeline->autoflush_timer,
250
+ jiffies + msecs_to_jiffies(AUTOFLUSH_INTERVAL));
251
+ CSTD_UNUSED(rcode);
264252
265
- if (ret >= 0)
266
- timeline->last_acquire_time = ktime_get();
253
+ timeline->last_acquire_time = ktime_get_raw();
267254
268
- return ret;
255
+ return err;
256
+}
257
+
258
+void kbase_timeline_release(struct kbase_timeline *timeline)
259
+{
260
+ ktime_t elapsed_time;
261
+ s64 elapsed_time_ms, time_to_sleep;
262
+
263
+ if (WARN_ON(!timeline) || WARN_ON(!atomic_read(timeline->timeline_flags)))
264
+ return;
265
+
266
+ /* Get the amount of time passed since the timeline was acquired and ensure
267
+ * we sleep for long enough such that it has been at least
268
+ * TIMELINE_HYSTERESIS_TIMEOUT_MS amount of time between acquire and release.
269
+ * This prevents userspace from spamming acquire and release too quickly.
270
+ */
271
+ elapsed_time = ktime_sub(ktime_get_raw(), timeline->last_acquire_time);
272
+ elapsed_time_ms = ktime_to_ms(elapsed_time);
273
+ time_to_sleep = (elapsed_time_ms < 0 ? TIMELINE_HYSTERESIS_TIMEOUT_MS :
274
+ TIMELINE_HYSTERESIS_TIMEOUT_MS - elapsed_time_ms);
275
+ if (time_to_sleep > 0)
276
+ msleep_interruptible(time_to_sleep);
277
+
278
+#if MALI_USE_CSF
279
+ kbase_csf_tl_reader_stop(&timeline->csf_tl_reader);
280
+#endif
281
+
282
+ /* Stop autoflush timer before releasing access to streams. */
283
+ atomic_set(&timeline->autoflush_timer_active, 0);
284
+ del_timer_sync(&timeline->autoflush_timer);
285
+
286
+ atomic_set(timeline->timeline_flags, 0);
269287 }
270288
271289 int kbase_timeline_streams_flush(struct kbase_timeline *timeline)
....@@ -273,11 +291,17 @@
273291 enum tl_stream_type stype;
274292 bool has_bytes = false;
275293 size_t nbytes = 0;
276
-#if MALI_USE_CSF
277
- int ret = kbase_csf_tl_reader_flush_buffer(&timeline->csf_tl_reader);
278294
279
- if (ret > 0)
280
- has_bytes = true;
295
+ if (WARN_ON(!timeline))
296
+ return -EINVAL;
297
+
298
+#if MALI_USE_CSF
299
+ {
300
+ int ret = kbase_csf_tl_reader_flush_buffer(&timeline->csf_tl_reader);
301
+
302
+ if (ret > 0)
303
+ has_bytes = true;
304
+ }
281305 #endif
282306
283307 for (stype = 0; stype < TL_STREAM_TYPE_COUNT; stype++) {