blob: 6f7e1ab1e9e6b5e94c3a7cd95a46b6dd4a4d1a10 [file] [log] [blame]
xf.lied996a22025-03-13 23:49:05 -07001/*
2 * tracker.c - System accounting over taskstats interface
3 *
4 * Copyright (C) Jay Lan, <jlan@sgi.com>
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18#include <linux/io.h>
19#include <linux/module.h>
20#include <linux/kernel.h>
21#include <linux/sched.h>
22#include <linux/jiffies.h>
23#include <linux/slab.h>
24#include <linux/timer.h>
25#include <linux/delay.h>
26#include <linux/kthread.h>
27#include <linux/timer.h>
28#include <linux/uaccess.h>
29#include <linux/export.h>
30#include <linux/sched/clock.h>
31#include "ram_config.h"
32
33/*******************************************************************************
34* ºê¶¨Òå *
35*******************************************************************************/
36#define _OS_LINUX 1
37
38#if defined(_OS_TOS)
39# define OS_STATISTIC_IRAM_BASE (IRAM_BASE_ADDR_OS_STATISTIC_PSCPU)
40# define OS_STATISTIC_TIME zDrvTimer_Stamp()
41#elif defined(_OS_LINUX)
42# define OS_STATISTIC_IRAM_BASE g_zxic_trace_apcpu_addr //(IRAM_BASE_ADDR_OS_STATISTIC_APCPU)
43# define OS_STATISTIC_TIME (cpu_clock(0)>>10)
44#else
45# error "unknown os"
46#endif
47
48
49
50#define OS_IRAM_STATISTIC_CNT (5)
51#define OS_IRAM_STATISTIC_NAME_LEN (16)
52#define OS_DDR_STATISTIC_CNT (1000)
53
54#define OS_IRAM_THREAD_SWAPIN (OS_STATISTIC_IRAM_BASE)
55#define OS_IRAM_IRQ_START (OS_IRAM_THREAD_SWAPIN + sizeof(t_os_iram_thread_statistic))
56#define OS_IRAM_IRQ_END (OS_IRAM_IRQ_START + sizeof(t_os_iram_statistic))
57
58#if defined(_OS_TOS)
59#define OS_IRAM_DSR_START (OS_IRAM_IRQ_END + sizeof(t_os_iram_statistic))
60#define OS_IRAM_DSR_END (OS_IRAM_DSR_START + sizeof(t_os_iram_statistic))
61#elif defined(_OS_LINUX)
62#define OS_IRAM_SOFTIRQ_START (OS_IRAM_IRQ_END + sizeof(t_os_iram_statistic))
63#define OS_IRAM_SOFTIRQ_END (OS_IRAM_SOFTIRQ_START + sizeof(t_os_iram_statistic))
64#define OS_IRAM_TIMER_START (OS_IRAM_SOFTIRQ_END + sizeof(t_os_iram_statistic))
65#define OS_IRAM_TIMER_END (OS_IRAM_TIMER_START + sizeof(t_os_iram_statistic))
66#endif
67
68#define os_statistic_check() *((volatile unsigned long *)OS_STATISTIC_IRAM_BASE)
69#define os_statistic_enabled() g_os_statistic_enable
70
71/*******************************************************************************
72* Êý¾Ý½á¹¹¶¨Òå *
73*******************************************************************************/
74typedef volatile struct {
75 unsigned int cnt;
76 unsigned int index;
77 struct {
78 unsigned char name[OS_IRAM_STATISTIC_NAME_LEN];
79 unsigned int data2;
80 } statistics[OS_IRAM_STATISTIC_CNT];
81}t_os_iram_thread_statistic;
82
83typedef volatile struct {
84 unsigned int cnt;
85 unsigned int index;
86 struct {
87 unsigned int data1;
88 unsigned int data2;
89 } statistics[OS_IRAM_STATISTIC_CNT];
90}t_os_iram_statistic;
91
92typedef struct {
93 unsigned int cnt;
94 unsigned int index;
95 struct {
96 unsigned int data1;
97 unsigned int data2;
98 } statistics[OS_DDR_STATISTIC_CNT];
99}t_os_ddr_statistic;
100
101/*******************************************************************************
102* È«¾Ö±äÁ¿ *
103*******************************************************************************/
104#if defined(_OS_LINUX)
105volatile static char *g_zxic_trace_apcpu_addr;
106#endif
107
108volatile static int g_os_statistic_enable;
109volatile static unsigned int g_os_statistic_cnt;
110
111volatile static t_os_iram_thread_statistic *g_os_iram_swapin_statistic;
112volatile static t_os_iram_statistic *g_os_iram_irq_start_statistic;
113volatile static t_os_iram_statistic *g_os_iram_irq_end_statistic;
114
115#if defined(_OS_TOS)
116static t_os_iram_statistic *g_os_iram_dsr_start_statistic;
117static t_os_iram_statistic *g_os_iram_dsr_end_statistic;
118#elif defined(_OS_LINUX)
119volatile static t_os_iram_statistic *g_os_iram_softirq_start_statistic;
120volatile static t_os_iram_statistic *g_os_iram_softirq_end_statistic;
121volatile static t_os_iram_statistic *g_os_iram_timer_start_statistic;
122volatile static t_os_iram_statistic *g_os_iram_timer_end_statistic;
123#endif
124
125volatile static t_os_ddr_statistic *g_os_ddr_swapin_statistic;
126volatile static t_os_ddr_statistic *g_os_ddr_irq_start_statistic;
127volatile static t_os_ddr_statistic *g_os_ddr_irq_end_statistic;
128
129#if defined(_OS_TOS)
130static t_os_ddr_statistic *g_os_ddr_dsr_start_statistic;
131static t_os_ddr_statistic *g_os_ddr_dsr_end_statistic;
132#elif defined(_OS_LINUX)
133volatile static t_os_ddr_statistic *g_os_ddr_softirq_start_statistic;
134volatile static t_os_ddr_statistic *g_os_ddr_softirq_end_statistic;
135volatile static t_os_ddr_statistic *g_os_ddr_timer_start_statistic;
136volatile static t_os_ddr_statistic *g_os_ddr_timer_end_statistic;
137#endif
138
139/*******************************************************************************
140* È«¾Öº¯ÊýÉùÃ÷ *
141*******************************************************************************/
142void os_statistic_enable(void);
143/*******************************************************************************
144* ¾Ö²¿º¯Êý *
145*******************************************************************************/
146/*******************************************************************************
147* ¹¦ÄÜÃèÊö: ¹ì¼£Í³¼Æµ½IRAM
148* ²ÎÊý˵Ã÷:
149* (´«Èë²ÎÊý) iram_addr: µØÖ·
150 data: ʼþÏî
151 time: ʱ¼ä
152* (´«³ö²ÎÊý) void
153* ·µ »Ø Öµ: void
154* ÆäËü˵Ã÷: ÎÞ
155*******************************************************************************/
156static inline void os_statistic_in_iram(volatile void *iram_addr, void *data, unsigned long time)
157{
158 unsigned long index;
159 t_os_iram_statistic *iram;
160
161 iram = (t_os_iram_statistic *)iram_addr;
162
163 index = iram->index;
164 if(index >= OS_IRAM_STATISTIC_CNT)
165 {
166 index = 0;
167 }
168
169 iram->statistics[index].data1 = (unsigned int)data;
170 iram->statistics[index].data2 = time;
171 index++;
172
173 iram->index = index;
174 iram->cnt = g_os_statistic_cnt;
175}
176
177/*******************************************************************************
178* ¹¦ÄÜÃèÊö: Ï̹߳켣ͳ¼Æµ½IRAM
179* ²ÎÊý˵Ã÷:
180* (´«Èë²ÎÊý) iram_addr: µØÖ·
181 data: ʼþÏî
182 time: ʱ¼ä
183* (´«³ö²ÎÊý) void
184* ·µ »Ø Öµ: void
185* ÆäËü˵Ã÷: ÎÞ
186*******************************************************************************/
187static inline void os_statistic_thread_in_iram(volatile void *iram_addr, void *data, unsigned long time)
188{
189 unsigned long index;
190 t_os_iram_thread_statistic *iram;
191
192 iram = (t_os_iram_thread_statistic *)iram_addr;
193
194 index = iram->index;
195 if(index >= OS_IRAM_STATISTIC_CNT)
196 {
197 index = 0;
198 }
199
200#if defined(_OS_TOS)
201 strncpy((char *)(iram->statistics[index].name), cyg_thread_get_name((cyg_handle_t)data), OS_IRAM_STATISTIC_NAME_LEN - 1);
202#elif defined(_OS_LINUX)
203 strncpy((char *)(iram->statistics[index].name), ((struct task_struct *)data)->comm, OS_IRAM_STATISTIC_NAME_LEN - 1);
204#else
205# error "unkown os"
206#endif
207 iram->statistics[index].name[OS_IRAM_STATISTIC_NAME_LEN - 1] = 0;
208 iram->statistics[index].data2 = time;
209 index++;
210
211 iram->index = index;
212 iram->cnt = g_os_statistic_cnt;
213}
214
215/*******************************************************************************
216* ¹¦ÄÜÃèÊö: ¹ì¼£Í³¼Æµ½DDR
217* ²ÎÊý˵Ã÷:
218* (´«Èë²ÎÊý) iram_addr: µØÖ·
219 data: ʼþÏî
220 time: ʱ¼ä
221* (´«³ö²ÎÊý) void
222* ·µ »Ø Öµ: void
223* ÆäËü˵Ã÷: ÎÞ
224*******************************************************************************/
225static inline void os_statistic_in_ddr(void *ddr_addr, void *data, unsigned long time)
226{
227 unsigned long index;
228 t_os_ddr_statistic *ddr;
229
230 ddr = (t_os_ddr_statistic *)ddr_addr;
231
232 index = ddr->index;
233 if (index >= OS_DDR_STATISTIC_CNT)
234 {
235 index = 0;
236 }
237 ddr->statistics[index].data1 = (unsigned int)data;
238 ddr->statistics[index].data2 = time;
239 index++;
240
241 ddr->index = index;
242 ddr->cnt = g_os_statistic_cnt;
243}
244
245/*******************************************************************************
246* ¹¦ÄÜÃèÊö: ¹ì¼£Í³¼Æµ½DDR
247* ²ÎÊý˵Ã÷:
248* (´«Èë²ÎÊý) iram_addr: µØÖ·
249 data: ʼþÏî
250 time: ʱ¼ä
251* (´«³ö²ÎÊý) void
252* ·µ »Ø Öµ: void
253* ÆäËü˵Ã÷: ÎÞ
254*******************************************************************************/
255static inline void os_statistic_info_update(void)
256{
257 g_os_statistic_cnt++;
258}
259
260/*******************************************************************************
261* ¹¦ÄÜÃèÊö: ¶¨Ê±Æ÷»Øµ÷¹³×Ó
262* ²ÎÊý˵Ã÷:
263* (´«Èë²ÎÊý)
264* (´«³ö²ÎÊý) void
265* ·µ »Ø Öµ: void
266* ÆäËü˵Ã÷: ÎÞ
267*******************************************************************************/
268static int os_statistic_delayed_work_timer_fn(unsigned long data)
269{
270 int sec = 0;
271 msleep(20000);
272 while(!os_statistic_check())
273 {
274 //³¬¹ý40s£¬Ö±½ÓÍ˳ö
275 if(sec >= 4)
276 return 0;
277 msleep(10000);
278 sec++;
279 }
280 os_statistic_enable();
281 return 0;
282}
283
284/*******************************************************************************
285* È«¾Öº¯ÊýʵÏÖ *
286*******************************************************************************/
287/*******************************************************************************
288* ¹¦ÄÜÃèÊö: ʹÄܹ켣ͳ¼Æ¹¦ÄÜ
289* ²ÎÊý˵Ã÷:
290* (´«Èë²ÎÊý) address: ¼Ç¼µ½IRAMÖеĵØÖ·
291 size: IRAM¿Õ¼ä´óС
292* (´«³ö²ÎÊý) void
293* ·µ »Ø Öµ: void
294* ÆäËü˵Ã÷: ÎÞ
295*******************************************************************************/
296void os_statistic_enable(void)
297{
298#if defined(_OS_TOS)
299 g_os_iram_swapin_statistic = (t_os_iram_thread_statistic *)OS_IRAM_THREAD_SWAPIN;
300 g_os_iram_irq_start_statistic = (t_os_iram_statistic *)OS_IRAM_IRQ_START;
301 g_os_iram_irq_end_statistic = (t_os_iram_statistic *)OS_IRAM_IRQ_END;
302 g_os_iram_dsr_start_statistic = (t_os_iram_statistic *)OS_IRAM_DSR_START;
303 g_os_iram_dsr_end_statistic = (t_os_iram_statistic *)OS_IRAM_DSR_END;
304
305 g_os_ddr_swapin_statistic = (t_os_ddr_statistic *)zOss_Malloc(sizeof(t_os_ddr_statistic));
306 g_os_ddr_irq_start_statistic = (t_os_ddr_statistic *)zOss_Malloc(sizeof(t_os_ddr_statistic));
307 g_os_ddr_irq_end_statistic = (t_os_ddr_statistic *)zOss_Malloc(sizeof(t_os_ddr_statistic));
308 g_os_ddr_dsr_start_statistic = (t_os_ddr_statistic *)zOss_Malloc(sizeof(t_os_ddr_statistic));
309 g_os_ddr_dsr_end_statistic = (t_os_ddr_statistic *)zOss_Malloc(sizeof(t_os_ddr_statistic));
310#elif defined(_OS_LINUX)
311 g_os_iram_swapin_statistic = (t_os_iram_thread_statistic *)OS_IRAM_THREAD_SWAPIN;
312 g_os_iram_irq_start_statistic = (t_os_iram_statistic *)OS_IRAM_IRQ_START;
313 g_os_iram_irq_end_statistic = (t_os_iram_statistic *)OS_IRAM_IRQ_END;
314 g_os_iram_softirq_start_statistic = (t_os_iram_statistic *)OS_IRAM_SOFTIRQ_START;
315 g_os_iram_softirq_end_statistic = (t_os_iram_statistic *)OS_IRAM_SOFTIRQ_END;
316 g_os_iram_timer_start_statistic = (t_os_iram_statistic *)OS_IRAM_TIMER_START;
317 g_os_iram_timer_end_statistic = (t_os_iram_statistic *)OS_IRAM_TIMER_END;
318
319 g_os_ddr_swapin_statistic = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
320 g_os_ddr_irq_start_statistic = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
321 g_os_ddr_irq_end_statistic = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
322 g_os_ddr_softirq_start_statistic = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
323 g_os_ddr_softirq_end_statistic = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
324 g_os_ddr_timer_start_statistic = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
325 g_os_ddr_timer_end_statistic = (t_os_ddr_statistic *)kmalloc(sizeof(t_os_ddr_statistic), GFP_KERNEL);
326
327#else
328# error "unkown os"
329#endif
330 if ((unsigned int )g_os_iram_timer_end_statistic - (unsigned int )g_os_iram_swapin_statistic > (unsigned int )IRAM_BASE_LEN_OS_STATISTIC_PSCPU )
331 {
332 BUG();
333 }
334 g_os_statistic_enable = 1;
335}
336EXPORT_SYMBOL(os_statistic_enable);
337
338void zxic_trace_task_switch(struct task_struct *next)
339{
340 unsigned long time;
341 if (!g_os_statistic_enable)
342 return ;
343
344 time = OS_STATISTIC_TIME;
345 os_statistic_thread_in_iram(g_os_iram_swapin_statistic, next, time);
346 os_statistic_in_ddr(g_os_ddr_swapin_statistic, next, time);
347 os_statistic_info_update();
348}
349
350void zxic_trace_irq_enter(u32 irq)
351{
352 unsigned long time;
353 if (!g_os_statistic_enable)
354 return ;
355
356 time = OS_STATISTIC_TIME;
357 os_statistic_in_iram(g_os_iram_irq_start_statistic, irq, time);
358 os_statistic_in_ddr(g_os_ddr_irq_start_statistic, irq, time);
359 os_statistic_info_update();
360}
361
362void zxic_trace_irq_exit(u32 irq)
363{
364 unsigned long time;
365 if (!g_os_statistic_enable)
366 return ;
367
368 time = OS_STATISTIC_TIME;
369 os_statistic_in_iram(g_os_iram_irq_end_statistic, irq, time);
370 os_statistic_in_ddr(g_os_ddr_irq_end_statistic, irq, time);
371 os_statistic_info_update();
372}
373
374void zxic_trace_softirq_enter(u32 vec_nr)
375{
376 unsigned long time;
377 if (!g_os_statistic_enable)
378 return ;
379
380 time = OS_STATISTIC_TIME;
381 os_statistic_in_iram(g_os_iram_softirq_start_statistic, vec_nr, time);
382 os_statistic_in_ddr(g_os_ddr_softirq_start_statistic, vec_nr, time);
383 os_statistic_info_update();
384}
385
386void zxic_trace_softirq_exit(u32 vec_nr)
387{
388 unsigned long time;
389 if (!g_os_statistic_enable)
390 return ;
391
392 time = OS_STATISTIC_TIME;
393 os_statistic_in_iram(g_os_iram_softirq_end_statistic, vec_nr, time);
394 os_statistic_in_ddr(g_os_ddr_softirq_end_statistic, vec_nr, time);
395 os_statistic_info_update();
396}
397
398void zxic_trace_timer_enter(void *func)
399{
400 unsigned long time;
401 if (!g_os_statistic_enable)
402 return ;
403
404 time = OS_STATISTIC_TIME;
405 os_statistic_in_iram(g_os_iram_timer_start_statistic, func, time);
406 os_statistic_in_ddr(g_os_ddr_timer_start_statistic, func, time);
407 os_statistic_info_update();
408}
409
410void zxic_trace_timer_exit(void *func)
411{
412 unsigned long time;
413 if (!g_os_statistic_enable)
414 return ;
415
416 time = OS_STATISTIC_TIME;
417 os_statistic_in_iram(g_os_iram_timer_end_statistic, func, time);
418 os_statistic_in_ddr(g_os_ddr_timer_end_statistic, func, time);
419 os_statistic_info_update();
420}
421
422
423/*******************************************************************************
424* ¹¦ÄÜÃèÊö: ¹ì¼£Í³¼Æµ½DDR
425* ²ÎÊý˵Ã÷:
426* (´«Èë²ÎÊý) iram_addr: µØÖ·
427 data: ʼþÏî
428 time: ʱ¼ä
429* (´«³ö²ÎÊý) void
430* ·µ »Ø Öµ: void
431* ÆäËü˵Ã÷: ÎÞ
432*******************************************************************************/
433int __init zxic_enable_tracer(void)
434{
435 struct timer_list timer;
436 struct task_struct *task;
437
438#ifdef IRAM_BASE_ADDR_VA
439 g_zxic_trace_apcpu_addr = IRAM_BASE_ADDR_OS_STATISTIC_PSCPU;
440#else
441 g_zxic_trace_apcpu_addr = ioremap(IRAM_BASE_ADDR_OS_STATISTIC_PSCPU, IRAM_BASE_LEN_OS_STATISTIC_PSCPU);
442#endif
443
444 /*
445 init_timer(&timer);
446 timer.expires = jiffies + 40*HZ;//msecs_to_jiffies(40*1000);//ÑÓ³Ù40Ãë
447 timer.data = 0;
448 timer.function = os_statistic_delayed_work_timer_fn;
449 setup_timer(&timer, os_statistic_delayed_work_timer_fn, 0);
450 add_timer(&timer);
451 */
452 //task = kthread_create(os_statistic_delayed_work_timer_fn, 0, "g_zxic_trace_sync_thread", 0);
453 //wake_up_process(task);
454 os_statistic_enable();
455 return 0x0;
456}
457module_init(zxic_enable_tracer);
458
459