From fa0eb8b3e777560caf814980428125fb892d913e Mon Sep 17 00:00:00 2001 From: zy Date: Fri, 15 Dec 2023 05:50:05 -0500 Subject: [PATCH] ipi finily work , delay 15us.. need code clean --- source/module/monitor_kernel_lib.c | 121 ++++++++++++++++++++++------- source/module/monitor_perf.c | 2 +- testcase/userstack.c | 121 +++++++++++++++++------------ 3 files changed, 163 insertions(+), 81 deletions(-) diff --git a/source/module/monitor_kernel_lib.c b/source/module/monitor_kernel_lib.c index a865c89..5a5bdc3 100644 --- a/source/module/monitor_kernel_lib.c +++ b/source/module/monitor_kernel_lib.c @@ -172,28 +172,36 @@ static void push_tskinfo_2_sa_buffer(variable_monitor_task *tsk_info, * @param tsk_info * @param flags */ -static void push_tskinfo_22_buffer(variable_monitor_task *tsk_info, - unsigned long *flags) { +static void push_tskinfo_22_buffer_orig(variable_monitor_task *tsk_info, + unsigned long *flags, + struct diag_variant_buffer *buffer) { variable_monitor_task_system *tsk_info_system; if (tsk_info->task.sys_task == 1) // system task { tsk_info_system = (variable_monitor_task_system *)tsk_info; tsk_info_system->et_type = VARIABLE_MONITOR_TASK_TYPE_SYSTEM; - diag_variant_buffer_reserve(&load_monitor_variant_buffer, - sizeof(variable_monitor_task_system)); - diag_variant_buffer_write_nolock(&load_monitor_variant_buffer, - tsk_info_system, + diag_variant_buffer_reserve(buffer, sizeof(variable_monitor_task_system)); + diag_variant_buffer_write_nolock(buffer, tsk_info_system, sizeof(variable_monitor_task_system)); - diag_variant_buffer_seal(&load_monitor_variant_buffer); + diag_variant_buffer_seal(buffer); } else { - diag_variant_buffer_reserve(&load_monitor_variant_buffer, - sizeof(variable_monitor_task)); - diag_variant_buffer_write_nolock(&load_monitor_variant_buffer, tsk_info, + diag_variant_buffer_reserve(buffer, sizeof(variable_monitor_task)); + diag_variant_buffer_write_nolock(buffer, tsk_info, sizeof(variable_monitor_task)); - diag_variant_buffer_seal(&load_monitor_variant_buffer); + diag_variant_buffer_seal(buffer); } } +static void push_tskinfo_22_buffer(variable_monitor_task *tsk_info, + unsigned long *flags) { + push_tskinfo_22_buffer_orig(tsk_info, flags, &load_monitor_variant_buffer); +} + +// static void push_tskinfo_22_sa_buffer(variable_monitor_task *tsk_info, +// unsigned long *flags) { +// push_tskinfo_22_buffer_orig(tsk_info, flags, &stand_alone_buffer); +// } + /// @brief clear all watch and reset kernel_wtimer_list/kernel_wtimer_num /// @param static void clear_all_watch(void) { @@ -211,9 +219,9 @@ static void clear_all_watch(void) { /** * @brief all threshold reached info - * - * @param k_watch_timer - * @param is_print + * + * @param k_watch_timer + * @param is_print */ static void diag_vm_record(kernel_watch_timer *k_watch_timer, unsigned char is_print) { @@ -251,7 +259,8 @@ static void diag_vm_record(kernel_watch_timer *k_watch_timer, if (is_print) { printk(KERN_INFO "-----------variable monitor----------\n"); - printk(KERN_INFO "threshold exceeded, Timestamp %lld, Stack finish Delay %lld:\n", + printk(KERN_INFO + "threshold exceeded, Timestamp %lld, Stack finish Delay %lld:\n", vm_record.tv, start_time - vm_record.tv); for (i = 0; i < vm_record.threshold_over_count; i++) { @@ -270,13 +279,12 @@ static void diag_vm_record(kernel_watch_timer *k_watch_timer, } } - /** * @brief diag task by tgid - * - * @param tgid + * + * @param tgid */ -void diag_task_by_tgid(pid_t tgid) { +void diag_task_by_tgid_orig(pid_t tgid, struct diag_variant_buffer *buffer) { struct task_struct *tsk; int ret; @@ -295,7 +303,7 @@ void diag_task_by_tgid(pid_t tgid) { return; } - diag_variant_buffer_spin_lock(&load_monitor_variant_buffer, flags); + diag_variant_buffer_spin_lock(buffer, flags); struct task_struct *thread = tsk; unsigned long event_id = get_cycles(); @@ -307,15 +315,23 @@ void diag_task_by_tgid(pid_t tgid) { tsk_info.tv = ktime_get_real(); diag_tsk(tsk, &tsk_info); - push_tskinfo_22_buffer(&tsk_info, &flags); // push to buffer + push_tskinfo_22_buffer_orig(&tsk_info, &flags, buffer); // push to buffer } - diag_variant_buffer_spin_unlock(&load_monitor_variant_buffer, flags); + diag_variant_buffer_spin_unlock(buffer, flags); rcu_read_unlock(); } +void diag_task_by_tgid(pid_t tgid){ + diag_task_by_tgid_orig(tgid, &load_monitor_variant_buffer); +} + +void diag_task_sa_by_tgid(pid_t tgid){ + diag_task_by_tgid_orig(tgid, &stand_alone_buffer); +} + /** * @brief diag all task info - * + * */ void diag_task_all(void) { static variable_monitor_task tsk_info; @@ -351,8 +367,8 @@ void diag_task_all(void) { /** * @brief diag task entry - * - * @param k_watch_timer + * + * @param k_watch_timer */ void diag_task(kernel_watch_timer *k_watch_timer) { if (k_watch_timer->threshold_over_count <= 0) // if no threshold reached @@ -365,7 +381,7 @@ void diag_task(kernel_watch_timer *k_watch_timer) { kernel_watch_arg *kwarg; for (i = 0; i < k_watch_timer->threshold_over_count; i++) { kwarg = &k_watch_timer->k_watch_args[k_watch_timer->threshold_buffer[i]]; - diag_task_by_tgid(kwarg->task_id); + diag_task_by_tgid_orig(kwarg->task_id, &load_monitor_variant_buffer); } } pr_info("diag_stack, finish tv %lld\n", ktime_get_real()); @@ -493,6 +509,35 @@ void clear_watch(pid_t pid) { start_all_hrTimer(); // restart timer } +#include +#include + +static void ipi_test(void *info) { + // pr_info("CPU%d do task\n", smp_processor_id()); + struct task_struct *tsk = current; + // pr_info("CPU%d pid: %d, name: %s\n", smp_processor_id(), tsk->pid, tsk->comm); + + struct diag_variant_buffer *buffer = &stand_alone_buffer; + unsigned long flags; + + static variable_monitor_task tsk_info; + + rcu_read_lock(); + diag_variant_buffer_spin_lock(buffer, flags); + + unsigned long event_id = get_cycles(); + + tsk_info.et_type = VARIABLE_MONITOR_TASK_TYPE; + tsk_info.id = event_id; + tsk_info.tv = ktime_get_real(); + pr_info("diag_tsk tv %lld\n", tsk_info.tv); + diag_tsk(tsk, &tsk_info); + + push_tskinfo_22_buffer_orig(&tsk_info, &flags, buffer); // push to buffer + + diag_variant_buffer_spin_unlock(buffer, flags); + rcu_read_unlock(); +} /** * @brief main callback function @@ -525,8 +570,22 @@ enum hrtimer_restart check_variable_cb(struct hrtimer *timer) { k_watch_timer->tv = ktime_get_real(); pr_info("threshold reached, tv %lld\n", k_watch_timer->tv); // highpri_wq - queue_work(system_highpri_wq, &k_watch_timer->wk); - + // queue_work(system_highpri_wq, &k_watch_timer->wk); + + pid_t pid = (pid_t)2636; + struct task_struct *tsk; + tsk = NULL; + + rcu_read_lock(); + if (orig_find_task_by_vpid) + tsk = orig_find_task_by_vpid(pid); + rcu_read_unlock(); + if (tsk) { + int cpu = task_cpu(tsk); + // pr_info("diag_pid: %d, cpu %d\n", tsk->pid, cpu); + smp_call_function_single(cpu, ipi_test, NULL, 1); + } + // diag_task(k_watch_timer); // orig_raise_softirq(MY_SOFTIRQ); // for swirq test @@ -568,8 +627,10 @@ int diag_pid(int id) { return ret; } rcu_read_unlock(); + int cpu = task_cpu(tsk); + pr_info("diag_pid: %d, cpu %d\n", tsk->pid, cpu); - pr_info("diag_pid: %d\n", tsk->pid); + // smp_call_function_single(cpu, ipi_test, NULL, 1); // 让 CPU2 执行 print_str() // get_task_struct(tsk); // count +1 @@ -578,7 +639,7 @@ int diag_pid(int id) { // tsk_info.tv = vm_record.tv; // diag_tsk(tsk, &tsk_info); // printk(KERN_INFO "pid: %d, name: %s\n", tsk->pid, tsk->comm); - setup_perf_event_for_task(tsk); // setup perf event for task + // setup_perf_event_for_task(tsk); // setup perf event for task // put_task_struct(tsk); // count -1 diff --git a/source/module/monitor_perf.c b/source/module/monitor_perf.c index 63e4bb8..4c19b28 100644 --- a/source/module/monitor_perf.c +++ b/source/module/monitor_perf.c @@ -11,7 +11,7 @@ void vm_perf_overflow_callback(struct perf_event *event, pr_info("perf event callback\n"); - // perf_event_disable(event); + perf_event_disable(event); // 如果 perf_sample_data 有调用堆栈信息 // if (data->callchain) { diff --git a/testcase/userstack.c b/testcase/userstack.c index 5da72c7..578b2c0 100644 --- a/testcase/userstack.c +++ b/testcase/userstack.c @@ -1,12 +1,15 @@ #include // #include -#include #include +#include +#include +#include + // void customFunction1(int n); -void *customFunction1(void *n); -void customFunction2(int n); -void customFunction3(int n); +// void *customFunction1(void *n); +// void customFunction2(int n); +// void customFunction3(int n); // Call this function to get a backtrace. // void backtrace() { @@ -35,61 +38,79 @@ void customFunction3(int n); // } // } -void *customFunction1(void *n) { - int num = *((int *)n); - if(num <= 0) { - printf("End of recursion\n"); - printf("pid: %d\n", getpid()); - while (1) { - sleep(1); - } // never return, keep stack - // return NULL; - } else { - printf("Calling customFunction2\n"); - customFunction2(num-1); - } - return NULL; +pid_t gettid() { + return syscall(SYS_gettid); +} + +static void additionalFunction(int n) { + printf("Additional function called with n = %d\n", n); +} + +static void customFunction3(int n) { + printf("Calling customFunction3\n"); + additionalFunction(n); + if (n <= 0) { + printf("End of recursion\n"); + printf("pid: %d\n", getpid()); + while (1) { + sleep(1); + } // never return, keep stack + // return NULL; + } + customFunction2(n - 1); } void customFunction2(int n) { - printf("Calling customFunction2\n"); - if(n <= 0) { - printf("End of recursion\n"); - printf("pid: %d\n", getpid()); - while (1) { - sleep(1); - } // never return, keep stack - // return NULL; - } - customFunction3(n-1); + printf("Calling customFunction2\n"); + additionalFunction(n); + if (n <= 0) { + printf("End of recursion\n"); + printf("pid: %d\n", getpid()); + while (1) { + sleep(1); + } // never return, keep stack + // return NULL; + } + customFunction3(n - 1); } -void customFunction3(int n) { - printf("Calling customFunction3\n"); - if(n <= 0) { - printf("End of recursion\n"); - printf("pid: %d\n", getpid()); - while (1) { - sleep(1); - } // never return, keep stack - // return NULL; - } - customFunction2(n-1); +void *customFunction1(void *n) { + int num = *((int *)n); + if (num <= 0) { + printf("End of recursion\n"); + printf("pid: %d\n", getpid()); + while (1) { + sleep(1); + } // never return, keep stack + // return NULL; + } else { + printf("Calling customFunction2\n"); + customFunction2(num - 1); + } + return NULL; +} + +void *customFunction122(void *n) { + printf("tid: %d\n", gettid()); + while (1) + { + /* code */ + } } int main() { - int num1 = 4; - int num2 = 5; - int num3 = 6; + int num1 = 10; + int num2 = 11; + int num3 = 12; - pthread_t thread_id1, thread_id2, thread_id3; + pthread_t thread_id1, thread_id2, thread_id3; - pthread_create(&thread_id1, NULL, customFunction1, &num1); - pthread_create(&thread_id2, NULL, customFunction1, &num2); - pthread_create(&thread_id3, NULL, customFunction1, &num3); + pthread_create(&thread_id2, NULL, customFunction1, &num2); + pthread_create(&thread_id3, NULL, customFunction1, &num3); + pthread_create(&thread_id1, NULL, customFunction122, &num1); - pthread_join(thread_id1, NULL); - pthread_join(thread_id2, NULL); - pthread_join(thread_id3, NULL); - return 0; + pthread_join(thread_id1, NULL); + pthread_join(thread_id2, NULL); + pthread_join(thread_id3, NULL); + return 0; } \ No newline at end of file