blob: 8e8be4219f76b6a0a1fbcd39209d6fdc3a5c0d5c [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * Copyright (C) 2018 MediaTek Inc.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <asm/page.h>
15#include "interface.h"
16#include "met_drv.h"
17
18#ifdef CONFIG_GPU_TRACEPOINTS
19#include <trace/events/gpu.h>
20
21#define show_secs_from_ns(ns) \
22 ({ \
23 u64 t = ns + (NSEC_PER_USEC / 2); \
24 do_div(t, NSEC_PER_SEC); \
25 t; \
26 })
27
28#define show_usecs_from_ns(ns) \
29 ({ \
30 u64 t = ns + (NSEC_PER_USEC / 2) ; \
31 u32 rem; \
32 do_div(t, NSEC_PER_USEC); \
33 rem = do_div(t, USEC_PER_SEC); \
34 })
35
36static int event_gpu_registered;
37static int event_gpu_enabled;
38
39noinline void gpu_sched_switch(const char *gpu_name, u64 timestamp,
40 u32 next_ctx_id, s32 next_prio, u32 next_job_id)
41{
42 MET_TRACE("gpu_name=%s ts=%llu.%06lu next_ctx_id=%lu next_prio=%ld next_job_id=%lu\n",
43 gpu_name,
44 (unsigned long long)show_secs_from_ns(timestamp),
45 (unsigned long)show_usecs_from_ns(timestamp),
46 (unsigned long)next_ctx_id, (long)next_prio, (unsigned long)next_job_id);
47}
48
49MET_DEFINE_PROBE(gpu_sched_switch, TP_PROTO(const char *gpu_name, u64 timestamp,
50 u32 next_ctx_id, s32 next_prio, u32 next_job_id))
51{
52 gpu_sched_switch(gpu_name, timestamp, next_ctx_id, next_prio, next_job_id);
53}
54
55noinline void gpu_job_enqueue(u32 ctx_id, u32 job_id, const char *type)
56{
57 MET_TRACE("ctx_id=%lu job_id=%lu type=%s",
58 (unsigned long)ctx_id, (unsigned long)job_id, type);
59}
60
61MET_DEFINE_PROBE(gpu_job_enqueue, TP_PROTO(u32 ctx_id, u32 job_id, const char *type))
62{
63 gpu_job_enqueue(ctx_id, job_id, type);
64}
65#endif
66
67static int reset_driver_stat(void)
68{
69#ifdef CONFIG_GPU_TRACEPOINTS
70 event_gpu_enabled = 0;
71#endif
72 met_trace_event.mode = 0;
73 return 0;
74}
75
76
77
78static void met_event_start(void)
79{
80#ifdef CONFIG_GPU_TRACEPOINTS
81 /* register trace event for gpu */
82 do {
83 if (!event_gpu_enabled)
84 break;
85 if (MET_REGISTER_TRACE(gpu_sched_switch)) {
86 pr_debug("can not register callback of gpu_sched_switch\n");
87 break;
88 }
89 if (MET_REGISTER_TRACE(gpu_job_enqueue)) {
90 pr_debug("can not register callback of gpu_job_enqueue\n");
91 MET_UNREGISTER_TRACE(gpu_sched_switch);
92 break;
93 }
94 event_gpu_registered = 1;
95 } while (0);
96#endif
97}
98
99static void met_event_stop(void)
100{
101#ifdef CONFIG_GPU_TRACEPOINTS
102 /* unregister trace event for gpu */
103 if (event_gpu_registered) {
104 MET_UNREGISTER_TRACE(gpu_job_enqueue);
105 MET_UNREGISTER_TRACE(gpu_sched_switch);
106 event_gpu_registered = 0;
107 }
108#endif
109}
110
111static int met_event_process_argument(const char *arg, int len)
112{
113 int ret = -1;
114
115#ifdef CONFIG_GPU_TRACEPOINTS
116 if (strcasecmp(arg, "gpu") == 0) {
117 event_gpu_enabled = 1;
118 met_trace_event.mode = 1;
119 ret = 0;
120 }
121#endif
122
123 return ret;
124}
125
126static const char help[] = "\b"
127#ifdef CONFIG_GPU_TRACEPOINTS
128 " --event=gpu output gpu trace events\n"
129#endif
130 ;
131
132static int met_event_print_help(char *buf, int len)
133{
134 return snprintf(buf, PAGE_SIZE, help);
135}
136
137static const char header[] =
138 "met-info [000] 0.0: met_ftrace_event:"
139#ifdef CONFIG_GPU_TRACEPOINTS
140 " gpu:gpu_sched_switch gpu:gpu_job_enqueue"
141#endif
142 "\n";
143
144static int met_event_print_header(char *buf, int len)
145{
146 int ret;
147
148 ret = snprintf(buf, PAGE_SIZE, header);
149 return ret;
150}
151
152struct metdevice met_trace_event = {
153 .name = "event",
154 .type = MET_TYPE_PMU,
155 .start = met_event_start,
156 .stop = met_event_stop,
157 .reset = reset_driver_stat,
158 .process_argument = met_event_process_argument,
159 .print_help = met_event_print_help,
160 .print_header = met_event_print_header,
161};