summaryrefslogtreecommitdiff
path: root/SOURCE
diff options
context:
space:
mode:
authorYang Wei <[email protected]>2021-10-27 22:39:58 +0800
committerYang Wei <[email protected]>2021-10-27 22:50:23 +0800
commite285bc4626a7d207eabd4a69cb276e1a3b1b7c76 (patch)
tree429dfcdefce77bc38ac8fb146a52dd63a1136007 /SOURCE
parent13f43482289bbb6f1b903674b03ca9ecc4db1f48 (diff)
load-monitor: 新增输出各CPU上正在运行进程的内核态和用户态堆栈功能
Diffstat (limited to 'SOURCE')
-rw-r--r--SOURCE/diagnose-tools/load.cc29
-rwxr-xr-xSOURCE/module/kernel/load.c40
-rw-r--r--SOURCE/uapi/ali_diagnose.h1
-rw-r--r--SOURCE/uapi/load_monitor.h11
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;