2 * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <sys/types.h>
29 #include "ss_resm_resourcemanagerlog.h"
33 typedef struct _task_stat {
34 struct _task_stat *next;
41 unsigned long utime; // NOLINT
42 unsigned long stime; // NOLINT
46 unsigned int task_rt_priority;
47 unsigned int task_policy;
51 typedef struct _task_rank
55 unsigned long taskOccupancy;
59 unsigned int task_policy;
65 static TASK_STAT *g_task_stat = NULL;
67 static int32_t g_fifo_task_pid = -1;
68 static int32_t g_tss_task_pid = -1;
69 static unsigned long g_fifo_task_occ = -1;
70 static unsigned long g_tss_task_occ = -1;
71 static int32_t g_fifo_show_timer = 0;
72 static int32_t g_tss_show_timer = 0;
73 static unsigned int g_startTime = 0;
74 static char g_fifo_path[64];
75 static char g_tss_path[64];
76 static unsigned long g_fifo_utime;
77 static unsigned long g_fifo_stime;
78 static unsigned long g_tss_utime;
79 static unsigned long g_tss_stime;
82 static void cleanup_task_stat(void) {
94 static int add_task_stat(TASK_STAT *tstat) {
97 p = reinterpret_cast<TASK_STAT *>(malloc(sizeof(TASK_STAT)));
98 if (p == NULL) { // LCOV_EXCL_BR_LINE 5: malloc error case
99 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
100 return -1; // LCOV_EXCL_LINE 5: malloc error case
102 memcpy(p, tstat, sizeof(TASK_STAT));
106 p->next = g_task_stat;
114 static int get_task_stat(const char *path, TASK_STAT *tstat) {
116 int tty_nr, tty_pgrp;
117 unsigned long task_flags; // NOLINT
118 unsigned long min_flt, cmin_flt, maj_flt, cmaj_flt; // NOLINT
119 signed long cutime, cstime; // NOLINT
120 int num_threads, zero1;
121 unsigned long long start_time; // NOLINT
122 unsigned long vsize, mm_rss, rsslim, start_code, end_code, start_stack; // NOLINT
123 unsigned long esp, eip, task_pending_signal_sig, task_blocked_sig; // NOLINT
124 unsigned long sigign_sig, sigcatch_sig, wchan, zero2, zero3; // NOLINT
126 unsigned long long delayacct_blkio_ticks; // NOLINT
127 unsigned long guest_time; // NOLINT
128 signed long cguest_time; // NOLINT
132 #define READ_MAX_SIZE 4096
133 char buf[READ_MAX_SIZE];
135 fd = open(path, O_RDONLY);
137 if (read(fd, buf, sizeof(buf)) != -1) { // LCOV_EXCL_BR_LINE 5: read's error case
141 "%d %32s %c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %d %d %d %d %llu %lu %lu"
142 " %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld",
143 &(tstat->pid_nr_ns), tstat->tcomm, &(tstat->state),
144 &(tstat->ppid), &(tstat->pgid), &sid, &tty_nr, &tty_pgrp,
145 &task_flags, &min_flt, &cmin_flt, &maj_flt, &cmaj_flt,
146 &(tstat->utime), &(tstat->stime), &cutime, &cstime,
147 &(tstat->priority), &(tstat->nice), &num_threads, &zero1,
148 &start_time, &vsize, &mm_rss, &rsslim, &start_code, &end_code,
149 &start_stack, &esp, &eip, &task_pending_signal_sig,
150 &task_blocked_sig, &sigign_sig, &sigcatch_sig, &wchan, &zero2,
151 &zero3, &exit_signal, &(tstat->task_cpu),
152 &(tstat->task_rt_priority), &(tstat->task_policy),
153 &delayacct_blkio_ticks, &guest_time, &cguest_time);
160 static void get_current_task_stat(void) {
164 struct dirent *result;
169 dirp = opendir("/proc");
170 if (dirp == NULL) { // LCOV_EXCL_BR_LINE 5: opendir error case
171 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
172 return; // LCOV_EXCL_LINE 5: opendir error case
175 if (clock_gettime (CLOCK_MONOTONIC, &tp) == 0) {
176 g_startTime = ((tp.tv_sec * 1000) + (tp.tv_nsec / 1000000)); // Unit is msec
181 while ((readdir_r(dirp, &entry, &result) == 0) && (result != NULL)) {
182 if ((entry.d_name[0] >= '1') && (entry.d_name[0] <= '9')) {
184 struct dirent entry2;
185 struct dirent *result2;
187 sprintf(path, "/proc/%s/task", entry.d_name); // NOLINT
188 dirp2 = opendir(path);
189 if (dirp2 == NULL) { // LCOV_EXCL_BR_LINE 5: opendir error case
190 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
191 continue; // LCOV_EXCL_LINE 5: opendir error case
194 while ((readdir_r(dirp2, &entry2, &result2) == 0) && (result2 != NULL)) {
195 if ((entry2.d_name[0] >= '1') && (entry2.d_name[0] <= '9')) {
198 struct timespec req = { 0, 1000000 }; // 1msec
200 sprintf(path2, "%s/%s/stat", path, entry2.d_name); // NOLINT
201 ret = get_task_stat(path2, &tstat);
203 // if ((ret > 0) && (tstat.task_policy == SCHED_FIFO)) {
204 if (ret > 0) { // LCOV_EXCL_BR_LINE 200: ret must be bigger than 0
206 strcpy(tstat.path, path2); // NOLINT
207 add_task_stat(&tstat);
209 nanosleep(&req, NULL);
218 static void show_cpuload(void) {
221 TASK_STAT *p = g_task_stat;
223 TASK_RANK ttaskRankData[TASK_STAT_RANK_NUM+1];
224 TASK_RANK t_eva_taskRank;
225 int setRankDatanum = 0;
228 unsigned long dtime; // NOLINT
229 unsigned long dtime_urank;
230 unsigned long dtime_drank;
232 unsigned int endTime = 0;
235 // FRAMEWORKUNIFIEDLOG(
238 // "[CpuHighLoad]Please check User backtrace of following processes in kernel.log");
239 // FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__,
240 // "[CpuHighLoad] PID ST PRI POLICY cpuX %%CPU (ut:st) comm");
242 if (clock_gettime (CLOCK_MONOTONIC, &tp) == 0) {
243 endTime = ((tp.tv_sec * 1000) + (tp.tv_nsec / 1000000)); // Unit is msec
245 endTime = (WTC_CPU_INTERVAL * 1000) + g_startTime;
247 if (endTime - g_startTime <= 0) { // LCOV_EXCL_BR_LINE 200: (endTime - g_startTime) must be bigger than 0
248 // LCOV_EXCL_START 200: (endTime - g_startTime) must be bigger than 0
249 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
250 FRAMEWORKUNIFIEDLOG (ZONE_WARN, __FUNCTION__, "[CpuHighLoad] Timer abnormality.");
251 endTime = g_startTime + 1;
256 ret = get_task_stat(p->path, &tstat);
260 dtime = (tstat.utime + tstat.stime) - (p->utime + p->stime);
265 "[CpuHighLoad]%5d %c %3d %5s cpu%d %4lu (%lu:%lu) %s",
269 p->task_policy == SCHED_FIFO ? "FIFO" :
270 p->task_policy == SCHED_RR ? "RR" : "OTHER",
271 p->task_cpu, dtime, tstat.utime - p->utime, tstat.stime - p->stime,
273 if ((dtime >= 70) // %%CPU 70% over only
274 && (getpid() != p->pid_nr_ns) // except current process
275 && (strcmp(p->tcomm, "(NS_BackupMgr)"))) { // except "BackupMgr"
276 // print_backtrace_pid (p->pid_nr_ns); // backtrace in kernel.log
283 dtime = (((tstat.utime + tstat.stime) - (p->utime + p->stime)) * 1000) / (endTime - g_startTime);
284 if (((tstat.utime + tstat.stime) - (p->utime + p->stime)) > 0) {
285 if (setRankDatanum <= TASK_STAT_RANK_NUM) {
286 ttaskRankData[setRankDatanum].pid_nr_ns = p->pid_nr_ns;
287 ttaskRankData[setRankDatanum].state = p->state;
288 ttaskRankData[setRankDatanum].priority = p->priority;
289 ttaskRankData[setRankDatanum].task_policy = p->task_policy;
290 ttaskRankData[setRankDatanum].task_cpu = p->task_cpu;
291 ttaskRankData[setRankDatanum].taskOccupancy = dtime;
292 ttaskRankData[setRankDatanum].utime = tstat.utime - p->utime;
293 ttaskRankData[setRankDatanum].stime = tstat.stime - p->stime;
294 strcpy(ttaskRankData[setRankDatanum].tcomm, p->tcomm);
297 ttaskRankData[TASK_STAT_RANK_NUM].pid_nr_ns = p->pid_nr_ns;
298 ttaskRankData[TASK_STAT_RANK_NUM].state = p->state;
299 ttaskRankData[TASK_STAT_RANK_NUM].priority = p->priority;
300 ttaskRankData[TASK_STAT_RANK_NUM].task_policy = p->task_policy;
301 ttaskRankData[TASK_STAT_RANK_NUM].task_cpu = p->task_cpu;
302 ttaskRankData[TASK_STAT_RANK_NUM].taskOccupancy = dtime;
303 ttaskRankData[TASK_STAT_RANK_NUM].utime = tstat.utime - p->utime;
304 ttaskRankData[TASK_STAT_RANK_NUM].stime = tstat.stime - p->stime;
305 strcpy(ttaskRankData[TASK_STAT_RANK_NUM].tcomm, p->tcomm);
307 for (checkCounter = (setRankDatanum - 1); checkCounter > 0; checkCounter--) {
308 dtime_urank = ttaskRankData[checkCounter - 1].utime + ttaskRankData[checkCounter - 1].stime;
309 dtime_drank = ttaskRankData[checkCounter].utime + ttaskRankData[checkCounter].stime;
310 if (dtime_urank < dtime_drank) {
311 t_eva_taskRank.pid_nr_ns = ttaskRankData[checkCounter].pid_nr_ns;
312 t_eva_taskRank.state = ttaskRankData[checkCounter].state;
313 t_eva_taskRank.priority = ttaskRankData[checkCounter].priority;
314 t_eva_taskRank.task_policy = ttaskRankData[checkCounter].task_policy;
315 t_eva_taskRank.task_cpu = ttaskRankData[checkCounter].task_cpu;
316 t_eva_taskRank.taskOccupancy = ttaskRankData[checkCounter].taskOccupancy;
317 t_eva_taskRank.utime = ttaskRankData[checkCounter].utime;
318 t_eva_taskRank.stime = ttaskRankData[checkCounter].stime;
319 strcpy(t_eva_taskRank.tcomm, ttaskRankData[checkCounter].tcomm);
321 ttaskRankData[checkCounter].pid_nr_ns = ttaskRankData[checkCounter - 1].pid_nr_ns;
322 ttaskRankData[checkCounter].state = ttaskRankData[checkCounter - 1].state;
323 ttaskRankData[checkCounter].priority = ttaskRankData[checkCounter - 1].priority;
324 ttaskRankData[checkCounter].task_policy = ttaskRankData[checkCounter - 1].task_policy;
325 ttaskRankData[checkCounter].task_cpu = ttaskRankData[checkCounter - 1].task_cpu;
326 ttaskRankData[checkCounter].taskOccupancy = ttaskRankData[checkCounter - 1].taskOccupancy;
327 ttaskRankData[checkCounter].utime = ttaskRankData[checkCounter - 1].utime;
328 ttaskRankData[checkCounter].stime = ttaskRankData[checkCounter - 1].stime;
329 strcpy(ttaskRankData[checkCounter].tcomm, ttaskRankData[checkCounter - 1].tcomm);
331 ttaskRankData[checkCounter - 1].pid_nr_ns = t_eva_taskRank.pid_nr_ns;
332 ttaskRankData[checkCounter - 1].state = t_eva_taskRank.state;
333 ttaskRankData[checkCounter - 1].priority = t_eva_taskRank.priority;
334 ttaskRankData[checkCounter - 1].task_policy = t_eva_taskRank.task_policy;
335 ttaskRankData[checkCounter - 1].task_cpu = t_eva_taskRank.task_cpu;
336 ttaskRankData[checkCounter - 1].taskOccupancy = t_eva_taskRank.taskOccupancy;
337 ttaskRankData[checkCounter - 1].utime = t_eva_taskRank.utime;
338 ttaskRankData[checkCounter - 1].stime = t_eva_taskRank.stime;
339 strcpy(ttaskRankData[checkCounter - 1].tcomm, t_eva_taskRank.tcomm);
344 if ((dtime >= TASK_STAT_THRESHOLD) && // %%CPU over only
345 (getpid() != p->pid_nr_ns) && // except current process
346 (strcmp (p->tcomm, "(NS_BackupMgr)"))) { // except "BackupMgr"
347 if (p->task_policy == SCHED_FIFO) {
348 if ((g_fifo_task_occ < dtime) && (g_fifo_show_timer == 0)) { // first time only
349 g_fifo_task_pid = p->pid_nr_ns;
350 g_fifo_task_occ = dtime;
351 g_fifo_utime = tstat.utime;
352 g_fifo_stime = tstat.stime;
353 strcpy(g_fifo_path,p->path);
354 } else if (g_fifo_task_pid == p->pid_nr_ns) {
355 g_fifo_task_occ = dtime;
356 g_fifo_utime = tstat.utime;
357 g_fifo_stime = tstat.stime;
358 strcpy(g_fifo_path,p->path);
361 if ((g_tss_task_occ < dtime) && (g_tss_show_timer == 0)) { // first time only
362 g_tss_task_pid = p->pid_nr_ns;
363 g_tss_task_occ = dtime;
364 g_tss_utime = tstat.utime;
365 g_tss_stime = tstat.stime;
366 strcpy(g_tss_path,p->path);
367 } else if (g_tss_task_pid == p->pid_nr_ns) {
368 g_tss_task_occ = dtime;
369 g_tss_utime = tstat.utime;
370 g_tss_stime = tstat.stime;
371 strcpy(g_tss_path,p->path);
380 if (setRankDatanum != 0) {
381 FRAMEWORKUNIFIEDLOG (ZONE_WARN, __FUNCTION__, "[CpuHighLoad] PID ST PRI POLICY cpuX %%CPU (%%ut:%%st) comm");
382 for (checkCounter = 0;
383 checkCounter < (setRankDatanum < TASK_STAT_RANK_NUM ? setRankDatanum : TASK_STAT_RANK_NUM); checkCounter++) {
384 FRAMEWORKUNIFIEDLOG (ZONE_WARN, __FUNCTION__, "[CpuHighLoad]%5d %c %3d %5s cpu%d %4lu (%2lu.%03lu:%2lu.%03lu) %s",
385 ttaskRankData[checkCounter].pid_nr_ns,
386 ttaskRankData[checkCounter].state,
387 ttaskRankData[checkCounter].priority,
388 ttaskRankData[checkCounter].task_policy == SCHED_FIFO ? "FIFO"
389 : ttaskRankData[checkCounter].task_policy == SCHED_RR ? "RR" : "TSS",
390 ttaskRankData[checkCounter].task_cpu,
391 ttaskRankData[checkCounter].taskOccupancy,
392 ttaskRankData[checkCounter].utime * 100 / ((endTime - g_startTime)/10),
393 ttaskRankData[checkCounter].utime * 100 % ((endTime - g_startTime)/10),
394 ttaskRankData[checkCounter].stime * 100 / ((endTime - g_startTime)/10),
395 ttaskRankData[checkCounter].stime * 100 % ((endTime - g_startTime)/10),
396 ttaskRankData[checkCounter].tcomm);
398 FRAMEWORKUNIFIEDLOG (ZONE_WARN, __FUNCTION__, "[CpuHighLoad] -------------------------------------------------");
405 show_cpuload_onetask(int loadType) {
410 unsigned int endTime = 0;
412 unsigned long beforeUtime;
413 unsigned long beforeStime;
414 if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
415 endTime = ((tp.tv_sec * 1000) + (tp.tv_nsec / 1000000)); // Unit is msec
417 endTime = (WTC_CPU_INTERVAL * 1000) + g_startTime;
419 if (endTime - g_startTime <= 0) { // LCOV_EXCL_BR_LINE 200: (endTime - g_startTime) must be bigger than 0
420 // LCOV_EXCL_START 200: (endTime - g_startTime) must be bigger than 0
421 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
422 FRAMEWORKUNIFIEDLOG (ZONE_WARN, __FUNCTION__, "[CpuHighLoad] Timer abnormality.");
423 endTime = g_startTime + 1;
426 if (loadType == FIFO_TASK_SHOW) { // LCOV_EXCL_BR_LINE 200: loadType can't be FIFO_TASK_SHOW
427 // LCOV_EXCL_START 200: loadType can't be FIFO_TASK_SHOW
428 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
429 strcpy(loadPath,g_fifo_path);
430 beforeUtime = g_fifo_utime;
431 beforeStime = g_fifo_stime;
434 strcpy(loadPath,g_tss_path);
435 beforeUtime = g_tss_utime;
436 beforeStime = g_tss_stime;
438 if (strlen(loadPath) > 0) {
439 ret = get_task_stat(loadPath, &tstat);
441 dtime = (((tstat.utime + tstat.stime) - (beforeUtime + beforeStime)) * 1000) / (endTime - g_startTime);
442 if (tstat.task_policy == SCHED_FIFO) {
443 g_fifo_task_occ = dtime;
444 g_fifo_utime = tstat.utime;
445 g_fifo_stime = tstat.stime;
447 g_tss_task_occ = dtime;
448 g_tss_utime = tstat.utime;
449 g_tss_stime = tstat.stime;
457 //void logging_cpuload_custom(void) {
458 // struct timespec req = { 1, 0 }; // 1sec
460 // cleanup_task_stat();
461 // get_current_task_stat();
463 // nanosleep(&req, NULL);
468 logging_cpuload_custom(int32_t tmode) {
470 if (tmode == CPU_TASK_INIT) {
471 g_fifo_task_pid = -1;
479 memset(g_fifo_path, 0x00, sizeof(g_fifo_path));
480 memset(g_tss_path, 0x00, sizeof(g_tss_path));
482 get_current_task_stat();
483 } else if (tmode == CPU_TASK_SHOW_BF) {
485 get_current_task_stat();
486 } else if (tmode == CPU_TASK_SHOW_AF) {
488 } else if (tmode == FIFO_TASK_SHOW) { // LCOV_EXCL_BR_LINE 200: tmode can't be FIFO_TASK_SHOW
489 // LCOV_EXCL_START 200: tmode can't be FIFO_TASK_SHOW
490 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
491 show_cpuload_onetask(FIFO_TASK_SHOW);
493 } else if (tmode == TSS_TASK_SHOW) {
494 show_cpuload_onetask(TSS_TASK_SHOW);
495 } else if (tmode == CPU_FIFO_TASK_GET_ID) {
496 res = g_fifo_task_pid;
497 g_fifo_show_timer = 0;
498 } else if (tmode == CPU_TSS_TASK_GET_ID) {
499 res = g_tss_task_pid;
500 g_tss_show_timer = 0;
501 } else if (tmode == CPU_FIFO_TASK_GET_OCCUPANCY) {
502 g_fifo_show_timer = g_fifo_show_timer + WTC_CPU_INTERVAL;
503 res = g_fifo_task_occ;
505 } else if (tmode == CPU_TSS_TASK_GET_OCCUPANCY) { // LCOV_EXCL_BR_LINE 200: tmode can't be other value
506 g_tss_show_timer = g_tss_show_timer + WTC_CPU_INTERVAL;
507 res = g_tss_task_occ;