1 // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
2 /*
3 *
4 * (C) COPYRIGHT 2021 ARM Limited. All rights reserved.
5 *
6 * This program is free software and is provided to you under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation, and any use by you of this program is subject to the terms
9 * of such GNU license.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you can access it online at
18 * http://www.gnu.org/licenses/gpl-2.0.html.
19 *
20 */
21
22 #include "mali_kbase.h"
23 #include "mali_kbase_kinstr_prfcnt.h"
24 #include "mali_kbase_hwcnt_virtualizer.h"
25 #include "mali_kbase_hwcnt_types.h"
26 #include "mali_kbase_hwcnt_gpu.h"
27 #include <uapi/gpu/arm/bifrost/mali_kbase_ioctl.h>
28 #include "mali_malisw.h"
29 #include "mali_kbase_debug.h"
30
31 #include <linux/anon_inodes.h>
32 #include <linux/fcntl.h>
33 #include <linux/fs.h>
34 #include <linux/hrtimer.h>
35 #include <linux/log2.h>
36 #include <linux/mm.h>
37 #include <linux/mutex.h>
38 #include <linux/poll.h>
39 #include <linux/slab.h>
40 #include <linux/workqueue.h>
41
42 /* The minimum allowed interval between dumps, in nanoseconds
43 * (equivalent to 10KHz)
44 */
45 #define DUMP_INTERVAL_MIN_NS (100 * NSEC_PER_USEC)
46
47 /* The maximum allowed buffers per client */
48 #define MAX_BUFFER_COUNT 32
49
50 /* The module printing prefix */
51 #define KINSTR_PRFCNT_PREFIX "mali_kbase_kinstr_prfcnt: "
52
53 /**
54 * struct kbase_kinstr_prfcnt_context - IOCTL interface for userspace hardware
55 * counters.
56 * @hvirt: Hardware counter virtualizer used by kinstr_prfcnt.
57 * @info_item_count: Number of metadata elements.
58 * @metadata: Hardware counter metadata provided by virtualizer.
59 * @lock: Lock protecting kinstr_prfcnt state.
60 * @suspend_count: Suspend reference count. If non-zero, timer and worker
61 * are prevented from being re-scheduled.
62 * @client_count: Number of kinstr_prfcnt clients.
63 * @clients: List of kinstr_prfcnt clients.
64 * @dump_timer: Timer that enqueues dump_work to a workqueue.
65 * @dump_work: Worker for performing periodic counter dumps.
66 */
67 struct kbase_kinstr_prfcnt_context {
68 struct kbase_hwcnt_virtualizer *hvirt;
69 u32 info_item_count;
70 const struct kbase_hwcnt_metadata *metadata;
71 struct mutex lock;
72 size_t suspend_count;
73 size_t client_count;
74 struct list_head clients;
75 struct hrtimer dump_timer;
76 struct work_struct dump_work;
77 };
78
79 /**
80 * struct kbase_kinstr_prfcnt_sample - Buffer and descriptor for sample data.
81 * @sample_meta: Pointer to sample metadata.
82 * @dump_buf: Dump buffer containing sample data.
83 */
84 struct kbase_kinstr_prfcnt_sample {
85 struct prfcnt_metadata *sample_meta;
86 struct kbase_hwcnt_dump_buffer dump_buf;
87 };
88
89 /**
90 * struct kbase_kinstr_prfcnt_sample_array - Array of sample data.
91 * @page_addr: Address of allocated pages. A single allocation is used
92 * for all Dump Buffers in the array.
93 * @page_order: The allocation order of the pages, the order is on a
94 * logarithmic scale.
95 * @sample_count: Number of allocated samples.
96 * @samples: Non-NULL pointer to the array of Dump Buffers.
97 */
98 struct kbase_kinstr_prfcnt_sample_array {
99 u64 page_addr;
100 unsigned int page_order;
101 size_t sample_count;
102 struct kbase_kinstr_prfcnt_sample *samples;
103 };
104
105 /**
106 * struct kbase_kinstr_prfcnt_client_config - Client session configuration.
107 * @prfcnt_mode: Sampling mode: either manual or periodic.
108 * @counter_set: Set of performance counter blocks.
109 * @scope: Scope of performance counters to capture.
110 * @buffer_count: Number of buffers used to store samples.
111 * @period_ns: Sampling period, in nanoseconds, or 0 if manual mode.
112 * @phys_em: Enable map used by the GPU.
113 */
114 struct kbase_kinstr_prfcnt_client_config {
115 u8 prfcnt_mode;
116 u8 counter_set;
117 u8 scope;
118 u16 buffer_count;
119 u64 period_ns;
120 struct kbase_hwcnt_physical_enable_map phys_em;
121 };
122
123 /**
124 * struct kbase_kinstr_prfcnt_async - Asynchronous sampling operation to
125 * carry out for a kinstr_prfcnt_client.
126 * @dump_work: Worker for performing asynchronous counter dumps.
127 * @user_data: User data for asynchronous dump in progress.
128 * @ts_end_ns: End timestamp of most recent async dump.
129 */
130 struct kbase_kinstr_prfcnt_async {
131 struct work_struct dump_work;
132 u64 user_data;
133 u64 ts_end_ns;
134 };
135
136 /**
137 * struct kbase_kinstr_prfcnt_client - A kinstr_prfcnt client attached
138 * to a kinstr_prfcnt context.
139 * @kinstr_ctx: kinstr_prfcnt context client is attached to.
140 * @hvcli: Hardware counter virtualizer client.
141 * @node: Node used to attach this client to list in
142 * kinstr_prfcnt context.
143 * @cmd_sync_lock: Lock coordinating the reader interface for commands
144 * that need interacting with the async sample dump
145 * worker thread.
146 * @next_dump_time_ns: Time in ns when this client's next periodic dump must
147 * occur. If 0, not a periodic client.
148 * @dump_interval_ns: Interval between periodic dumps. If 0, not a periodic
149 * client.
150 * @sample_flags: Flags for the current active dumping sample, marking
151 * the conditions/events during the dump duration.
152 * @active: True if the client has been started.
153 * @config: Configuration of the client session.
154 * @enable_map: Counters enable map.
155 * @tmp_buf: Temporary buffer to use before handing over dump to
156 * client.
157 * @sample_arr: Array of dump buffers allocated by this client.
158 * @read_idx: Index of buffer read by userspace.
159 * @write_idx: Index of buffer being written by dump worker.
160 * @waitq: Client's notification queue.
161 * @sample_size: Size of the data required for one sample, in bytes.
162 * @sample_count: Number of samples the client is able to capture.
163 * @sync_sample_count: Number of available spaces for synchronous samples.
164 * It can differ from sample_count if asynchronous
165 * sample requests are reserving space in the buffer.
166 * @user_data: User data associated with the session.
167 * This is set when the session is started and stopped.
168 * This value is ignored for control commands that
169 * provide another value.
170 * @async: Asynchronous sampling operations to carry out in this
171 * client's session.
172 */
173 struct kbase_kinstr_prfcnt_client {
174 struct kbase_kinstr_prfcnt_context *kinstr_ctx;
175 struct kbase_hwcnt_virtualizer_client *hvcli;
176 struct list_head node;
177 struct mutex cmd_sync_lock;
178 u64 next_dump_time_ns;
179 u32 dump_interval_ns;
180 u32 sample_flags;
181 bool active;
182 struct kbase_kinstr_prfcnt_client_config config;
183 struct kbase_hwcnt_enable_map enable_map;
184 struct kbase_hwcnt_dump_buffer tmp_buf;
185 struct kbase_kinstr_prfcnt_sample_array sample_arr;
186 atomic_t read_idx;
187 atomic_t write_idx;
188 wait_queue_head_t waitq;
189 size_t sample_size;
190 size_t sample_count;
191 atomic_t sync_sample_count;
192 u64 user_data;
193 struct kbase_kinstr_prfcnt_async async;
194 };
195
196 static struct prfcnt_enum_item kinstr_prfcnt_supported_requests[] = {
197 {
198 /* Request description for MODE request */
199 .hdr = {
200 .item_type = PRFCNT_ENUM_TYPE_REQUEST,
201 .item_version = PRFCNT_READER_API_VERSION,
202 },
203 .u.request = {
204 .request_item_type = PRFCNT_REQUEST_MODE,
205 .versions_mask = 0x1,
206 },
207 },
208 {
209 /* Request description for ENABLE request */
210 .hdr = {
211 .item_type = PRFCNT_ENUM_TYPE_REQUEST,
212 .item_version = PRFCNT_READER_API_VERSION,
213 },
214 .u.request = {
215 .request_item_type = PRFCNT_REQUEST_ENABLE,
216 .versions_mask = 0x1,
217 },
218 },
219 };
220
221 /**
222 * kbasep_kinstr_prfcnt_hwcnt_reader_poll() - hwcnt reader's poll.
223 * @filp: Non-NULL pointer to file structure.
224 * @wait: Non-NULL pointer to poll table.
225 *
226 * Return: POLLIN if data can be read without blocking, 0 if data can not be
227 * read without blocking, else error code.
228 */
229 #if KERNEL_VERSION(4, 16, 0) >= LINUX_VERSION_CODE
230 static unsigned int
kbasep_kinstr_prfcnt_hwcnt_reader_poll(struct file * filp,struct poll_table_struct * wait)231 kbasep_kinstr_prfcnt_hwcnt_reader_poll(struct file *filp,
232 struct poll_table_struct *wait)
233 #else
234 static __poll_t
235 kbasep_kinstr_prfcnt_hwcnt_reader_poll(struct file *filp,
236 struct poll_table_struct *wait)
237 #endif
238 {
239 struct kbase_kinstr_prfcnt_client *cli;
240
241 if (!filp || !wait)
242 return -EINVAL;
243
244 cli = filp->private_data;
245
246 if (!cli)
247 return -EINVAL;
248
249 poll_wait(filp, &cli->waitq, wait);
250
251 if (atomic_read(&cli->write_idx) != atomic_read(&cli->read_idx))
252 return POLLIN;
253
254 return 0;
255 }
256
257 /**
258 * kbasep_kinstr_prfcnt_next_dump_time_ns() - Calculate the next periodic
259 * dump time.
260 * @cur_ts_ns: Current time in nanoseconds.
261 * @interval: Interval between dumps in nanoseconds.
262 *
263 * Return: 0 if interval is 0 (i.e. a non-periodic client), or the next dump
264 * time that occurs after cur_ts_ns.
265 */
kbasep_kinstr_prfcnt_next_dump_time_ns(u64 cur_ts_ns,u32 interval)266 static u64 kbasep_kinstr_prfcnt_next_dump_time_ns(u64 cur_ts_ns, u32 interval)
267 {
268 /* Non-periodic client */
269 if (interval == 0)
270 return 0;
271
272 /*
273 * Return the next interval after the current time relative to t=0.
274 * This means multiple clients with the same period will synchronize,
275 * regardless of when they were started, allowing the worker to be
276 * scheduled less frequently.
277 */
278 do_div(cur_ts_ns, interval);
279
280 return (cur_ts_ns + 1) * interval;
281 }
282
283 /**
284 * kbasep_kinstr_prfcnt_timestamp_ns() - Get the current time in nanoseconds.
285 *
286 * Return: Current time in nanoseconds.
287 */
kbasep_kinstr_prfcnt_timestamp_ns(void)288 static u64 kbasep_kinstr_prfcnt_timestamp_ns(void)
289 {
290 return ktime_get_raw_ns();
291 }
292
293 /**
294 * kbasep_kinstr_prfcnt_reschedule_worker() - Update next dump times for all
295 * periodic kinstr_prfcnt clients,
296 * then reschedule the dump worker
297 * appropriately.
298 * @kinstr_ctx: Non-NULL pointer to the kinstr_prfcnt context.
299 *
300 * If there are no periodic clients, then the dump worker will not be
301 * rescheduled. Else, the dump worker will be rescheduled for the next
302 * periodic client dump.
303 */
kbasep_kinstr_prfcnt_reschedule_worker(struct kbase_kinstr_prfcnt_context * kinstr_ctx)304 static void kbasep_kinstr_prfcnt_reschedule_worker(
305 struct kbase_kinstr_prfcnt_context *kinstr_ctx)
306 {
307 u64 cur_ts_ns;
308 u64 shortest_period_ns = U64_MAX;
309 struct kbase_kinstr_prfcnt_client *pos;
310
311 WARN_ON(!kinstr_ctx);
312 lockdep_assert_held(&kinstr_ctx->lock);
313 cur_ts_ns = kbasep_kinstr_prfcnt_timestamp_ns();
314
315 /*
316 * This loop fulfills 2 separate tasks that don't affect each other:
317 *
318 * 1) Determine the shortest period.
319 * 2) Update the next dump time of clients that have already been
320 * dumped. It's important not to alter the next dump time of clients
321 * that haven't been dumped yet.
322 *
323 * For the sake of efficiency, the rescheduling decision ignores the time
324 * of the next dump and just uses the shortest period among all periodic
325 * clients. It is more efficient to serve multiple dump requests at once,
326 * rather than trying to reschedule the worker to serve each request
327 * individually.
328 */
329 list_for_each_entry(pos, &kinstr_ctx->clients, node) {
330 /* Ignore clients that are not periodic or not active. */
331 if (pos->active && pos->dump_interval_ns > 0) {
332 shortest_period_ns =
333 MIN(shortest_period_ns, pos->dump_interval_ns);
334
335 /* Next dump should happen exactly one period after the last dump.
336 * If last dump was overdue and scheduled to happen more than one
337 * period ago, compensate for that by scheduling next dump in the
338 * immediate future.
339 */
340 if (pos->next_dump_time_ns < cur_ts_ns)
341 pos->next_dump_time_ns =
342 MAX(cur_ts_ns + 1,
343 pos->next_dump_time_ns +
344 pos->dump_interval_ns);
345 }
346 }
347
348 /* Cancel the timer if it is already pending */
349 hrtimer_cancel(&kinstr_ctx->dump_timer);
350
351 /* Start the timer if there are periodic clients and kinstr_prfcnt is not
352 * suspended.
353 */
354 if ((shortest_period_ns != U64_MAX) &&
355 (kinstr_ctx->suspend_count == 0)) {
356 u64 next_schedule_time_ns =
357 kbasep_kinstr_prfcnt_next_dump_time_ns(
358 cur_ts_ns, shortest_period_ns);
359 hrtimer_start(&kinstr_ctx->dump_timer,
360 ns_to_ktime(next_schedule_time_ns - cur_ts_ns),
361 HRTIMER_MODE_REL);
362 }
363 }
364
365 static enum prfcnt_block_type
kbase_hwcnt_metadata_block_type_to_prfcnt_block_type(u64 type)366 kbase_hwcnt_metadata_block_type_to_prfcnt_block_type(u64 type)
367 {
368 enum prfcnt_block_type block_type;
369
370 switch (type) {
371 case KBASE_HWCNT_GPU_V5_BLOCK_TYPE_PERF_FE:
372 case KBASE_HWCNT_GPU_V5_BLOCK_TYPE_PERF_FE2:
373 case KBASE_HWCNT_GPU_V5_BLOCK_TYPE_PERF_FE3:
374 block_type = PRFCNT_BLOCK_TYPE_FE;
375 break;
376
377 case KBASE_HWCNT_GPU_V5_BLOCK_TYPE_PERF_TILER:
378 block_type = PRFCNT_BLOCK_TYPE_TILER;
379 break;
380
381 case KBASE_HWCNT_GPU_V5_BLOCK_TYPE_PERF_SC:
382 case KBASE_HWCNT_GPU_V5_BLOCK_TYPE_PERF_SC2:
383 case KBASE_HWCNT_GPU_V5_BLOCK_TYPE_PERF_SC3:
384 block_type = PRFCNT_BLOCK_TYPE_SHADER_CORE;
385 break;
386
387 case KBASE_HWCNT_GPU_V5_BLOCK_TYPE_PERF_MEMSYS:
388 case KBASE_HWCNT_GPU_V5_BLOCK_TYPE_PERF_MEMSYS2:
389 block_type = PRFCNT_BLOCK_TYPE_MEMORY;
390 break;
391
392 case KBASE_HWCNT_GPU_V5_BLOCK_TYPE_PERF_UNDEFINED:
393 default:
394 block_type = PRFCNT_BLOCK_TYPE_RESERVED;
395 break;
396 }
397
398 return block_type;
399 }
400
401 /**
402 * kbasep_kinstr_prfcnt_set_block_meta_items() - Populate a sample's block meta
403 * item array.
404 * @dst: Non-NULL pointer to the sample's dump buffer object.
405 * @block_meta_base: Non-NULL double pointer to the start of the block meta
406 * data items.
407 * @base_addr: Address of allocated pages for array of samples. Used
408 * to calculate offset of block values.
409 * @counter_set: The SET which blocks represent.
410 */
kbasep_kinstr_prfcnt_set_block_meta_items(struct kbase_hwcnt_dump_buffer * dst,struct prfcnt_metadata ** block_meta_base,u64 base_addr,u8 counter_set)411 int kbasep_kinstr_prfcnt_set_block_meta_items(struct kbase_hwcnt_dump_buffer *dst,
412 struct prfcnt_metadata **block_meta_base,
413 u64 base_addr, u8 counter_set)
414 {
415 size_t grp, blk, blk_inst;
416 struct prfcnt_metadata **ptr_md = block_meta_base;
417 const struct kbase_hwcnt_metadata *metadata;
418
419 if (!dst || !*block_meta_base)
420 return -EINVAL;
421
422 metadata = dst->metadata;
423 kbase_hwcnt_metadata_for_each_block(metadata, grp, blk, blk_inst) {
424 u64 *dst_blk;
425
426 /* Skip unused blocks */
427 if (!kbase_hwcnt_metadata_block_instance_avail(metadata, grp, blk, blk_inst))
428 continue;
429
430 dst_blk = kbase_hwcnt_dump_buffer_block_instance(dst, grp, blk, blk_inst);
431 (*ptr_md)->hdr.item_type = PRFCNT_SAMPLE_META_TYPE_BLOCK;
432 (*ptr_md)->hdr.item_version = PRFCNT_READER_API_VERSION;
433 (*ptr_md)->u.block_md.block_type =
434 kbase_hwcnt_metadata_block_type_to_prfcnt_block_type(
435 kbase_hwcnt_metadata_block_type(metadata, grp,
436 blk));
437 (*ptr_md)->u.block_md.block_idx = (u8)blk_inst;
438 (*ptr_md)->u.block_md.set = counter_set;
439 (*ptr_md)->u.block_md.block_state = BLOCK_STATE_UNKNOWN;
440 (*ptr_md)->u.block_md.values_offset = (u32)((u64)(uintptr_t)dst_blk - base_addr);
441
442 /* update the buf meta data block pointer to next item */
443 (*ptr_md)++;
444 }
445
446 return 0;
447 }
448
449 /**
450 * kbasep_kinstr_prfcnt_set_sample_metadata() - Set sample metadata for sample
451 * output.
452 * @cli: Non-NULL pointer to a kinstr_prfcnt client.
453 * @dump_buf: Non-NULL pointer to dump buffer where sample is stored.
454 * @ptr_md: Non-NULL pointer to sample metadata.
455 */
kbasep_kinstr_prfcnt_set_sample_metadata(struct kbase_kinstr_prfcnt_client * cli,struct kbase_hwcnt_dump_buffer * dump_buf,struct prfcnt_metadata * ptr_md)456 static void kbasep_kinstr_prfcnt_set_sample_metadata(
457 struct kbase_kinstr_prfcnt_client *cli,
458 struct kbase_hwcnt_dump_buffer *dump_buf,
459 struct prfcnt_metadata *ptr_md)
460 {
461 u8 clk_cnt, i;
462
463 clk_cnt = cli->kinstr_ctx->metadata->clk_cnt;
464
465 /* PRFCNT_SAMPLE_META_TYPE_SAMPLE must be the first item */
466 ptr_md->hdr.item_type = PRFCNT_SAMPLE_META_TYPE_SAMPLE;
467 ptr_md->hdr.item_version = PRFCNT_READER_API_VERSION;
468 ptr_md->u.sample_md.seq = atomic_read(&cli->write_idx);
469 ptr_md->u.sample_md.flags = cli->sample_flags;
470
471 /* Place the PRFCNT_SAMPLE_META_TYPE_CLOCK optionally as the 2nd */
472 ptr_md++;
473 if (clk_cnt > MAX_REPORTED_DOMAINS)
474 clk_cnt = MAX_REPORTED_DOMAINS;
475
476 /* Handle the prfcnt_clock_metadata meta item */
477 ptr_md->hdr.item_type = PRFCNT_SAMPLE_META_TYPE_CLOCK;
478 ptr_md->hdr.item_version = PRFCNT_READER_API_VERSION;
479 ptr_md->u.clock_md.num_domains = clk_cnt;
480 for (i = 0; i < clk_cnt; i++)
481 ptr_md->u.clock_md.cycles[i] = dump_buf->clk_cnt_buf[i];
482
483 /* Dealing with counter blocks */
484 ptr_md++;
485 if (WARN_ON(kbasep_kinstr_prfcnt_set_block_meta_items(
486 dump_buf, &ptr_md, cli->sample_arr.page_addr, cli->config.counter_set)))
487 return;
488
489 /* Handle the last sentinel item */
490 ptr_md->hdr.item_type = FLEX_LIST_TYPE_NONE;
491 ptr_md->hdr.item_version = 0;
492 }
493
494 /**
495 * kbasep_kinstr_prfcnt_client_output_empty_sample() - Assemble an empty sample
496 * for output.
497 * @cli: Non-NULL pointer to a kinstr_prfcnt client.
498 * @buf_idx: The index to the sample array for saving the sample.
499 */
kbasep_kinstr_prfcnt_client_output_empty_sample(struct kbase_kinstr_prfcnt_client * cli,unsigned int buf_idx)500 static void kbasep_kinstr_prfcnt_client_output_empty_sample(
501 struct kbase_kinstr_prfcnt_client *cli, unsigned int buf_idx)
502 {
503 struct kbase_hwcnt_dump_buffer *dump_buf;
504 struct prfcnt_metadata *ptr_md;
505
506 if (WARN_ON(buf_idx >= cli->sample_arr.sample_count))
507 return;
508
509 dump_buf = &cli->sample_arr.samples[buf_idx].dump_buf;
510 ptr_md = cli->sample_arr.samples[buf_idx].sample_meta;
511
512 kbase_hwcnt_dump_buffer_zero(dump_buf, &cli->enable_map);
513
514 /* Use end timestamp from most recent async dump */
515 ptr_md->u.sample_md.timestamp_start = cli->async.ts_end_ns;
516 ptr_md->u.sample_md.timestamp_end = cli->async.ts_end_ns;
517
518 kbasep_kinstr_prfcnt_set_sample_metadata(cli, dump_buf, ptr_md);
519 }
520
521 /**
522 * kbasep_kinstr_prfcnt_client_output_sample() - Assemble a sample for output.
523 * @cli: Non-NULL pointer to a kinstr_prfcnt client.
524 * @buf_idx: The index to the sample array for saving the sample.
525 * @user_data: User data to return to the user.
526 * @ts_start_ns: Time stamp for the start point of the sample dump.
527 * @ts_end_ns: Time stamp for the end point of the sample dump.
528 */
kbasep_kinstr_prfcnt_client_output_sample(struct kbase_kinstr_prfcnt_client * cli,unsigned int buf_idx,u64 user_data,u64 ts_start_ns,u64 ts_end_ns)529 static void kbasep_kinstr_prfcnt_client_output_sample(
530 struct kbase_kinstr_prfcnt_client *cli, unsigned int buf_idx,
531 u64 user_data, u64 ts_start_ns, u64 ts_end_ns)
532 {
533 struct kbase_hwcnt_dump_buffer *dump_buf;
534 struct kbase_hwcnt_dump_buffer *tmp_buf = &cli->tmp_buf;
535 struct prfcnt_metadata *ptr_md;
536
537 if (WARN_ON(buf_idx >= cli->sample_arr.sample_count))
538 return;
539
540 dump_buf = &cli->sample_arr.samples[buf_idx].dump_buf;
541 ptr_md = cli->sample_arr.samples[buf_idx].sample_meta;
542
543 /* Patch the dump buf headers, to hide the counters that other hwcnt
544 * clients are using.
545 */
546 kbase_hwcnt_gpu_patch_dump_headers(tmp_buf, &cli->enable_map);
547
548 /* Copy the temp buffer to the userspace visible buffer. The strict
549 * variant will explicitly zero any non-enabled counters to ensure
550 * nothing except exactly what the user asked for is made visible.
551 */
552 kbase_hwcnt_dump_buffer_copy_strict(dump_buf, tmp_buf,
553 &cli->enable_map);
554
555 /* PRFCNT_SAMPLE_META_TYPE_SAMPLE must be the first item.
556 * Set timestamp and user data for real dump.
557 */
558 ptr_md->u.sample_md.timestamp_start = ts_start_ns;
559 ptr_md->u.sample_md.timestamp_end = ts_end_ns;
560 ptr_md->u.sample_md.user_data = user_data;
561
562 kbasep_kinstr_prfcnt_set_sample_metadata(cli, dump_buf, ptr_md);
563 }
564
565 /**
566 * kbasep_kinstr_prfcnt_client_dump() - Perform a dump for a client.
567 * @cli: Non-NULL pointer to a kinstr_prfcnt client.
568 * @event_id: Event type that triggered the dump.
569 * @user_data: User data to return to the user.
570 * @async_dump: Whether this is an asynchronous dump or not.
571 * @empty_sample: Sample block data will be 0 if this is true.
572 *
573 * Return: 0 on success, else error code.
574 */
575 static int
kbasep_kinstr_prfcnt_client_dump(struct kbase_kinstr_prfcnt_client * cli,enum base_hwcnt_reader_event event_id,u64 user_data,bool async_dump,bool empty_sample)576 kbasep_kinstr_prfcnt_client_dump(struct kbase_kinstr_prfcnt_client *cli,
577 enum base_hwcnt_reader_event event_id,
578 u64 user_data, bool async_dump,
579 bool empty_sample)
580 {
581 int ret;
582 u64 ts_start_ns = 0;
583 u64 ts_end_ns = 0;
584 unsigned int write_idx;
585 unsigned int read_idx;
586 size_t available_samples_count;
587
588 WARN_ON(!cli);
589 lockdep_assert_held(&cli->kinstr_ctx->lock);
590
591 write_idx = atomic_read(&cli->write_idx);
592 read_idx = atomic_read(&cli->read_idx);
593
594 /* Check if there is a place to copy HWC block into. Calculate the
595 * number of available samples count, by taking into account the type
596 * of dump.
597 * Asynchronous dumps have the ability to reserve space in the samples
598 * array for future dumps, unlike synchronous dumps. Because of that,
599 * the samples count for synchronous dumps is managed by a variable
600 * called sync_sample_count, that originally is defined as equal to the
601 * size of the whole array but later decreases every time an
602 * asynchronous dump request is pending and then re-increased every
603 * time an asynchronous dump request is completed.
604 */
605 available_samples_count = async_dump ?
606 cli->sample_arr.sample_count :
607 atomic_read(&cli->sync_sample_count);
608 if (write_idx - read_idx == available_samples_count) {
609 /* For periodic sampling, the current active dump
610 * will be accumulated in the next sample, when
611 * a buffer becomes available.
612 */
613 if (event_id == BASE_HWCNT_READER_EVENT_PERIODIC)
614 cli->sample_flags |= SAMPLE_FLAG_OVERFLOW;
615 return -EBUSY;
616 }
617
618 /* For the rest of the function, use the actual sample_count
619 * that represents the real size of the array.
620 */
621 write_idx %= cli->sample_arr.sample_count;
622
623 if (!empty_sample) {
624 ret = kbase_hwcnt_virtualizer_client_dump(
625 cli->hvcli, &ts_start_ns, &ts_end_ns, &cli->tmp_buf);
626 /* HWC dump error, set the sample with error flag */
627 if (ret)
628 cli->sample_flags |= SAMPLE_FLAG_ERROR;
629
630 /* Make the sample ready and copy it to the userspace mapped buffer */
631 kbasep_kinstr_prfcnt_client_output_sample(
632 cli, write_idx, user_data, ts_start_ns, ts_end_ns);
633 } else {
634 if (!async_dump) {
635 struct prfcnt_metadata *ptr_md;
636 /* User data will not be updated for empty samples. */
637 ptr_md = cli->sample_arr.samples[write_idx].sample_meta;
638 ptr_md->u.sample_md.user_data = user_data;
639 }
640
641 /* Make the sample ready and copy it to the userspace mapped buffer */
642 kbasep_kinstr_prfcnt_client_output_empty_sample(cli, write_idx);
643 }
644
645 /* Notify client. Make sure all changes to memory are visible. */
646 wmb();
647 atomic_inc(&cli->write_idx);
648 if (async_dump) {
649 /* Remember the end timestamp of async dump for empty samples */
650 if (!empty_sample)
651 cli->async.ts_end_ns = ts_end_ns;
652
653 atomic_inc(&cli->sync_sample_count);
654 }
655 wake_up_interruptible(&cli->waitq);
656 /* Reset the flags for the next sample dump */
657 cli->sample_flags = 0;
658
659 return 0;
660 }
661
662 static int
kbasep_kinstr_prfcnt_client_start(struct kbase_kinstr_prfcnt_client * cli,u64 user_data)663 kbasep_kinstr_prfcnt_client_start(struct kbase_kinstr_prfcnt_client *cli,
664 u64 user_data)
665 {
666 int ret;
667 u64 tm_start, tm_end;
668
669 WARN_ON(!cli);
670 lockdep_assert_held(&cli->cmd_sync_lock);
671
672 /* If the client is already started, the command is a no-op */
673 if (cli->active)
674 return 0;
675
676 kbase_hwcnt_gpu_enable_map_from_physical(&cli->enable_map,
677 &cli->config.phys_em);
678
679 mutex_lock(&cli->kinstr_ctx->lock);
680 /* Enable HWC from the configuration of the client creation */
681 ret = kbase_hwcnt_virtualizer_client_set_counters(
682 cli->hvcli, &cli->enable_map, &tm_start, &tm_end, NULL);
683
684 if (!ret) {
685 atomic_set(&cli->sync_sample_count, cli->sample_count);
686 cli->active = true;
687 cli->user_data = user_data;
688 cli->sample_flags = 0;
689
690 if (cli->dump_interval_ns)
691 kbasep_kinstr_prfcnt_reschedule_worker(cli->kinstr_ctx);
692 }
693
694 mutex_unlock(&cli->kinstr_ctx->lock);
695
696 return ret;
697 }
698
kbasep_kinstr_prfcnt_client_wait_async_done(struct kbase_kinstr_prfcnt_client * cli)699 static int kbasep_kinstr_prfcnt_client_wait_async_done(
700 struct kbase_kinstr_prfcnt_client *cli)
701 {
702 lockdep_assert_held(&cli->cmd_sync_lock);
703
704 return wait_event_interruptible(cli->waitq,
705 atomic_read(&cli->sync_sample_count) ==
706 cli->sample_count);
707 }
708
709 static int
kbasep_kinstr_prfcnt_client_stop(struct kbase_kinstr_prfcnt_client * cli,u64 user_data)710 kbasep_kinstr_prfcnt_client_stop(struct kbase_kinstr_prfcnt_client *cli,
711 u64 user_data)
712 {
713 int ret;
714 u64 tm_start = 0;
715 u64 tm_end = 0;
716 struct kbase_hwcnt_physical_enable_map phys_em;
717 struct kbase_hwcnt_dump_buffer *tmp_buf = NULL;
718 unsigned int write_idx;
719 unsigned int read_idx;
720
721 WARN_ON(!cli);
722 lockdep_assert_held(&cli->cmd_sync_lock);
723
724 /* If the client is not started, the command is invalid */
725 if (!cli->active)
726 return -EINVAL;
727
728 /* Wait until pending async sample operation done */
729 ret = kbasep_kinstr_prfcnt_client_wait_async_done(cli);
730
731 if (ret < 0)
732 return -ERESTARTSYS;
733
734 phys_em.fe_bm = 0;
735 phys_em.tiler_bm = 0;
736 phys_em.mmu_l2_bm = 0;
737 phys_em.shader_bm = 0;
738
739 kbase_hwcnt_gpu_enable_map_from_physical(&cli->enable_map, &phys_em);
740
741 mutex_lock(&cli->kinstr_ctx->lock);
742
743 /* Check whether one has the buffer to hold the last sample */
744 write_idx = atomic_read(&cli->write_idx);
745 read_idx = atomic_read(&cli->read_idx);
746
747 /* Check if there is a place to save the last stop produced sample */
748 if (write_idx - read_idx < cli->sample_arr.sample_count)
749 tmp_buf = &cli->tmp_buf;
750
751 ret = kbase_hwcnt_virtualizer_client_set_counters(cli->hvcli,
752 &cli->enable_map,
753 &tm_start, &tm_end,
754 &cli->tmp_buf);
755 /* If the last stop sample is in error, set the sample flag */
756 if (ret)
757 cli->sample_flags |= SAMPLE_FLAG_ERROR;
758
759 if (tmp_buf) {
760 write_idx %= cli->sample_arr.sample_count;
761 /* Handle the last stop sample */
762 kbase_hwcnt_gpu_enable_map_from_physical(&cli->enable_map,
763 &cli->config.phys_em);
764 /* As this is a stop sample, mark it as MANUAL */
765 kbasep_kinstr_prfcnt_client_output_sample(
766 cli, write_idx, user_data, tm_start, tm_end);
767 /* Notify client. Make sure all changes to memory are visible. */
768 wmb();
769 atomic_inc(&cli->write_idx);
770 wake_up_interruptible(&cli->waitq);
771 }
772
773 cli->active = false;
774 cli->user_data = user_data;
775
776 if (cli->dump_interval_ns)
777 kbasep_kinstr_prfcnt_reschedule_worker(cli->kinstr_ctx);
778
779 mutex_unlock(&cli->kinstr_ctx->lock);
780
781 return ret;
782 }
783
784 static int
kbasep_kinstr_prfcnt_client_sync_dump(struct kbase_kinstr_prfcnt_client * cli,u64 user_data)785 kbasep_kinstr_prfcnt_client_sync_dump(struct kbase_kinstr_prfcnt_client *cli,
786 u64 user_data)
787 {
788 int ret;
789 bool empty_sample = false;
790
791 lockdep_assert_held(&cli->cmd_sync_lock);
792
793 /* If the client is not started, or not manual, the command invalid */
794 if (!cli->active || cli->dump_interval_ns)
795 return -EINVAL;
796
797 /* Wait until pending async sample operation done, this is required to
798 * satisfy the stated sample sequence following their issuing order,
799 * reflected by the sample start timestamp.
800 */
801 if (atomic_read(&cli->sync_sample_count) != cli->sample_count) {
802 /* Return empty sample instead of performing real dump.
803 * As there is an async dump currently in-flight which will
804 * have the desired information.
805 */
806 empty_sample = true;
807 ret = kbasep_kinstr_prfcnt_client_wait_async_done(cli);
808
809 if (ret < 0)
810 return -ERESTARTSYS;
811 }
812
813 mutex_lock(&cli->kinstr_ctx->lock);
814
815 ret = kbasep_kinstr_prfcnt_client_dump(cli,
816 BASE_HWCNT_READER_EVENT_MANUAL,
817 user_data, false, empty_sample);
818
819 mutex_unlock(&cli->kinstr_ctx->lock);
820
821 return ret;
822 }
823
824 static int
kbasep_kinstr_prfcnt_client_async_dump(struct kbase_kinstr_prfcnt_client * cli,u64 user_data)825 kbasep_kinstr_prfcnt_client_async_dump(struct kbase_kinstr_prfcnt_client *cli,
826 u64 user_data)
827 {
828 unsigned int write_idx;
829 unsigned int read_idx;
830 unsigned int active_async_dumps;
831 unsigned int new_async_buf_idx;
832 int ret;
833
834 lockdep_assert_held(&cli->cmd_sync_lock);
835
836 /* If the client is not started, or not manual, the command invalid */
837 if (!cli->active || cli->dump_interval_ns)
838 return -EINVAL;
839
840 mutex_lock(&cli->kinstr_ctx->lock);
841
842 write_idx = atomic_read(&cli->write_idx);
843 read_idx = atomic_read(&cli->read_idx);
844 active_async_dumps =
845 cli->sample_count - atomic_read(&cli->sync_sample_count);
846 new_async_buf_idx = write_idx + active_async_dumps;
847
848 /* Check if there is a place to copy HWC block into.
849 * If successful, reserve space in the buffer for the asynchronous
850 * operation to make sure that it can actually take place.
851 * Because we reserve space for asynchronous dumps we need to take that
852 * in consideration here.
853 */
854 ret = (new_async_buf_idx - read_idx == cli->sample_arr.sample_count) ?
855 -EBUSY :
856 0;
857
858 if (ret == -EBUSY) {
859 mutex_unlock(&cli->kinstr_ctx->lock);
860 return ret;
861 }
862
863 if (active_async_dumps > 0) {
864 struct prfcnt_metadata *ptr_md;
865 unsigned int buf_idx =
866 new_async_buf_idx % cli->sample_arr.sample_count;
867 /* Instead of storing user_data, write it directly to future
868 * empty sample.
869 */
870 ptr_md = cli->sample_arr.samples[buf_idx].sample_meta;
871 ptr_md->u.sample_md.user_data = user_data;
872
873 atomic_dec(&cli->sync_sample_count);
874 } else {
875 cli->async.user_data = user_data;
876 atomic_dec(&cli->sync_sample_count);
877
878 kbase_hwcnt_virtualizer_queue_work(cli->kinstr_ctx->hvirt,
879 &cli->async.dump_work);
880 }
881
882 mutex_unlock(&cli->kinstr_ctx->lock);
883
884 return ret;
885 }
886
887 static int
kbasep_kinstr_prfcnt_client_discard(struct kbase_kinstr_prfcnt_client * cli)888 kbasep_kinstr_prfcnt_client_discard(struct kbase_kinstr_prfcnt_client *cli)
889 {
890 WARN_ON(!cli);
891 lockdep_assert_held(&cli->cmd_sync_lock);
892
893 mutex_lock(&cli->kinstr_ctx->lock);
894
895 /* Discard (Clear) all internally buffered samples */
896 atomic_set(&cli->read_idx, atomic_read(&cli->write_idx));
897
898 mutex_unlock(&cli->kinstr_ctx->lock);
899
900 return 0;
901 }
902
903 /**
904 * kbasep_kinstr_prfcnt_cmd() - Execute command for a client session.
905 * @cli: Non-NULL pointer to kinstr_prfcnt client.
906 * @control_cmd: Control command to execute.
907 *
908 * Return: 0 on success, else error code.
909 */
kbasep_kinstr_prfcnt_cmd(struct kbase_kinstr_prfcnt_client * cli,struct prfcnt_control_cmd * control_cmd)910 static int kbasep_kinstr_prfcnt_cmd(struct kbase_kinstr_prfcnt_client *cli,
911 struct prfcnt_control_cmd *control_cmd)
912 {
913 int ret = 0;
914
915 mutex_lock(&cli->cmd_sync_lock);
916
917 switch (control_cmd->cmd) {
918 case PRFCNT_CONTROL_CMD_START:
919 ret = kbasep_kinstr_prfcnt_client_start(cli,
920 control_cmd->user_data);
921 break;
922 case PRFCNT_CONTROL_CMD_STOP:
923 ret = kbasep_kinstr_prfcnt_client_stop(cli,
924 control_cmd->user_data);
925 break;
926 case PRFCNT_CONTROL_CMD_SAMPLE_SYNC:
927 ret = kbasep_kinstr_prfcnt_client_sync_dump(
928 cli, control_cmd->user_data);
929 break;
930 case PRFCNT_CONTROL_CMD_SAMPLE_ASYNC:
931 ret = kbasep_kinstr_prfcnt_client_async_dump(
932 cli, control_cmd->user_data);
933 break;
934 case PRFCNT_CONTROL_CMD_DISCARD:
935 ret = kbasep_kinstr_prfcnt_client_discard(cli);
936 break;
937 default:
938 ret = -EINVAL;
939 break;
940 }
941
942 mutex_unlock(&cli->cmd_sync_lock);
943
944 return ret;
945 }
946
947 static int
kbasep_kinstr_prfcnt_get_sample(struct kbase_kinstr_prfcnt_client * cli,struct prfcnt_sample_access * sample_access)948 kbasep_kinstr_prfcnt_get_sample(struct kbase_kinstr_prfcnt_client *cli,
949 struct prfcnt_sample_access *sample_access)
950 {
951 unsigned int write_idx;
952 unsigned int read_idx;
953 u64 sample_offset_bytes;
954 struct prfcnt_metadata *sample_meta;
955
956 write_idx = atomic_read(&cli->write_idx);
957 read_idx = atomic_read(&cli->read_idx);
958
959 if (write_idx == read_idx)
960 return -EINVAL;
961
962 read_idx %= cli->sample_arr.sample_count;
963 sample_offset_bytes =
964 (u64)(uintptr_t)cli->sample_arr.samples[read_idx].sample_meta -
965 (u64)(uintptr_t)cli->sample_arr.page_addr;
966 sample_meta =
967 (struct prfcnt_metadata *)cli->sample_arr.samples[read_idx]
968 .sample_meta;
969
970 /* Verify that a valid sample has been dumped in the read_idx.
971 * There are situations where this may not be the case,
972 * for instance if the client is trying to get an asynchronous
973 * sample which has not been dumped yet.
974 */
975 if (sample_meta->hdr.item_type != PRFCNT_SAMPLE_META_TYPE_SAMPLE)
976 return -EINVAL;
977 if (sample_meta->hdr.item_version != PRFCNT_READER_API_VERSION)
978 return -EINVAL;
979
980 sample_access->sequence = sample_meta->u.sample_md.seq;
981 sample_access->sample_offset_bytes = sample_offset_bytes;
982
983 /* read_idx is not incremented here, because the interface allows
984 * only one sample to be "in flight" between kernel space and user space.
985 */
986
987 return 0;
988 }
989
990 static int
kbasep_kinstr_prfcnt_put_sample(struct kbase_kinstr_prfcnt_client * cli,struct prfcnt_sample_access * sample_access)991 kbasep_kinstr_prfcnt_put_sample(struct kbase_kinstr_prfcnt_client *cli,
992 struct prfcnt_sample_access *sample_access)
993 {
994 unsigned int write_idx;
995 unsigned int read_idx;
996 u64 sample_offset_bytes;
997
998 write_idx = atomic_read(&cli->write_idx);
999 read_idx = atomic_read(&cli->read_idx);
1000
1001 if (write_idx == read_idx)
1002 return -EINVAL;
1003
1004 if (sample_access->sequence != read_idx)
1005 return -EINVAL;
1006
1007 read_idx %= cli->sample_arr.sample_count;
1008 sample_offset_bytes =
1009 (u64)(uintptr_t)cli->sample_arr.samples[read_idx].sample_meta -
1010 (u64)(uintptr_t)cli->sample_arr.page_addr;
1011
1012 if (sample_access->sample_offset_bytes != sample_offset_bytes)
1013 return -EINVAL;
1014
1015 atomic_inc(&cli->read_idx);
1016
1017 return 0;
1018 }
1019
1020 /**
1021 * kbasep_kinstr_prfcnt_hwcnt_reader_ioctl() - hwcnt reader's ioctl.
1022 * @filp: Non-NULL pointer to file structure.
1023 * @cmd: User command.
1024 * @arg: Command's argument.
1025 *
1026 * Return: 0 on success, else error code.
1027 */
kbasep_kinstr_prfcnt_hwcnt_reader_ioctl(struct file * filp,unsigned int cmd,unsigned long arg)1028 static long kbasep_kinstr_prfcnt_hwcnt_reader_ioctl(struct file *filp,
1029 unsigned int cmd,
1030 unsigned long arg)
1031 {
1032 long rcode = 0;
1033 struct kbase_kinstr_prfcnt_client *cli;
1034 void __user *uarg = (void __user *)arg;
1035
1036 if (!filp)
1037 return -EINVAL;
1038
1039 cli = filp->private_data;
1040
1041 if (!cli)
1042 return -EINVAL;
1043
1044 switch (_IOC_NR(cmd)) {
1045 case _IOC_NR(KBASE_IOCTL_KINSTR_PRFCNT_CMD): {
1046 struct prfcnt_control_cmd control_cmd;
1047 int err;
1048
1049 err = copy_from_user(&control_cmd, uarg, sizeof(control_cmd));
1050 if (err)
1051 return -EFAULT;
1052 rcode = kbasep_kinstr_prfcnt_cmd(cli, &control_cmd);
1053 } break;
1054 case _IOC_NR(KBASE_IOCTL_KINSTR_PRFCNT_GET_SAMPLE): {
1055 struct prfcnt_sample_access sample_access;
1056 int err;
1057
1058 memset(&sample_access, 0, sizeof(sample_access));
1059 rcode = kbasep_kinstr_prfcnt_get_sample(cli, &sample_access);
1060 err = copy_to_user(uarg, &sample_access, sizeof(sample_access));
1061 if (err)
1062 return -EFAULT;
1063 } break;
1064 case _IOC_NR(KBASE_IOCTL_KINSTR_PRFCNT_PUT_SAMPLE): {
1065 struct prfcnt_sample_access sample_access;
1066 int err;
1067
1068 err = copy_from_user(&sample_access, uarg,
1069 sizeof(sample_access));
1070 if (err)
1071 return -EFAULT;
1072 rcode = kbasep_kinstr_prfcnt_put_sample(cli, &sample_access);
1073 } break;
1074 default:
1075 rcode = -EINVAL;
1076 break;
1077 }
1078
1079 return rcode;
1080 }
1081
1082 /**
1083 * kbasep_kinstr_prfcnt_hwcnt_reader_mmap() - hwcnt reader's mmap.
1084 * @filp: Non-NULL pointer to file structure.
1085 * @vma: Non-NULL pointer to vma structure.
1086 *
1087 * Return: 0 on success, else error code.
1088 */
kbasep_kinstr_prfcnt_hwcnt_reader_mmap(struct file * filp,struct vm_area_struct * vma)1089 static int kbasep_kinstr_prfcnt_hwcnt_reader_mmap(struct file *filp,
1090 struct vm_area_struct *vma)
1091 {
1092 struct kbase_kinstr_prfcnt_client *cli;
1093 unsigned long vm_size, size, addr, pfn, offset;
1094
1095 if (!filp || !vma)
1096 return -EINVAL;
1097 cli = filp->private_data;
1098
1099 if (!cli)
1100 return -EINVAL;
1101
1102 vm_size = vma->vm_end - vma->vm_start;
1103
1104 /* The mapping is allowed to span the entirety of the page allocation,
1105 * not just the chunk where the dump buffers are allocated.
1106 * This accommodates the corner case where the combined size of the
1107 * dump buffers is smaller than a single page.
1108 * This does not pose a security risk as the pages are zeroed on
1109 * allocation, and anything out of bounds of the dump buffers is never
1110 * written to.
1111 */
1112 size = (1ull << cli->sample_arr.page_order) * PAGE_SIZE;
1113
1114 if (vma->vm_pgoff > (size >> PAGE_SHIFT))
1115 return -EINVAL;
1116
1117 offset = vma->vm_pgoff << PAGE_SHIFT;
1118
1119 if (vm_size > size - offset)
1120 return -EINVAL;
1121
1122 addr = __pa(cli->sample_arr.page_addr + offset);
1123 pfn = addr >> PAGE_SHIFT;
1124
1125 return remap_pfn_range(vma, vma->vm_start, pfn, vm_size,
1126 vma->vm_page_prot);
1127 }
1128
kbasep_kinstr_prfcnt_sample_array_free(struct kbase_kinstr_prfcnt_sample_array * sample_arr)1129 static void kbasep_kinstr_prfcnt_sample_array_free(
1130 struct kbase_kinstr_prfcnt_sample_array *sample_arr)
1131 {
1132 if (!sample_arr)
1133 return;
1134
1135 kfree((void *)sample_arr->samples);
1136 kfree((void *)(size_t)sample_arr->page_addr);
1137 memset(sample_arr, 0, sizeof(*sample_arr));
1138 }
1139
1140 /**
1141 * kbasep_kinstr_prfcnt_client_destroy() - Destroy a kinstr_prfcnt client.
1142 * @cli: kinstr_prfcnt client. Must not be attached to a kinstr_prfcnt context.
1143 */
1144 static void
kbasep_kinstr_prfcnt_client_destroy(struct kbase_kinstr_prfcnt_client * cli)1145 kbasep_kinstr_prfcnt_client_destroy(struct kbase_kinstr_prfcnt_client *cli)
1146 {
1147 if (!cli)
1148 return;
1149
1150 kbase_hwcnt_virtualizer_client_destroy(cli->hvcli);
1151 kbasep_kinstr_prfcnt_sample_array_free(&cli->sample_arr);
1152 kbase_hwcnt_dump_buffer_free(&cli->tmp_buf);
1153 kbase_hwcnt_enable_map_free(&cli->enable_map);
1154 mutex_destroy(&cli->cmd_sync_lock);
1155 kfree(cli);
1156 }
1157
1158 /**
1159 * kbasep_kinstr_prfcnt_hwcnt_reader_release() - hwcnt reader's release.
1160 * @inode: Non-NULL pointer to inode structure.
1161 * @filp: Non-NULL pointer to file structure.
1162 *
1163 * Return: 0 always.
1164 */
kbasep_kinstr_prfcnt_hwcnt_reader_release(struct inode * inode,struct file * filp)1165 static int kbasep_kinstr_prfcnt_hwcnt_reader_release(struct inode *inode,
1166 struct file *filp)
1167 {
1168 struct kbase_kinstr_prfcnt_client *cli = filp->private_data;
1169
1170 mutex_lock(&cli->kinstr_ctx->lock);
1171
1172 WARN_ON(cli->kinstr_ctx->client_count == 0);
1173 if (cli->kinstr_ctx->client_count > 0)
1174 cli->kinstr_ctx->client_count--;
1175 list_del(&cli->node);
1176
1177 mutex_unlock(&cli->kinstr_ctx->lock);
1178
1179 kbasep_kinstr_prfcnt_client_destroy(cli);
1180
1181 return 0;
1182 }
1183
1184 /* kinstr_prfcnt client file operations */
1185 static const struct file_operations kinstr_prfcnt_client_fops = {
1186 .owner = THIS_MODULE,
1187 .poll = kbasep_kinstr_prfcnt_hwcnt_reader_poll,
1188 .unlocked_ioctl = kbasep_kinstr_prfcnt_hwcnt_reader_ioctl,
1189 .compat_ioctl = kbasep_kinstr_prfcnt_hwcnt_reader_ioctl,
1190 .mmap = kbasep_kinstr_prfcnt_hwcnt_reader_mmap,
1191 .release = kbasep_kinstr_prfcnt_hwcnt_reader_release,
1192 };
1193
kbasep_kinstr_prfcnt_get_sample_md_count(const struct kbase_hwcnt_metadata * metadata)1194 size_t kbasep_kinstr_prfcnt_get_sample_md_count(const struct kbase_hwcnt_metadata *metadata)
1195 {
1196 size_t grp, blk, blk_inst;
1197 size_t md_count = 0;
1198
1199 if (!metadata)
1200 return 0;
1201
1202 kbase_hwcnt_metadata_for_each_block(metadata, grp, blk, blk_inst) {
1203 /* Skip unused blocks */
1204 if (!kbase_hwcnt_metadata_block_instance_avail(metadata, grp, blk, blk_inst))
1205 continue;
1206
1207 md_count++;
1208 }
1209
1210 /* add counts for clock_meta and sample meta, respectively */
1211 md_count += 2;
1212
1213 /* Reserve one for last sentinel item. */
1214 md_count++;
1215
1216 return md_count;
1217 }
1218
kbasep_kinstr_prfcnt_get_sample_size(const struct kbase_hwcnt_metadata * metadata,struct kbase_hwcnt_dump_buffer * dump_buf)1219 static size_t kbasep_kinstr_prfcnt_get_sample_size(
1220 const struct kbase_hwcnt_metadata *metadata,
1221 struct kbase_hwcnt_dump_buffer *dump_buf)
1222 {
1223 size_t dump_buf_bytes;
1224 size_t clk_cnt_buf_bytes;
1225 size_t sample_meta_bytes;
1226 size_t md_count = kbasep_kinstr_prfcnt_get_sample_md_count(metadata);
1227
1228 if (!metadata)
1229 return 0;
1230
1231 sample_meta_bytes = sizeof(struct prfcnt_metadata) * md_count;
1232 dump_buf_bytes = metadata->dump_buf_bytes;
1233 clk_cnt_buf_bytes = sizeof(*dump_buf->clk_cnt_buf) * metadata->clk_cnt;
1234
1235 return (sample_meta_bytes + dump_buf_bytes + clk_cnt_buf_bytes);
1236 }
1237
1238 /**
1239 * kbasep_kinstr_prfcnt_dump_worker()- Dump worker, that dumps all periodic
1240 * clients that need to be dumped, then
1241 * reschedules itself.
1242 * @work: Work structure.
1243 */
kbasep_kinstr_prfcnt_dump_worker(struct work_struct * work)1244 static void kbasep_kinstr_prfcnt_dump_worker(struct work_struct *work)
1245 {
1246 struct kbase_kinstr_prfcnt_context *kinstr_ctx = container_of(
1247 work, struct kbase_kinstr_prfcnt_context, dump_work);
1248 struct kbase_kinstr_prfcnt_client *pos;
1249 u64 cur_time_ns;
1250
1251 mutex_lock(&kinstr_ctx->lock);
1252
1253 cur_time_ns = kbasep_kinstr_prfcnt_timestamp_ns();
1254
1255 list_for_each_entry(pos, &kinstr_ctx->clients, node) {
1256 if (pos->active && (pos->next_dump_time_ns != 0) &&
1257 (pos->next_dump_time_ns < cur_time_ns))
1258 kbasep_kinstr_prfcnt_client_dump(
1259 pos, BASE_HWCNT_READER_EVENT_PERIODIC,
1260 pos->user_data, false, false);
1261 }
1262
1263 kbasep_kinstr_prfcnt_reschedule_worker(kinstr_ctx);
1264
1265 mutex_unlock(&kinstr_ctx->lock);
1266 }
1267
1268 /**
1269 * kbasep_kinstr_prfcnt_async_dump_worker()- Dump worker for a manual client
1270 * to take a single asynchronous
1271 * sample.
1272 * @work: Work structure.
1273 */
kbasep_kinstr_prfcnt_async_dump_worker(struct work_struct * work)1274 static void kbasep_kinstr_prfcnt_async_dump_worker(struct work_struct *work)
1275 {
1276 struct kbase_kinstr_prfcnt_async *cli_async =
1277 container_of(work, struct kbase_kinstr_prfcnt_async, dump_work);
1278 struct kbase_kinstr_prfcnt_client *cli = container_of(
1279 cli_async, struct kbase_kinstr_prfcnt_client, async);
1280
1281 mutex_lock(&cli->kinstr_ctx->lock);
1282 /* While the async operation is in flight, a sync stop might have been
1283 * executed, for which the dump should be skipped. Further as we are
1284 * doing an async dump, we expect that there is reserved buffer for
1285 * this to happen. This is to avoid the rare corner case where the
1286 * user side has issued a stop/start pair before the async work item
1287 * get the chance to execute.
1288 */
1289 if (cli->active &&
1290 (atomic_read(&cli->sync_sample_count) < cli->sample_count))
1291 kbasep_kinstr_prfcnt_client_dump(cli,
1292 BASE_HWCNT_READER_EVENT_MANUAL,
1293 cli->async.user_data, true,
1294 false);
1295
1296 /* While the async operation is in flight, more async dump requests
1297 * may have been submitted. In this case, no more async dumps work
1298 * will be queued. Instead space will be reserved for that dump and
1299 * an empty sample will be return after handling the current async
1300 * dump.
1301 */
1302 while (cli->active &&
1303 (atomic_read(&cli->sync_sample_count) < cli->sample_count)) {
1304 kbasep_kinstr_prfcnt_client_dump(
1305 cli, BASE_HWCNT_READER_EVENT_MANUAL, 0, true, true);
1306 }
1307 mutex_unlock(&cli->kinstr_ctx->lock);
1308 }
1309
1310 /**
1311 * kbasep_kinstr_prfcnt_dump_timer() - Dump timer that schedules the dump worker for
1312 * execution as soon as possible.
1313 * @timer: Timer structure.
1314 */
1315 static enum hrtimer_restart
kbasep_kinstr_prfcnt_dump_timer(struct hrtimer * timer)1316 kbasep_kinstr_prfcnt_dump_timer(struct hrtimer *timer)
1317 {
1318 struct kbase_kinstr_prfcnt_context *kinstr_ctx = container_of(
1319 timer, struct kbase_kinstr_prfcnt_context, dump_timer);
1320
1321 /* We don't need to check kinstr_ctx->suspend_count here.
1322 * Suspend and resume functions already ensure that the worker
1323 * is cancelled when the driver is suspended, and resumed when
1324 * the suspend_count reaches 0.
1325 */
1326 kbase_hwcnt_virtualizer_queue_work(kinstr_ctx->hvirt,
1327 &kinstr_ctx->dump_work);
1328
1329 return HRTIMER_NORESTART;
1330 }
1331
kbase_kinstr_prfcnt_init(struct kbase_hwcnt_virtualizer * hvirt,struct kbase_kinstr_prfcnt_context ** out_kinstr_ctx)1332 int kbase_kinstr_prfcnt_init(struct kbase_hwcnt_virtualizer *hvirt,
1333 struct kbase_kinstr_prfcnt_context **out_kinstr_ctx)
1334 {
1335 struct kbase_kinstr_prfcnt_context *kinstr_ctx;
1336 const struct kbase_hwcnt_metadata *metadata;
1337
1338 if (!hvirt || !out_kinstr_ctx)
1339 return -EINVAL;
1340
1341 metadata = kbase_hwcnt_virtualizer_metadata(hvirt);
1342
1343 if (!metadata)
1344 return -EINVAL;
1345
1346 kinstr_ctx = kzalloc(sizeof(*kinstr_ctx), GFP_KERNEL);
1347
1348 if (!kinstr_ctx)
1349 return -ENOMEM;
1350
1351 kinstr_ctx->hvirt = hvirt;
1352 kinstr_ctx->metadata = metadata;
1353
1354 mutex_init(&kinstr_ctx->lock);
1355 INIT_LIST_HEAD(&kinstr_ctx->clients);
1356 hrtimer_init(&kinstr_ctx->dump_timer, CLOCK_MONOTONIC,
1357 HRTIMER_MODE_REL);
1358 kinstr_ctx->dump_timer.function = kbasep_kinstr_prfcnt_dump_timer;
1359 INIT_WORK(&kinstr_ctx->dump_work, kbasep_kinstr_prfcnt_dump_worker);
1360
1361 *out_kinstr_ctx = kinstr_ctx;
1362 return 0;
1363 }
1364
kbase_kinstr_prfcnt_term(struct kbase_kinstr_prfcnt_context * kinstr_ctx)1365 void kbase_kinstr_prfcnt_term(struct kbase_kinstr_prfcnt_context *kinstr_ctx)
1366 {
1367 if (!kinstr_ctx)
1368 return;
1369
1370 cancel_work_sync(&kinstr_ctx->dump_work);
1371
1372 /* Non-zero client count implies client leak */
1373 if (WARN_ON(kinstr_ctx->client_count > 0)) {
1374 struct kbase_kinstr_prfcnt_client *pos, *n;
1375
1376 list_for_each_entry_safe(pos, n, &kinstr_ctx->clients, node) {
1377 list_del(&pos->node);
1378 kinstr_ctx->client_count--;
1379 kbasep_kinstr_prfcnt_client_destroy(pos);
1380 }
1381 }
1382
1383 WARN_ON(kinstr_ctx->client_count > 0);
1384 kfree(kinstr_ctx);
1385 }
1386
kbase_kinstr_prfcnt_suspend(struct kbase_kinstr_prfcnt_context * kinstr_ctx)1387 void kbase_kinstr_prfcnt_suspend(struct kbase_kinstr_prfcnt_context *kinstr_ctx)
1388 {
1389 if (WARN_ON(!kinstr_ctx))
1390 return;
1391
1392 mutex_lock(&kinstr_ctx->lock);
1393
1394 if (!WARN_ON(kinstr_ctx->suspend_count == SIZE_MAX))
1395 kinstr_ctx->suspend_count++;
1396
1397 mutex_unlock(&kinstr_ctx->lock);
1398
1399 /* Always sync cancel the timer and then the worker, regardless of the
1400 * new suspend count.
1401 *
1402 * This ensures concurrent calls to kbase_kinstr_prfcnt_suspend() always block
1403 * until kinstr_prfcnt is fully suspended.
1404 *
1405 * The timer is canceled before the worker, as the timer
1406 * unconditionally re-enqueues the worker, but the worker checks the
1407 * suspend_count that we just incremented before rescheduling the timer.
1408 *
1409 * Therefore if we cancel the worker first, the timer might re-enqueue
1410 * the worker before we cancel the timer, but the opposite is not
1411 * possible.
1412 */
1413 hrtimer_cancel(&kinstr_ctx->dump_timer);
1414 cancel_work_sync(&kinstr_ctx->dump_work);
1415 }
1416
kbase_kinstr_prfcnt_resume(struct kbase_kinstr_prfcnt_context * kinstr_ctx)1417 void kbase_kinstr_prfcnt_resume(struct kbase_kinstr_prfcnt_context *kinstr_ctx)
1418 {
1419 if (WARN_ON(!kinstr_ctx))
1420 return;
1421
1422 mutex_lock(&kinstr_ctx->lock);
1423
1424 if (!WARN_ON(kinstr_ctx->suspend_count == 0)) {
1425 kinstr_ctx->suspend_count--;
1426
1427 /* Last resume, so re-enqueue the worker if we have any periodic
1428 * clients.
1429 */
1430 if (kinstr_ctx->suspend_count == 0) {
1431 struct kbase_kinstr_prfcnt_client *pos;
1432 bool has_periodic_clients = false;
1433
1434 list_for_each_entry(pos, &kinstr_ctx->clients, node) {
1435 if (pos->dump_interval_ns != 0) {
1436 has_periodic_clients = true;
1437 break;
1438 }
1439 }
1440
1441 if (has_periodic_clients)
1442 kbase_hwcnt_virtualizer_queue_work(
1443 kinstr_ctx->hvirt,
1444 &kinstr_ctx->dump_work);
1445 }
1446 }
1447
1448 mutex_unlock(&kinstr_ctx->lock);
1449 }
1450
kbasep_kinstr_prfcnt_sample_array_alloc(const struct kbase_hwcnt_metadata * metadata,size_t n,struct kbase_kinstr_prfcnt_sample_array * sample_arr)1451 static int kbasep_kinstr_prfcnt_sample_array_alloc(
1452 const struct kbase_hwcnt_metadata *metadata, size_t n,
1453 struct kbase_kinstr_prfcnt_sample_array *sample_arr)
1454 {
1455 struct kbase_kinstr_prfcnt_sample *samples;
1456 size_t sample_idx;
1457 u64 addr;
1458 unsigned int order;
1459 size_t dump_buf_bytes;
1460 size_t clk_cnt_buf_bytes;
1461 size_t sample_meta_bytes;
1462 size_t md_count;
1463 size_t sample_size;
1464
1465 if (!metadata || !sample_arr)
1466 return -EINVAL;
1467
1468 md_count = kbasep_kinstr_prfcnt_get_sample_md_count(metadata);
1469 sample_meta_bytes = sizeof(struct prfcnt_metadata) * md_count;
1470 dump_buf_bytes = metadata->dump_buf_bytes;
1471 clk_cnt_buf_bytes =
1472 sizeof(*samples->dump_buf.clk_cnt_buf) * metadata->clk_cnt;
1473 sample_size = sample_meta_bytes + dump_buf_bytes + clk_cnt_buf_bytes;
1474
1475 samples = kmalloc_array(n, sizeof(*samples), GFP_KERNEL);
1476
1477 if (!samples)
1478 return -ENOMEM;
1479
1480 order = get_order(sample_size * n);
1481 addr = (u64)(uintptr_t)kzalloc(sample_size * n, GFP_KERNEL);
1482
1483 if (!addr) {
1484 kfree((void *)samples);
1485 return -ENOMEM;
1486 }
1487
1488 sample_arr->page_addr = addr;
1489 sample_arr->page_order = order;
1490 sample_arr->sample_count = n;
1491 sample_arr->samples = samples;
1492
1493 for (sample_idx = 0; sample_idx < n; sample_idx++) {
1494 const size_t sample_meta_offset = sample_size * sample_idx;
1495 const size_t dump_buf_offset =
1496 sample_meta_offset + sample_meta_bytes;
1497 const size_t clk_cnt_buf_offset =
1498 dump_buf_offset + dump_buf_bytes;
1499
1500 /* Internal layout in a sample buffer: [sample metadata, dump_buf, clk_cnt_buf]. */
1501 samples[sample_idx].dump_buf.metadata = metadata;
1502 samples[sample_idx].sample_meta =
1503 (struct prfcnt_metadata *)(uintptr_t)(
1504 addr + sample_meta_offset);
1505 samples[sample_idx].dump_buf.dump_buf =
1506 (u64 *)(uintptr_t)(addr + dump_buf_offset);
1507 samples[sample_idx].dump_buf.clk_cnt_buf =
1508 (u64 *)(uintptr_t)(addr + clk_cnt_buf_offset);
1509 }
1510
1511 return 0;
1512 }
1513
prfcnt_mode_supported(u8 mode)1514 static bool prfcnt_mode_supported(u8 mode)
1515 {
1516 return (mode == PRFCNT_MODE_MANUAL) || (mode == PRFCNT_MODE_PERIODIC);
1517 }
1518
1519 static void
kbasep_kinstr_prfcnt_block_enable_to_physical(uint32_t * phys_em,const uint64_t * enable_mask)1520 kbasep_kinstr_prfcnt_block_enable_to_physical(uint32_t *phys_em,
1521 const uint64_t *enable_mask)
1522 {
1523 *phys_em |= kbase_hwcnt_backend_gpu_block_map_to_physical(
1524 enable_mask[0], enable_mask[1]);
1525 }
1526
1527 /**
1528 * kbasep_kinstr_prfcnt_parse_request_enable - Parse an enable request
1529 * @req_enable: Performance counters enable request to parse.
1530 * @config: Client object the session configuration should be written to.
1531 *
1532 * This function parses a performance counters enable request.
1533 * This type of request specifies a bitmask of HW counters to enable
1534 * for one performance counters block type. In addition to that,
1535 * a performance counters enable request may also set "global"
1536 * configuration properties that affect the whole session, like the
1537 * performance counters set, which shall be compatible with the same value
1538 * set by other performance request items.
1539 *
1540 * Return: 0 on success, else error code.
1541 */
kbasep_kinstr_prfcnt_parse_request_enable(const struct prfcnt_request_enable * req_enable,struct kbase_kinstr_prfcnt_client_config * config)1542 static int kbasep_kinstr_prfcnt_parse_request_enable(
1543 const struct prfcnt_request_enable *req_enable,
1544 struct kbase_kinstr_prfcnt_client_config *config)
1545 {
1546 int err = 0;
1547 u8 req_set = KBASE_HWCNT_SET_UNDEFINED, default_set;
1548
1549 switch (req_enable->set) {
1550 case PRFCNT_SET_PRIMARY:
1551 req_set = KBASE_HWCNT_SET_PRIMARY;
1552 break;
1553 case PRFCNT_SET_SECONDARY:
1554 req_set = KBASE_HWCNT_SET_SECONDARY;
1555 break;
1556 case PRFCNT_SET_TERTIARY:
1557 req_set = KBASE_HWCNT_SET_TERTIARY;
1558 break;
1559 default:
1560 err = -EINVAL;
1561 break;
1562 }
1563
1564 /* The performance counter set is a "global" property that affects
1565 * the whole session. Either this is the first request that sets
1566 * the value, or it shall be identical to all previous requests.
1567 */
1568 if (!err) {
1569 if (config->counter_set == KBASE_HWCNT_SET_UNDEFINED)
1570 config->counter_set = req_set;
1571 else if (config->counter_set != req_set)
1572 err = -EINVAL;
1573 }
1574
1575 /* Temporarily, the requested set cannot be different from the default
1576 * set because it's the only one to be supported. This will change in
1577 * the future.
1578 */
1579 #if defined(CONFIG_MALI_BIFROST_PRFCNT_SET_SECONDARY)
1580 default_set = KBASE_HWCNT_SET_SECONDARY;
1581 #elif defined(CONFIG_MALI_PRFCNT_SET_TERTIARY)
1582 default_set = KBASE_HWCNT_SET_TERTIARY;
1583 #else
1584 /* Default to primary */
1585 default_set = KBASE_HWCNT_SET_PRIMARY;
1586 #endif
1587
1588 if (req_set != default_set)
1589 err = -EINVAL;
1590
1591 if (err < 0)
1592 return err;
1593
1594 /* Enable the performance counters based on the bitmask provided
1595 * by the user space client.
1596 * It is possible to receive multiple requests for the same counter
1597 * block, in which case the bitmask will be a logical OR of all the
1598 * bitmasks given by the client.
1599 */
1600 switch (req_enable->block_type) {
1601 case PRFCNT_BLOCK_TYPE_FE:
1602 kbasep_kinstr_prfcnt_block_enable_to_physical(
1603 &config->phys_em.fe_bm, req_enable->enable_mask);
1604 break;
1605 case PRFCNT_BLOCK_TYPE_TILER:
1606 kbasep_kinstr_prfcnt_block_enable_to_physical(
1607 &config->phys_em.tiler_bm, req_enable->enable_mask);
1608 break;
1609 case PRFCNT_BLOCK_TYPE_MEMORY:
1610 kbasep_kinstr_prfcnt_block_enable_to_physical(
1611 &config->phys_em.mmu_l2_bm, req_enable->enable_mask);
1612 break;
1613 case PRFCNT_BLOCK_TYPE_SHADER_CORE:
1614 kbasep_kinstr_prfcnt_block_enable_to_physical(
1615 &config->phys_em.shader_bm, req_enable->enable_mask);
1616 break;
1617 default:
1618 err = -EINVAL;
1619 break;
1620 }
1621
1622 return err;
1623 }
1624
1625 /**
1626 * kbasep_kinstr_prfcnt_parse_request_scope - Parse a scope request
1627 * @req_scope: Performance counters scope request to parse.
1628 * @config: Client object the session configuration should be written to.
1629 *
1630 * This function parses a performance counters scope request.
1631 * There are only 2 acceptable outcomes: either the client leaves the scope
1632 * as undefined, or all the scope requests are set to the same value.
1633 *
1634 * Return: 0 on success, else error code.
1635 */
kbasep_kinstr_prfcnt_parse_request_scope(const struct prfcnt_request_scope * req_scope,struct kbase_kinstr_prfcnt_client_config * config)1636 static int kbasep_kinstr_prfcnt_parse_request_scope(
1637 const struct prfcnt_request_scope *req_scope,
1638 struct kbase_kinstr_prfcnt_client_config *config)
1639 {
1640 int err = 0;
1641
1642 if (config->scope == PRFCNT_SCOPE_RESERVED)
1643 config->scope = req_scope->scope;
1644 else if (config->scope != req_scope->scope)
1645 err = -EINVAL;
1646
1647 return err;
1648 }
1649
1650 /**
1651 * kbasep_kinstr_prfcnt_parse_setup - Parse session setup
1652 * @kinstr_ctx: Pointer to the kinstr_prfcnt context.
1653 * @setup: Session setup information to parse.
1654 * @config: Client object the session configuration should be written to.
1655 *
1656 * This function parses the list of "request" items sent by the user space
1657 * client, and writes the configuration for the new client to be created
1658 * for the session.
1659 *
1660 * Return: 0 on success, else error code.
1661 */
kbasep_kinstr_prfcnt_parse_setup(struct kbase_kinstr_prfcnt_context * kinstr_ctx,union kbase_ioctl_kinstr_prfcnt_setup * setup,struct kbase_kinstr_prfcnt_client_config * config)1662 static int kbasep_kinstr_prfcnt_parse_setup(
1663 struct kbase_kinstr_prfcnt_context *kinstr_ctx,
1664 union kbase_ioctl_kinstr_prfcnt_setup *setup,
1665 struct kbase_kinstr_prfcnt_client_config *config)
1666 {
1667 uint32_t i;
1668 struct prfcnt_request_item *req_arr;
1669 unsigned int item_count = setup->in.request_item_count;
1670 unsigned long bytes;
1671 int err = 0;
1672
1673 /* Limiting the request items to 2x of the expected: acommodating
1674 * moderate duplications but rejecting excessive abuses.
1675 */
1676 if (!setup->in.requests_ptr || (item_count < 2) ||
1677 (setup->in.request_item_size == 0) ||
1678 item_count > 2 * kinstr_ctx->info_item_count) {
1679 return -EINVAL;
1680 }
1681
1682 bytes = item_count * sizeof(*req_arr);
1683 req_arr = kmalloc(bytes, GFP_KERNEL);
1684 if (!req_arr)
1685 return -ENOMEM;
1686
1687 if (copy_from_user(req_arr, u64_to_user_ptr(setup->in.requests_ptr),
1688 bytes)) {
1689 err = -EFAULT;
1690 goto free_buf;
1691 }
1692
1693 if (req_arr[item_count - 1].hdr.item_type != FLEX_LIST_TYPE_NONE ||
1694 req_arr[item_count - 1].hdr.item_version != 0) {
1695 err = -EINVAL;
1696 goto free_buf;
1697 }
1698
1699 /* The session configuration can only feature one value for some
1700 * properties (like capture mode, block counter set and scope), but the
1701 * client may potential issue multiple requests and try to set more than
1702 * one value for those properties. While issuing multiple requests for the
1703 * same property is allowed by the protocol, asking for different values
1704 * is illegal. Leaving these properties as undefined is illegal, too.
1705 */
1706 config->prfcnt_mode = PRFCNT_MODE_RESERVED;
1707 config->counter_set = KBASE_HWCNT_SET_UNDEFINED;
1708 config->scope = PRFCNT_SCOPE_RESERVED;
1709
1710 for (i = 0; i < item_count - 1; i++) {
1711 if (req_arr[i].hdr.item_version > PRFCNT_READER_API_VERSION) {
1712 err = -EINVAL;
1713 break;
1714 }
1715
1716 switch (req_arr[i].hdr.item_type) {
1717 /* Capture mode is initialized as undefined.
1718 * The first request of this type sets the capture mode.
1719 * The protocol allows the client to send redundant requests,
1720 * but only if they replicate the same value that has already
1721 * been set by the first request.
1722 */
1723 case PRFCNT_REQUEST_TYPE_MODE:
1724 if (!prfcnt_mode_supported(req_arr[i].u.req_mode.mode))
1725 err = -EINVAL;
1726 else if (config->prfcnt_mode == PRFCNT_MODE_RESERVED)
1727 config->prfcnt_mode =
1728 req_arr[i].u.req_mode.mode;
1729 else if (req_arr[i].u.req_mode.mode !=
1730 config->prfcnt_mode)
1731 err = -EINVAL;
1732
1733 if (err < 0)
1734 break;
1735
1736 if (config->prfcnt_mode == PRFCNT_MODE_PERIODIC) {
1737 config->period_ns =
1738 req_arr[i]
1739 .u.req_mode.mode_config.periodic
1740 .period_ns;
1741
1742 if ((config->period_ns != 0) &&
1743 (config->period_ns <
1744 DUMP_INTERVAL_MIN_NS)) {
1745 config->period_ns =
1746 DUMP_INTERVAL_MIN_NS;
1747 }
1748
1749 if (config->period_ns == 0)
1750 err = -EINVAL;
1751 }
1752 break;
1753
1754 case PRFCNT_REQUEST_TYPE_ENABLE:
1755 err = kbasep_kinstr_prfcnt_parse_request_enable(
1756 &req_arr[i].u.req_enable, config);
1757 break;
1758
1759 case PRFCNT_REQUEST_TYPE_SCOPE:
1760 err = kbasep_kinstr_prfcnt_parse_request_scope(
1761 &req_arr[i].u.req_scope, config);
1762 break;
1763
1764 default:
1765 err = -EINVAL;
1766 break;
1767 }
1768
1769 if (err < 0)
1770 break;
1771 }
1772
1773 free_buf:
1774 kfree(req_arr);
1775
1776 if (!err) {
1777 /* Verify that properties (like capture mode and block counter
1778 * set) have been defined by the user space client.
1779 */
1780 if (config->prfcnt_mode == PRFCNT_MODE_RESERVED)
1781 err = -EINVAL;
1782
1783 if (config->counter_set == KBASE_HWCNT_SET_UNDEFINED)
1784 err = -EINVAL;
1785 }
1786
1787 return err;
1788 }
1789
1790 /**
1791 * kbasep_kinstr_prfcnt_client_create() - Create a kinstr_prfcnt client.
1792 * Does not attach to the kinstr_prfcnt
1793 * context.
1794 * @kinstr_ctx: Non-NULL pointer to kinstr_prfcnt context.
1795 * @setup: Non-NULL pointer to hardware counter ioctl setup structure.
1796 * @out_vcli: Non-NULL pointer to where created client will be stored on
1797 * success.
1798 *
1799 * Return: 0 on success, else error code.
1800 */
kbasep_kinstr_prfcnt_client_create(struct kbase_kinstr_prfcnt_context * kinstr_ctx,union kbase_ioctl_kinstr_prfcnt_setup * setup,struct kbase_kinstr_prfcnt_client ** out_vcli)1801 static int kbasep_kinstr_prfcnt_client_create(
1802 struct kbase_kinstr_prfcnt_context *kinstr_ctx,
1803 union kbase_ioctl_kinstr_prfcnt_setup *setup,
1804 struct kbase_kinstr_prfcnt_client **out_vcli)
1805 {
1806 int err;
1807 struct kbase_kinstr_prfcnt_client *cli;
1808 struct kbase_hwcnt_physical_enable_map phys_em;
1809
1810 WARN_ON(!kinstr_ctx);
1811 WARN_ON(!setup);
1812
1813 cli = kzalloc(sizeof(*cli), GFP_KERNEL);
1814
1815 if (!cli)
1816 return -ENOMEM;
1817
1818 cli->kinstr_ctx = kinstr_ctx;
1819 err = kbasep_kinstr_prfcnt_parse_setup(kinstr_ctx, setup, &cli->config);
1820
1821 if (err < 0)
1822 goto error;
1823
1824 cli->config.buffer_count = MAX_BUFFER_COUNT;
1825 cli->dump_interval_ns = cli->config.period_ns;
1826 cli->next_dump_time_ns = 0;
1827 cli->active = false;
1828 atomic_set(&cli->write_idx, 0);
1829 atomic_set(&cli->read_idx, 0);
1830
1831 err = kbase_hwcnt_enable_map_alloc(kinstr_ctx->metadata,
1832 &cli->enable_map);
1833
1834 if (err < 0)
1835 goto error;
1836
1837 phys_em.fe_bm = 0;
1838 phys_em.shader_bm = 0;
1839 phys_em.tiler_bm = 0;
1840 phys_em.mmu_l2_bm = 0;
1841
1842 kbase_hwcnt_gpu_enable_map_from_physical(&cli->enable_map, &phys_em);
1843
1844 cli->sample_count = cli->config.buffer_count;
1845 atomic_set(&cli->sync_sample_count, cli->sample_count);
1846 cli->sample_size = kbasep_kinstr_prfcnt_get_sample_size(
1847 kinstr_ctx->metadata, &cli->tmp_buf);
1848
1849 /* Use virtualizer's metadata to alloc tmp buffer which interacts with
1850 * the HWC virtualizer.
1851 */
1852 err = kbase_hwcnt_dump_buffer_alloc(kinstr_ctx->metadata,
1853 &cli->tmp_buf);
1854
1855 if (err < 0)
1856 goto error;
1857
1858 /* Enable all the available clk_enable_map. */
1859 cli->enable_map.clk_enable_map =
1860 (1ull << kinstr_ctx->metadata->clk_cnt) - 1;
1861
1862 /* Use metadata from virtualizer to allocate dump buffers if
1863 * kinstr_prfcnt doesn't have the truncated metadata.
1864 */
1865 err = kbasep_kinstr_prfcnt_sample_array_alloc(kinstr_ctx->metadata,
1866 cli->config.buffer_count,
1867 &cli->sample_arr);
1868
1869 if (err < 0)
1870 goto error;
1871
1872 err = kbase_hwcnt_virtualizer_client_create(
1873 kinstr_ctx->hvirt, &cli->enable_map, &cli->hvcli);
1874
1875 if (err < 0)
1876 goto error;
1877
1878 init_waitqueue_head(&cli->waitq);
1879 INIT_WORK(&cli->async.dump_work,
1880 kbasep_kinstr_prfcnt_async_dump_worker);
1881 mutex_init(&cli->cmd_sync_lock);
1882 *out_vcli = cli;
1883
1884 return 0;
1885
1886 error:
1887 kbasep_kinstr_prfcnt_client_destroy(cli);
1888 return err;
1889 }
1890
kbasep_kinstr_prfcnt_get_block_info_count(const struct kbase_hwcnt_metadata * metadata)1891 static size_t kbasep_kinstr_prfcnt_get_block_info_count(
1892 const struct kbase_hwcnt_metadata *metadata)
1893 {
1894 size_t grp;
1895 size_t block_info_count = 0;
1896
1897 if (!metadata)
1898 return 0;
1899
1900 for (grp = 0; grp < kbase_hwcnt_metadata_group_count(metadata); grp++) {
1901 block_info_count +=
1902 kbase_hwcnt_metadata_block_count(metadata, grp);
1903 }
1904
1905 return block_info_count;
1906 }
1907
kbasep_kinstr_prfcnt_get_request_info_list(struct kbase_kinstr_prfcnt_context * kinstr_ctx,struct prfcnt_enum_item * item_arr,size_t * arr_idx)1908 static void kbasep_kinstr_prfcnt_get_request_info_list(
1909 struct kbase_kinstr_prfcnt_context *kinstr_ctx,
1910 struct prfcnt_enum_item *item_arr, size_t *arr_idx)
1911 {
1912 memcpy(&item_arr[*arr_idx], kinstr_prfcnt_supported_requests,
1913 sizeof(kinstr_prfcnt_supported_requests));
1914 *arr_idx += ARRAY_SIZE(kinstr_prfcnt_supported_requests);
1915 }
1916
kbasep_kinstr_prfcnt_get_block_info_list(const struct kbase_hwcnt_metadata * metadata,size_t block_set,struct prfcnt_enum_item * item_arr,size_t * arr_idx)1917 int kbasep_kinstr_prfcnt_get_block_info_list(const struct kbase_hwcnt_metadata *metadata,
1918 size_t block_set, struct prfcnt_enum_item *item_arr,
1919 size_t *arr_idx)
1920 {
1921 size_t grp, blk;
1922
1923 if (!metadata || !item_arr || !arr_idx)
1924 return -EINVAL;
1925
1926 for (grp = 0; grp < kbase_hwcnt_metadata_group_count(metadata); grp++) {
1927 for (blk = 0;
1928 blk < kbase_hwcnt_metadata_block_count(metadata, grp);
1929 blk++, (*arr_idx)++) {
1930 size_t blk_inst;
1931 size_t unused_blk_inst_count = 0;
1932 size_t blk_inst_count =
1933 kbase_hwcnt_metadata_block_instance_count(metadata, grp, blk);
1934
1935 item_arr[*arr_idx].hdr.item_type =
1936 PRFCNT_ENUM_TYPE_BLOCK;
1937 item_arr[*arr_idx].hdr.item_version =
1938 PRFCNT_READER_API_VERSION;
1939 item_arr[*arr_idx].u.block_counter.set = block_set;
1940 item_arr[*arr_idx].u.block_counter.block_type =
1941 kbase_hwcnt_metadata_block_type_to_prfcnt_block_type(
1942 kbase_hwcnt_metadata_block_type(
1943 metadata, grp, blk));
1944
1945 /* Count number of unused blocks to updated number of instances */
1946 for (blk_inst = 0; blk_inst < blk_inst_count; blk_inst++) {
1947 if (!kbase_hwcnt_metadata_block_instance_avail(metadata, grp, blk,
1948 blk_inst))
1949 unused_blk_inst_count++;
1950 }
1951
1952 item_arr[*arr_idx].u.block_counter.num_instances =
1953 blk_inst_count - unused_blk_inst_count;
1954 item_arr[*arr_idx].u.block_counter.num_values =
1955 kbase_hwcnt_metadata_block_values_count(
1956 metadata, grp, blk);
1957
1958 /* The bitmask of available counters should be dynamic.
1959 * Temporarily, it is set to U64_MAX, waiting for the
1960 * required functionality to be available in the future.
1961 */
1962 item_arr[*arr_idx].u.block_counter.counter_mask[0] =
1963 U64_MAX;
1964 item_arr[*arr_idx].u.block_counter.counter_mask[1] =
1965 U64_MAX;
1966 }
1967 }
1968
1969 return 0;
1970 }
1971
kbasep_kinstr_prfcnt_enum_info_count(struct kbase_kinstr_prfcnt_context * kinstr_ctx,struct kbase_ioctl_kinstr_prfcnt_enum_info * enum_info)1972 static int kbasep_kinstr_prfcnt_enum_info_count(
1973 struct kbase_kinstr_prfcnt_context *kinstr_ctx,
1974 struct kbase_ioctl_kinstr_prfcnt_enum_info *enum_info)
1975 {
1976 int err = 0;
1977 uint32_t count = 0;
1978 size_t block_info_count = 0;
1979 const struct kbase_hwcnt_metadata *metadata;
1980
1981 count = ARRAY_SIZE(kinstr_prfcnt_supported_requests);
1982 metadata = kbase_hwcnt_virtualizer_metadata(kinstr_ctx->hvirt);
1983 block_info_count = kbasep_kinstr_prfcnt_get_block_info_count(metadata);
1984 count += block_info_count;
1985
1986 /* Reserve one for the last sentinel item. */
1987 count++;
1988 enum_info->info_item_count = count;
1989 enum_info->info_item_size = sizeof(struct prfcnt_enum_item);
1990 kinstr_ctx->info_item_count = count;
1991
1992 return err;
1993 }
1994
kbasep_kinstr_prfcnt_enum_info_list(struct kbase_kinstr_prfcnt_context * kinstr_ctx,struct kbase_ioctl_kinstr_prfcnt_enum_info * enum_info)1995 static int kbasep_kinstr_prfcnt_enum_info_list(
1996 struct kbase_kinstr_prfcnt_context *kinstr_ctx,
1997 struct kbase_ioctl_kinstr_prfcnt_enum_info *enum_info)
1998 {
1999 struct prfcnt_enum_item *prfcnt_item_arr;
2000 size_t arr_idx = 0;
2001 int err = 0;
2002 size_t block_info_count = 0;
2003 const struct kbase_hwcnt_metadata *metadata;
2004
2005 if ((enum_info->info_item_size == 0) ||
2006 (enum_info->info_item_count == 0) || !enum_info->info_list_ptr)
2007 return -EINVAL;
2008
2009 if (enum_info->info_item_count != kinstr_ctx->info_item_count)
2010 return -EINVAL;
2011
2012 prfcnt_item_arr = kcalloc(enum_info->info_item_count,
2013 sizeof(*prfcnt_item_arr), GFP_KERNEL);
2014 if (!prfcnt_item_arr)
2015 return -ENOMEM;
2016
2017 kbasep_kinstr_prfcnt_get_request_info_list(kinstr_ctx, prfcnt_item_arr,
2018 &arr_idx);
2019 metadata = kbase_hwcnt_virtualizer_metadata(kinstr_ctx->hvirt);
2020 block_info_count = kbasep_kinstr_prfcnt_get_block_info_count(metadata);
2021
2022 if (arr_idx + block_info_count >= enum_info->info_item_count)
2023 err = -EINVAL;
2024
2025 if (!err) {
2026 size_t counter_set;
2027
2028 #if defined(CONFIG_MALI_BIFROST_PRFCNT_SET_SECONDARY)
2029 counter_set = KBASE_HWCNT_SET_SECONDARY;
2030 #elif defined(CONFIG_MALI_PRFCNT_SET_TERTIARY)
2031 counter_set = KBASE_HWCNT_SET_TERTIARY;
2032 #else
2033 /* Default to primary */
2034 counter_set = KBASE_HWCNT_SET_PRIMARY;
2035 #endif
2036 kbasep_kinstr_prfcnt_get_block_info_list(
2037 metadata, counter_set, prfcnt_item_arr, &arr_idx);
2038 if (arr_idx != enum_info->info_item_count - 1)
2039 err = -EINVAL;
2040 }
2041
2042 /* The last sentinel item. */
2043 prfcnt_item_arr[enum_info->info_item_count - 1].hdr.item_type =
2044 FLEX_LIST_TYPE_NONE;
2045 prfcnt_item_arr[enum_info->info_item_count - 1].hdr.item_version = 0;
2046
2047 if (!err) {
2048 unsigned long bytes =
2049 enum_info->info_item_count * sizeof(*prfcnt_item_arr);
2050
2051 if (copy_to_user(u64_to_user_ptr(enum_info->info_list_ptr),
2052 prfcnt_item_arr, bytes))
2053 err = -EFAULT;
2054 }
2055
2056 kfree(prfcnt_item_arr);
2057 return err;
2058 }
2059
kbase_kinstr_prfcnt_enum_info(struct kbase_kinstr_prfcnt_context * kinstr_ctx,struct kbase_ioctl_kinstr_prfcnt_enum_info * enum_info)2060 int kbase_kinstr_prfcnt_enum_info(
2061 struct kbase_kinstr_prfcnt_context *kinstr_ctx,
2062 struct kbase_ioctl_kinstr_prfcnt_enum_info *enum_info)
2063 {
2064 int err;
2065
2066 if (!kinstr_ctx || !enum_info)
2067 return -EINVAL;
2068
2069 if (!enum_info->info_list_ptr)
2070 err = kbasep_kinstr_prfcnt_enum_info_count(kinstr_ctx,
2071 enum_info);
2072 else
2073 err = kbasep_kinstr_prfcnt_enum_info_list(kinstr_ctx,
2074 enum_info);
2075
2076 return err;
2077 }
2078
kbase_kinstr_prfcnt_setup(struct kbase_kinstr_prfcnt_context * kinstr_ctx,union kbase_ioctl_kinstr_prfcnt_setup * setup)2079 int kbase_kinstr_prfcnt_setup(struct kbase_kinstr_prfcnt_context *kinstr_ctx,
2080 union kbase_ioctl_kinstr_prfcnt_setup *setup)
2081 {
2082 int err;
2083 struct kbase_kinstr_prfcnt_client *cli = NULL;
2084
2085 if (!kinstr_ctx || !setup)
2086 return -EINVAL;
2087
2088 err = kbasep_kinstr_prfcnt_client_create(kinstr_ctx, setup, &cli);
2089
2090 if (err < 0)
2091 goto error;
2092
2093 mutex_lock(&kinstr_ctx->lock);
2094 kinstr_ctx->client_count++;
2095 list_add(&cli->node, &kinstr_ctx->clients);
2096 mutex_unlock(&kinstr_ctx->lock);
2097
2098 setup->out.prfcnt_metadata_item_size = sizeof(struct prfcnt_metadata);
2099 setup->out.prfcnt_mmap_size_bytes =
2100 cli->sample_size * cli->sample_count;
2101
2102 /* Expose to user-space only once the client is fully initialized */
2103 err = anon_inode_getfd("[mali_kinstr_prfcnt_desc]",
2104 &kinstr_prfcnt_client_fops, cli,
2105 O_RDONLY | O_CLOEXEC);
2106
2107 if (err < 0)
2108 goto client_installed_error;
2109
2110 return err;
2111
2112 client_installed_error:
2113 mutex_lock(&kinstr_ctx->lock);
2114 kinstr_ctx->client_count--;
2115 list_del(&cli->node);
2116 mutex_unlock(&kinstr_ctx->lock);
2117 error:
2118 kbasep_kinstr_prfcnt_client_destroy(cli);
2119 return err;
2120 }
2121