1 /*
2 * Copyright (c) 2019, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #define FARF_ERROR 1
31
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <unistd.h>
36 #include <sys/ioctl.h>
37 #include "HAP_farf.h"
38 #include "verify.h"
39 #include "remote.h"
40 #include "rpcmem.h"
41 #include "AEEstd.h"
42 #include "adsp_perf.h"
43 #include "fastrpc_perf.h"
44 #include "fastrpc_internal.h"
45 #include "fastrpc_apps_user.h"
46
47
48 #ifdef ANDROID_P
49 #define PERF_KEY_KERNEL "vendor.fastrpc.perf.kernel"
50 #define PERF_KEY_ADSP "vendor.fastrpc.perf.adsp"
51 #define PERF_KEY_FREQ "vendor.fastrpc.perf.freq"
52 #else
53 #define PERF_KEY_KERNEL "fastrpc.perf.kernel"
54 #define PERF_KEY_ADSP "fastrpc.perf.adsp"
55 #define PERF_KEY_FREQ "fastrpc.perf.freq"
56 #endif
57
58 #define PERF_MODE 2
59 #define PERF_OFF 0
60 #define PERF_KERNEL_MASK (0x1)
61 #define PERF_ADSP_MASK (0x2)
62 #define PERF_KEY_STR_MAX (2*1024)
63 #define PERF_MAX_NUM_KEYS 64
64
65 #define PERF_NS_TO_US(n) ((n)/1000)
66
67 #define IS_KEY_ENABLED(name) (!std_strncmp((name), "perf_invoke_count", 17) || \
68 !std_strncmp((name), "perf_mod_invoke", 15) || \
69 !std_strncmp((name), "perf_rsp", 8) || \
70 !std_strncmp((name), "perf_hdr_sync_flush", 19) || \
71 !std_strncmp((name), "perf_sync_flush", 15) || \
72 !std_strncmp((name), "perf_hdr_sync_inv", 17) || \
73 !std_strncmp((name), "perf_sync_inv", 13)) \
74
75 struct perf_keys {
76 int64 data[PERF_MAX_NUM_KEYS];
77 int numKeys;
78 int maxLen;
79 int enable;
80 char *keys;
81 };
82
83 struct fastrpc_perf {
84 int count;
85 int freq;
86 int perf_on;
87 struct perf_keys kernel;
88 struct perf_keys dsp;
89 };
90 struct fastrpc_perf gperf;
91
perf_kernel_getkeys(int dev)92 static int perf_kernel_getkeys(int dev) {
93 int nErr = 0;
94 bail:
95 return nErr;
96 }
97
get_perf_kernel(int dev,remote_handle handle,uint32_t sc)98 static void get_perf_kernel(int dev, remote_handle handle, uint32_t sc) {
99 bail:
100 return;
101 }
102
get_perf_adsp(remote_handle handle,uint32_t sc)103 static void get_perf_adsp(remote_handle handle, uint32_t sc) {
104 int nErr = 0;
105 struct fastrpc_perf *p = &gperf;
106 struct perf_keys *pdsp = &gperf.dsp;
107 int ii;
108 char *token;
109
110 char *keystr = pdsp->keys;
111 VERIFY(0 == adsp_perf_get_usecs(pdsp->data, PERF_MAX_NUM_KEYS));
112 VERIFY(pdsp->maxLen < PERF_KEY_STR_MAX);
113 VERIFY(pdsp->numKeys < PERF_MAX_NUM_KEYS);
114 FARF(ALWAYS, "\nFastRPC dsp perf for handle 0x%x sc 0x%x\n", handle, sc);
115 for(ii = 0; ii < pdsp->numKeys; ii++) {
116 token = keystr;
117 keystr += strlen(token) + 1;
118 VERIFY(token);
119 if (!pdsp->data[ii])
120 continue;
121 if (!std_strncmp(token, "perf_invoke_count",17)) {
122 FARF(ALWAYS, "fastrpc.dsp.%-20s : %lld \n", token, pdsp->data[ii]);
123 } else {
124 FARF(ALWAYS, "fastrpc.dsp.%-20s : %lld us\n", token, pdsp->data[ii]);
125 }
126 }
127 bail:
128 return;
129 }
130
fastrpc_perf_update(int dev,remote_handle handle,uint32_t sc)131 void fastrpc_perf_update(int dev, remote_handle handle, uint32_t sc) {
132 int nErr = 0;
133 struct fastrpc_perf *p = &gperf;
134
135 if (!(p->perf_on && !IS_STATIC_HANDLE(handle) && p->freq > 0))
136 return;
137
138 p->count++;
139 if (p->count % p->freq != 0)
140 return;
141
142 if (p->kernel.enable)
143 get_perf_kernel(dev, handle, sc);
144
145 if (p->dsp.enable)
146 get_perf_adsp(handle, sc);
147 bail:
148 return;
149 }
150
perf_dsp_enable(void)151 static int perf_dsp_enable(void) {
152 int nErr = 0;
153 int numKeys = 0, maxLen = 0;
154 char *keys = NULL;
155 int ii;
156
157 keys = (char *)rpcmem_alloc_internal(0, RPCMEM_HEAP_DEFAULT, PERF_KEY_STR_MAX);
158 VERIFY(gperf.dsp.keys = keys);
159 std_memset(keys, 0, PERF_KEY_STR_MAX);
160
161 VERIFY(0 == adsp_perf_get_keys(keys, PERF_KEY_STR_MAX, &maxLen, &numKeys));
162 VERIFY(maxLen < PERF_KEY_STR_MAX);
163 gperf.dsp.maxLen = maxLen;
164 gperf.dsp.numKeys = numKeys;
165 for(ii = 0; ii < numKeys; ii++) {
166 char *name = keys;
167 keys += strlen(name) + 1;
168 if (IS_KEY_ENABLED(name))
169 VERIFY(0 == adsp_perf_enable(ii));
170 }
171 FARF(HIGH, "keys enable done maxLen %d numKeys %d", maxLen, numKeys);
172 bail:
173 return nErr;
174 }
175
fastrpc_perf_init(int dev)176 int fastrpc_perf_init(int dev) {
177 int nErr = 0;
178 struct fastrpc_perf *p = &gperf;
179 struct perf_keys *pk = &gperf.kernel;
180 struct perf_keys *pd = &gperf.dsp;
181
182 pk->enable = FASTRPC_PROPERTY_GET_INT32(PERF_KEY_KERNEL, 0);
183 pd->enable = FASTRPC_PROPERTY_GET_INT32(PERF_KEY_ADSP, 0);
184 p->perf_on = (pk->enable || pd->enable) ? PERF_MODE : PERF_OFF;
185 p->freq = FASTRPC_PROPERTY_GET_INT32(PERF_KEY_FREQ, 1000);
186 VERIFY(p->freq > 0);
187
188 p->count = 0;
189 if (pk->enable) {
190 //VERIFY(!ioctl(dev, FASTRPC_IOCTL_SETMODE, PERF_MODE));
191 VERIFY(NULL != (pk->keys = (char *)calloc(sizeof(char), PERF_KEY_STR_MAX)));
192 VERIFY(0 == perf_kernel_getkeys(dev));
193 }
194
195 if (pd->enable)
196 perf_dsp_enable();
197 bail:
198 if (nErr) {
199 FARF(HIGH, "fastrpc perf init failed");
200 p->perf_on = 0;
201 }
202 return nErr;
203 }
204
fastrpc_perf_deinit(void)205 void fastrpc_perf_deinit(void) {
206 struct fastrpc_perf *p = &gperf;
207 if (p->kernel.keys){
208 free(p->kernel.keys);
209 p->kernel.keys = NULL;
210 }
211 if (p->dsp.keys){
212 rpcmem_free_internal(p->dsp.keys);
213 p->dsp.keys = NULL;
214 }
215 return;
216 }
217
218