hc
2024-05-16 8d2a02b24d66aa359e83eebc1ed3c0f85367a1cb
kernel/drivers/gpu/arm/bifrost/mali_kbase_vinstr.c
....@@ -1,7 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
22 /*
33 *
4
- * (C) COPYRIGHT 2011-2021 ARM Limited. All rights reserved.
4
+ * (C) COPYRIGHT 2011-2022 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
....@@ -20,10 +20,11 @@
2020 */
2121
2222 #include "mali_kbase_vinstr.h"
23
-#include "mali_kbase_hwcnt_virtualizer.h"
24
-#include "mali_kbase_hwcnt_types.h"
23
+#include "hwcnt/mali_kbase_hwcnt_virtualizer.h"
24
+#include "hwcnt/mali_kbase_hwcnt_types.h"
2525 #include <uapi/gpu/arm/bifrost/mali_kbase_hwcnt_reader.h>
26
-#include "mali_kbase_hwcnt_gpu.h"
26
+#include "hwcnt/mali_kbase_hwcnt_gpu.h"
27
+#include "hwcnt/mali_kbase_hwcnt_gpu_narrow.h"
2728 #include <uapi/gpu/arm/bifrost/mali_kbase_ioctl.h>
2829 #include "mali_malisw.h"
2930 #include "mali_kbase_debug.h"
....@@ -37,7 +38,13 @@
3738 #include <linux/mutex.h>
3839 #include <linux/poll.h>
3940 #include <linux/slab.h>
41
+#include <linux/version_compat_defs.h>
4042 #include <linux/workqueue.h>
43
+
44
+/* Explicitly include epoll header for old kernels. Not required from 4.16. */
45
+#if KERNEL_VERSION(4, 16, 0) > LINUX_VERSION_CODE
46
+#include <uapi/linux/eventpoll.h>
47
+#endif
4148
4249 /* Hwcnt reader API version */
4350 #define HWCNT_READER_API 1
....@@ -55,8 +62,8 @@
5562 * @metadata: Hardware counter metadata provided by virtualizer.
5663 * @metadata_user: API compatible hardware counter metadata provided by vinstr.
5764 * For compatibility with the user driver interface, this
58
- * contains a "truncated" version of the HWCNT metadata limited
59
- * to 64 entries per block. NULL when not required.
65
+ * contains a narrowed version of the HWCNT metadata limited
66
+ * to 64 entries per block of 32 bits each.
6067 * @lock: Lock protecting all vinstr state.
6168 * @suspend_count: Suspend reference count. If non-zero, timer and worker are
6269 * prevented from being re-scheduled.
....@@ -68,7 +75,7 @@
6875 struct kbase_vinstr_context {
6976 struct kbase_hwcnt_virtualizer *hvirt;
7077 const struct kbase_hwcnt_metadata *metadata;
71
- const struct kbase_hwcnt_metadata *metadata_user;
78
+ const struct kbase_hwcnt_metadata_narrow *metadata_user;
7279 struct mutex lock;
7380 size_t suspend_count;
7481 size_t client_count;
....@@ -89,8 +96,8 @@
8996 * occur. If 0, not a periodic client.
9097 * @enable_map: Counters enable map.
9198 * @tmp_buf: Temporary buffer to use before handing dump to client.
92
- * @dump_bufs: Array of dump buffers allocated by this client.
93
- * @dump_bufs_meta: Metadata of dump buffers.
99
+ * @dump_bufs: Array of narrow dump buffers allocated by this client.
100
+ * @dump_bufs_meta: Metadata of hwcnt reader client buffers.
94101 * @meta_idx: Index of metadata being accessed by userspace.
95102 * @read_idx: Index of buffer read by userspace.
96103 * @write_idx: Index of buffer being written by dump worker.
....@@ -104,7 +111,7 @@
104111 u32 dump_interval_ns;
105112 struct kbase_hwcnt_enable_map enable_map;
106113 struct kbase_hwcnt_dump_buffer tmp_buf;
107
- struct kbase_hwcnt_dump_buffer_array dump_bufs;
114
+ struct kbase_hwcnt_dump_buffer_narrow_array dump_bufs;
108115 struct kbase_hwcnt_reader_metadata *dump_bufs_meta;
109116 atomic_t meta_idx;
110117 atomic_t read_idx;
....@@ -112,9 +119,7 @@
112119 wait_queue_head_t waitq;
113120 };
114121
115
-static unsigned int kbasep_vinstr_hwcnt_reader_poll(
116
- struct file *filp,
117
- poll_table *wait);
122
+static __poll_t kbasep_vinstr_hwcnt_reader_poll(struct file *filp, poll_table *wait);
118123
119124 static long kbasep_vinstr_hwcnt_reader_ioctl(
120125 struct file *filp,
....@@ -190,7 +195,7 @@
190195 unsigned int write_idx;
191196 unsigned int read_idx;
192197 struct kbase_hwcnt_dump_buffer *tmp_buf;
193
- struct kbase_hwcnt_dump_buffer *dump_buf;
198
+ struct kbase_hwcnt_dump_buffer_narrow *dump_buf;
194199 struct kbase_hwcnt_reader_metadata *meta;
195200 u8 clk_cnt;
196201
....@@ -223,17 +228,11 @@
223228 * variant will explicitly zero any non-enabled counters to ensure
224229 * nothing except exactly what the user asked for is made visible.
225230 *
226
- * If the metadata in vinstr (vctx->metadata_user) is not NULL, it means
227
- * vinstr has the truncated metadata, so do a narrow copy since
228
- * virtualizer has a bigger buffer but user only needs part of it.
229
- * otherwise we do a full copy.
231
+ * A narrow copy is required since virtualizer has a bigger buffer
232
+ * but user only needs part of it.
230233 */
231
- if (vcli->vctx->metadata_user)
232
- kbase_hwcnt_dump_buffer_copy_strict_narrow(dump_buf, tmp_buf,
233
- &vcli->enable_map);
234
- else
235
- kbase_hwcnt_dump_buffer_copy_strict(dump_buf, tmp_buf,
236
- &vcli->enable_map);
234
+ kbase_hwcnt_dump_buffer_copy_strict_narrow(dump_buf, tmp_buf,
235
+ &vcli->enable_map);
237236
238237 clk_cnt = vcli->vctx->metadata->clk_cnt;
239238
....@@ -362,6 +361,8 @@
362361 * kbasep_vinstr_dump_timer() - Dump timer that schedules the dump worker for
363362 * execution as soon as possible.
364363 * @timer: Timer structure.
364
+ *
365
+ * Return: HRTIMER_NORESTART always.
365366 */
366367 static enum hrtimer_restart kbasep_vinstr_dump_timer(struct hrtimer *timer)
367368 {
....@@ -388,7 +389,7 @@
388389
389390 kbase_hwcnt_virtualizer_client_destroy(vcli->hvcli);
390391 kfree(vcli->dump_bufs_meta);
391
- kbase_hwcnt_dump_buffer_array_free(&vcli->dump_bufs);
392
+ kbase_hwcnt_dump_buffer_narrow_array_free(&vcli->dump_bufs);
392393 kbase_hwcnt_dump_buffer_free(&vcli->tmp_buf);
393394 kbase_hwcnt_enable_map_free(&vcli->enable_map);
394395 kfree(vcli);
....@@ -446,20 +447,11 @@
446447 /* Enable all the available clk_enable_map. */
447448 vcli->enable_map.clk_enable_map = (1ull << vctx->metadata->clk_cnt) - 1;
448449
449
- if (vctx->metadata_user)
450
- /* Use vinstr's truncated metadata to alloc dump buffers which
451
- * interact with clients.
452
- */
453
- errcode =
454
- kbase_hwcnt_dump_buffer_array_alloc(vctx->metadata_user,
455
- setup->buffer_count,
456
- &vcli->dump_bufs);
457
- else
458
- /* Use metadata from virtualizer to allocate dump buffers if
459
- * vinstr doesn't have the truncated metadata.
460
- */
461
- errcode = kbase_hwcnt_dump_buffer_array_alloc(
462
- vctx->metadata, setup->buffer_count, &vcli->dump_bufs);
450
+ /* Use vinstr's narrowed metadata to alloc narrow dump buffers which
451
+ * interact with clients.
452
+ */
453
+ errcode = kbase_hwcnt_dump_buffer_narrow_array_alloc(
454
+ vctx->metadata_user, setup->buffer_count, &vcli->dump_bufs);
463455 if (errcode)
464456 goto error;
465457
....@@ -504,9 +496,8 @@
504496
505497 vctx->hvirt = hvirt;
506498 vctx->metadata = metadata;
507
- vctx->metadata_user = NULL;
508
- errcode = kbase_hwcnt_gpu_metadata_create_truncate_64(
509
- &vctx->metadata_user, metadata);
499
+ errcode = kbase_hwcnt_gpu_metadata_narrow_create(&vctx->metadata_user,
500
+ metadata);
510501 if (errcode)
511502 goto err_metadata_create;
512503
....@@ -530,8 +521,6 @@
530521 if (!vctx)
531522 return;
532523
533
- cancel_work_sync(&vctx->dump_work);
534
-
535524 /* Non-zero client count implies client leak */
536525 if (WARN_ON(vctx->client_count != 0)) {
537526 struct kbase_vinstr_client *pos, *n;
....@@ -543,8 +532,8 @@
543532 }
544533 }
545534
546
- if (vctx->metadata_user)
547
- kbase_hwcnt_metadata_destroy(vctx->metadata_user);
535
+ cancel_work_sync(&vctx->dump_work);
536
+ kbase_hwcnt_gpu_metadata_narrow_destroy(vctx->metadata_user);
548537
549538 WARN_ON(vctx->client_count != 0);
550539 kfree(vctx);
....@@ -930,12 +919,13 @@
930919 }
931920
932921 /**
933
- * The hwcnt reader's ioctl command - get API version.
922
+ * kbasep_vinstr_hwcnt_reader_ioctl_get_api_version() - get API version ioctl
923
+ * command.
934924 * @cli: The non-NULL pointer to the client
935925 * @arg: Command's argument.
936926 * @size: Size of arg.
937927 *
938
- * @return 0 on success, else error code.
928
+ * Return: 0 on success, else error code.
939929 */
940930 static long kbasep_vinstr_hwcnt_reader_ioctl_get_api_version(
941931 struct kbase_vinstr_client *cli, unsigned long arg, size_t size)
....@@ -1006,14 +996,8 @@
1006996 cli, (u32 __user *)arg);
1007997 break;
1008998 case _IOC_NR(KBASE_HWCNT_READER_GET_BUFFER_SIZE):
1009
- if (cli->vctx->metadata_user)
1010
- rcode = put_user(
1011
- (u32)cli->vctx->metadata_user->dump_buf_bytes,
1012
- (u32 __user *)arg);
1013
- else
1014
- rcode = put_user(
1015
- (u32)cli->vctx->metadata->dump_buf_bytes,
1016
- (u32 __user *)arg);
999
+ rcode = put_user((u32)cli->vctx->metadata_user->dump_buf_bytes,
1000
+ (u32 __user *)arg);
10171001 break;
10181002 case _IOC_NR(KBASE_HWCNT_READER_DUMP):
10191003 rcode = kbasep_vinstr_hwcnt_reader_ioctl_dump(cli);
....@@ -1055,26 +1039,25 @@
10551039 * @filp: Non-NULL pointer to file structure.
10561040 * @wait: Non-NULL pointer to poll table.
10571041 *
1058
- * Return: POLLIN if data can be read without blocking, 0 if data can not be
1059
- * read without blocking, else error code.
1042
+ * Return: EPOLLIN | EPOLLRDNORM if data can be read without blocking, 0 if
1043
+ * data can not be read without blocking, else EPOLLHUP | EPOLLERR.
10601044 */
1061
-static unsigned int kbasep_vinstr_hwcnt_reader_poll(
1062
- struct file *filp,
1063
- poll_table *wait)
1045
+static __poll_t kbasep_vinstr_hwcnt_reader_poll(struct file *filp, poll_table *wait)
10641046 {
10651047 struct kbase_vinstr_client *cli;
10661048
10671049 if (!filp || !wait)
1068
- return -EINVAL;
1050
+ return EPOLLHUP | EPOLLERR;
10691051
10701052 cli = filp->private_data;
10711053 if (!cli)
1072
- return -EINVAL;
1054
+ return EPOLLHUP | EPOLLERR;
10731055
10741056 poll_wait(filp, &cli->waitq, wait);
10751057 if (kbasep_vinstr_hwcnt_reader_buffer_ready(cli))
1076
- return POLLIN;
1077
- return 0;
1058
+ return EPOLLIN | EPOLLRDNORM;
1059
+
1060
+ return (__poll_t)0;
10781061 }
10791062
10801063 /**