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