hc
2024-08-16 62c46c9150c4afde7e5b25436263fddf79d66f0b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#include "debug.h"
#include <linux/spinlock.h>
#include <linux/jiffies.h>
 
struct debug_ctrl {
   spinlock_t debug_ctrl_lock;
   bool start;
};
 
static struct debug_ctrl debug_ctrl;
 
void debug_ctrl_init(void)
{
   spin_lock_init(&debug_ctrl.debug_ctrl_lock);
   debug_ctrl.start = false;
}
 
static bool check_debug_ctrl(void)
{
   bool value = false;
 
   spin_lock_bh(&debug_ctrl.debug_ctrl_lock);
   if (debug_ctrl.start)
       value = true;
   spin_unlock_bh(&debug_ctrl.debug_ctrl_lock);
 
   return value;
}
 
#define MAX_TS_NUM 20
struct debug_time_stamp {
   unsigned long ts_enter;
   unsigned int pos;
   unsigned int ts_record[MAX_TS_NUM];
   unsigned int max_ts;
};
 
static struct debug_time_stamp g_debug_ts[MAX_DEBUG_TS_INDEX];
 
void debug_ts_enter(enum debug_ts_index index)
{
   if (!check_debug_ctrl())
       return;
 
   g_debug_ts[index].ts_enter = jiffies;
}
 
void debug_ts_leave(enum debug_ts_index index)
{
   struct debug_time_stamp *ts = &g_debug_ts[index];
 
   if (!check_debug_ctrl() || (ts->ts_enter == 0))
       return;
 
   ts->ts_record[ts->pos] =
       jiffies_to_usecs(jiffies - ts->ts_enter);
 
   if (ts->ts_record[ts->pos] > ts->max_ts)
       ts->max_ts = ts->ts_record[ts->pos];
 
   (ts->pos < (MAX_TS_NUM - 1)) ? ts->pos++ : (ts->pos = 0);
}
 
void debug_ts_show(struct seq_file *s, enum debug_ts_index index)
{
   unsigned int i = 0;
   unsigned int avr_time = 0, avr_cnt = 0;
   struct debug_time_stamp *ts = &g_debug_ts[index];
 
   if (!check_debug_ctrl())
       return;
 
   seq_printf(s, "%s(us):", ts_index2str(index));
   for (i = 0; i < MAX_TS_NUM; i++) {
       seq_printf(s, " %d", ts->ts_record[i]);
       if (ts->ts_record[i] != 0) {
           avr_time += ts->ts_record[i];
           avr_cnt++;
       }
   }
   seq_printf(s, "\n%s average time(us): %d\n",
           ts_index2str(index), avr_time/avr_cnt);
   seq_printf(s, "%s max time(us): %d\n",
           ts_index2str(index), ts->max_ts);
}
 
struct debug_cnt {
   int cnt;
};
 
static struct debug_cnt g_debug_cnt[MAX_DEBUG_CNT_INDEX];
 
void debug_cnt_inc(enum debug_cnt_index index)
{
   if (!check_debug_ctrl())
       return;
 
   g_debug_cnt[index].cnt++;
}
 
void debug_cnt_dec(enum debug_cnt_index index)
{
   if (!check_debug_ctrl())
       return;
 
   g_debug_cnt[index].cnt--;
}
 
void debug_cnt_add(enum debug_cnt_index index, int num)
{
   if (!check_debug_ctrl())
       return;
 
   g_debug_cnt[index].cnt += num;
}
 
void debug_cnt_sub(enum debug_cnt_index index, int num)
{
   if (!check_debug_ctrl())
       return;
 
   g_debug_cnt[index].cnt -= num;
}
 
void debug_cnt_show(struct seq_file *s, enum debug_cnt_index index)
{
   if (!check_debug_ctrl())
       return;
 
   seq_printf(s, "%s: %d\n",
       cnt_index2str(index), g_debug_cnt[index].cnt);
}
 
#define MAX_RECORD_NUM 20
struct debug_record {
   unsigned int pos;
   int record[MAX_TS_NUM];
};
 
static struct debug_record g_debug_record[MAX_RECORD_NUM];
 
void debug_record_add(enum debug_record_index index, int num)
{
   struct debug_record *record = &g_debug_record[index];
 
   if (!check_debug_ctrl())
       return;
 
   record->record[record->pos] = num;
   (record->pos < (MAX_RECORD_NUM - 1)) ?
       record->pos++ : (record->pos = 0);
}
 
void debug_record_show(struct seq_file *s, enum debug_record_index index)
{
   struct debug_record *record = &g_debug_record[index];
   unsigned int i = 0;
 
   if (!check_debug_ctrl())
       return;
 
   seq_printf(s, "%s:", record_index2str(index));
   for (i = 0; i < MAX_RECORD_NUM; i++)
       seq_printf(s, " %d", record->record[i]);
   seq_puts(s, "\n");
}
 
void adjust_ts_cnt_debug(char *buf, unsigned char offset)
{
   int level = buf[offset] - '0';
 
   spin_lock_bh(&debug_ctrl.debug_ctrl_lock);
   if (level == 0) {
       debug_ctrl.start = false;
       spin_unlock_bh(&debug_ctrl.debug_ctrl_lock);
   } else {
       memset(g_debug_ts, 0,
              (MAX_DEBUG_TS_INDEX *
           sizeof(struct debug_time_stamp)));
       memset(g_debug_cnt, 0,
              (MAX_DEBUG_CNT_INDEX * sizeof(struct debug_cnt)));
       memset(g_debug_record, 0,
              (MAX_RECORD_NUM * sizeof(struct debug_record)));
       debug_ctrl.start = true;
       spin_unlock_bh(&debug_ctrl.debug_ctrl_lock);
   }
}