diff options
| author | Yang Wei <[email protected]> | 2021-10-27 22:39:58 +0800 |
|---|---|---|
| committer | Yang Wei <[email protected]> | 2021-10-27 22:50:23 +0800 |
| commit | e285bc4626a7d207eabd4a69cb276e1a3b1b7c76 (patch) | |
| tree | 429dfcdefce77bc38ac8fb146a52dd63a1136007 /SOURCE | |
| parent | 13f43482289bbb6f1b903674b03ca9ecc4db1f48 (diff) | |
load-monitor: 新增输出各CPU上正在运行进程的内核态和用户态堆栈功能
Diffstat (limited to 'SOURCE')
| -rw-r--r-- | SOURCE/diagnose-tools/load.cc | 29 | ||||
| -rwxr-xr-x | SOURCE/module/kernel/load.c | 40 | ||||
| -rw-r--r-- | SOURCE/uapi/ali_diagnose.h | 1 | ||||
| -rw-r--r-- | SOURCE/uapi/load_monitor.h | 11 |
4 files changed, 80 insertions, 1 deletions
diff --git a/SOURCE/diagnose-tools/load.cc b/SOURCE/diagnose-tools/load.cc index 0def903..5a34790 100644 --- a/SOURCE/diagnose-tools/load.cc +++ b/SOURCE/diagnose-tools/load.cc @@ -74,6 +74,7 @@ static void do_activate(const char *arg) settings.verbose = parse.int_value("verbose"); settings.style = parse.int_value("style"); settings.mass = parse.int_value("mass"); + settings.cpu_run = parse.int_value("cpu.run"); if (run_in_host) { ret = diag_call_ioctl(DIAG_IOCTL_LOAD_MONITOR_SET, (long)&settings); @@ -180,6 +181,7 @@ static int load_monitor_extract(void *buf, unsigned int len, void *) int *et_type; struct load_monitor_detail *detail; struct load_monitor_task *tsk_info; + struct load_monitor_cpu_run *cpu_run; static int seq = 0; if (len == 0) @@ -229,6 +231,30 @@ static int load_monitor_extract(void *buf, unsigned int len, void *) tsk_info++; break; + case et_load_monitor_cpu_run: + if (len < sizeof(struct load_monitor_cpu_run)) + break; + cpu_run = (struct load_monitor_cpu_run *)buf; + printf("输出各CPU当前运行任务: CPU:%lu task:%s(%u)\n", + cpu_run->cpu, cpu_run->task.comm, cpu_run->task.pid); + + printf("##CGROUP:[%s] %u [%03d] 采样命中[%s]\n", + cpu_run->task.cgroup_buf, + cpu_run->task.pid, + seq, + cpu_run->task.state == 0 ? "R" : "D"); + + diag_printf_kern_stack(&cpu_run->kern_stack); + diag_printf_user_stack(cpu_run->task.tgid, + cpu_run->task.container_tgid, + cpu_run->task.comm, + &cpu_run->user_stack); + printf("#* 0xffffffffffffff %s (UNKNOWN)\n", + cpu_run->task.comm); + printf("#* 0xffffffffffffff cpu:%lu (UNKNOWN)\n", cpu_run->cpu); + printf("##\n"); + + break; default: break; } @@ -436,6 +462,9 @@ static void do_dump(const char *arg) out_json = parse.int_value("json", 0); out_flame = parse.int_value("flame", 1); + g_symbol_parser.java_only = parse.int_value("java-only", 0); + g_symbol_parser.user_symbol = parse.int_value("user-symbol", 1); + if (run_in_host) { ret = diag_call_ioctl(DIAG_IOCTL_LOAD_MONITOR_DUMP, (long)&dump_param); } else { diff --git a/SOURCE/module/kernel/load.c b/SOURCE/module/kernel/load.c index 9b4af2f..09f4f42 100755 --- a/SOURCE/module/kernel/load.c +++ b/SOURCE/module/kernel/load.c @@ -40,7 +40,7 @@ static atomic64_t diag_nr_running = ATOMIC64_INIT(0); -struct diag_load_monitor_settings load_monitor_settings; +static struct diag_load_monitor_settings load_monitor_settings; static unsigned int load_monitor_alloced; @@ -49,6 +49,7 @@ static struct mm_tree mm_tree; unsigned long *orig_avenrun_r; unsigned long *orig_avenrun; +static struct load_monitor_cpu_run ld_mon_cpu_run[NR_CPUS]; static struct diag_variant_buffer load_monitor_variant_buffer; static ktime_t last_dump; @@ -77,6 +78,38 @@ void diag_load_timer(struct diag_percpu_context *context) return; } #else + +static void load_monitor_ipi(void *ignore) +{ + struct load_monitor_cpu_run *cpu_run; + struct task_struct *tsk; + unsigned long flags; + int cpu; + + tsk = current; + cpu = smp_processor_id(); + if (cpu >= NR_CPUS) + return; + + cpu_run = &ld_mon_cpu_run[cpu]; + + cpu_run->id = get_cycles(); + cpu_run->et_type = et_load_monitor_cpu_run; + cpu_run->cpu = cpu; + do_gettimeofday(&cpu_run->tv); + + diag_task_brief(tsk, &cpu_run->task); + diag_task_kern_stack(tsk, &cpu_run->kern_stack); + diag_task_user_stack(tsk, &cpu_run->user_stack); + + diag_variant_buffer_spin_lock(&load_monitor_variant_buffer, flags); + diag_variant_buffer_reserve(&load_monitor_variant_buffer, sizeof(struct load_monitor_cpu_run)); + diag_variant_buffer_write_nolock(&load_monitor_variant_buffer, + cpu_run, sizeof(struct load_monitor_cpu_run)); + diag_variant_buffer_seal(&load_monitor_variant_buffer); + diag_variant_buffer_spin_unlock(&load_monitor_variant_buffer, flags); +} + void diag_load_timer(struct diag_percpu_context *context) { u64 ms; @@ -190,6 +223,11 @@ void diag_load_timer(struct diag_percpu_context *context) } } while_each_thread(g, p); rcu_read_unlock(); + + if (!load_monitor_settings.mass && load_monitor_settings.cpu_run) { + smp_call_function(load_monitor_ipi, NULL, 1); + load_monitor_ipi(NULL); + } } } #endif diff --git a/SOURCE/uapi/ali_diagnose.h b/SOURCE/uapi/ali_diagnose.h index 9d79bff..1ba7763 100644 --- a/SOURCE/uapi/ali_diagnose.h +++ b/SOURCE/uapi/ali_diagnose.h @@ -395,6 +395,7 @@ enum diag_record_id { et_load_monitor_base = et_kprobe_base + DIAG_EVENT_TYPE_INTERVAL, et_load_monitor_detail, et_load_monitor_task, + et_load_monitor_cpu_run, et_mm_leak_base = et_load_monitor_base + DIAG_EVENT_TYPE_INTERVAL, et_mm_leak_detail, diff --git a/SOURCE/uapi/load_monitor.h b/SOURCE/uapi/load_monitor.h index bff499a..f4f91e9 100644 --- a/SOURCE/uapi/load_monitor.h +++ b/SOURCE/uapi/load_monitor.h @@ -27,6 +27,7 @@ struct diag_load_monitor_settings { unsigned int verbose; unsigned int style; unsigned int mass; + unsigned int cpu_run; unsigned int threshold_load; unsigned int threshold_load_r; unsigned int threshold_load_d; @@ -42,6 +43,16 @@ struct load_monitor_task { struct diag_proc_chains_detail proc_chains; }; +struct load_monitor_cpu_run { + int et_type; + unsigned long id; + unsigned long cpu; + struct timeval tv; + struct diag_task_detail task; + struct diag_kern_stack_detail kern_stack; + struct diag_user_stack_detail user_stack; +}; + struct load_monitor_detail { int et_type; unsigned long id; |
