diff options
| author | zy <[email protected]> | 2023-12-19 22:28:35 -0500 |
|---|---|---|
| committer | zy <[email protected]> | 2023-12-19 22:28:35 -0500 |
| commit | f2c70efbd56c62e75f449648e216fb6187265443 (patch) | |
| tree | 9ff624118164c6869e1784a019b8338bb43647b9 /source | |
| parent | 46a03f035758dd6d379338c6b0f24c3fda475afe (diff) | |
kernel_watch_timer add *task
Diffstat (limited to 'source')
| -rw-r--r-- | source/module/monitor_timer.c | 59 | ||||
| -rw-r--r-- | source/module/monitor_timer.h | 6 |
2 files changed, 49 insertions, 16 deletions
diff --git a/source/module/monitor_timer.c b/source/module/monitor_timer.c index 4652bc4..28d8f7b 100644 --- a/source/module/monitor_timer.c +++ b/source/module/monitor_timer.c @@ -1,18 +1,26 @@ #include "monitor_timer.h" +#include <linux/sched.h> +#include <linux/pid.h> // Global variable kernel_watch_timer kernel_wtimer_list[MAX_TIMER_NUM] = { - 0}; // all kernel_watch_timer + 0}; // all kernel_watch_timer volatile int kernel_wtimer_num = 0; // current kernel_watch_timer number EXPORT_SYMBOL(kernel_wtimer_list); // export kernel_watch_timer_list EXPORT_SYMBOL(kernel_wtimer_num); // export kernel_watch_timer_num - #define TIMER_FILLED(timer) ((timer)->sentinel >= TIMER_MAX_WATCH_NUM) -#define TIMER_EMPTY(timer) (!((timer)->time_ns | (timer)->sentinel)) +#define TIMER_EMPTY(timer) \ + (!((timer)->time_ns | (timer)->sentinel | ((timer)->task != NULL))) #define TIMER_NO_KWARG(timer) ((timer)->sentinel == 0) +/** + * @brief search all kwarg, if pid match, delete all + * + * @param pid + * @return unsigned char + */ unsigned char del_all_kwarg_by_pid(pid_t pid) { int i = 0; kernel_watch_timer *timer = NULL; @@ -42,7 +50,6 @@ unsigned char del_all_kwarg_by_pid(pid_t pid) { } kernel_wtimer_num--; i--; - } } return 0; @@ -51,9 +58,23 @@ unsigned char del_all_kwarg_by_pid(pid_t pid) { /// @brief get a valuable timer /// @param time_ns /// @return kernel_watch_timer *, NULL means fail -kernel_watch_timer *get_timer(unsigned long long time_ns) { - int i = 0; +kernel_watch_timer *get_timer(pid_t tid, unsigned long long time_ns) { kernel_watch_timer *timer = NULL; + struct task_struct *task = NULL; + // if tid is 0 or current pid, task is current + if ((tid == 0) || (tid == current->pid)) { + task = current; + } else { + rcu_read_lock(); + task = pid_task(find_vpid(tid), PIDTYPE_PID); // find task by pid + rcu_read_unlock(); + } + + if (task == NULL) { + pr_info("get_timer tid is abnormal\n"); + return NULL; + } + int i = 0; // chose a timer for (i = 0; i < kernel_wtimer_num; i++) { timer = &kernel_wtimer_list[i]; @@ -61,7 +82,9 @@ kernel_watch_timer *get_timer(unsigned long long time_ns) { if (TIMER_EMPTY(timer)) { break; } - if ((timer->time_ns == time_ns) && (!TIMER_FILLED(timer))) { + // if task match, time_ns match, and timer is not filled + if ((task->pid == timer->task->pid) && (timer->time_ns == time_ns) && + (!TIMER_FILLED(timer))) { break; } } @@ -72,7 +95,8 @@ kernel_watch_timer *get_timer(unsigned long long time_ns) { // if a new timer, init it if (i > kernel_wtimer_num - 1) { printk(KERN_INFO "New timer\n"); - + // init timer + kernel_wtimer_list[i].task = task; kernel_wtimer_list[i].time_ns = time_ns; kernel_wtimer_list[i].sentinel = 0; @@ -106,6 +130,13 @@ unsigned char timer_add_watch(kernel_watch_timer *timer, return 0; } +/** + * @brief for each timer's k_watch_args, if pid match, delete it + * + * @param timer + * @param pid + * @return unsigned char + */ unsigned char timer_del_watch_by_pid(kernel_watch_timer *timer, pid_t pid) { int i = 0; for (i = 0; i < timer->sentinel; i++) { @@ -149,10 +180,11 @@ void start_all_hrTimer(void) { timer = &(kernel_wtimer_list[i]); TIMER_START(timer); } - printk(KERN_INFO "HrTimer start,module keep %d hrtimer for now\n", kernel_wtimer_num); + printk(KERN_INFO "HrTimer start,module keep %d hrtimer for now\n", + kernel_wtimer_num); } -/// @brief cancel hrTimer and stop all work +/// @brief cancel hrTimer /// @param void cancel_all_hrTimer(void) { int i = 0; @@ -161,12 +193,13 @@ void cancel_all_hrTimer(void) { timer = &(kernel_wtimer_list[i]); TIMER_CANCEL(timer); } - printk(KERN_INFO "HrTimer cancel,module keep %d hrtimer for now\n", kernel_wtimer_num); + printk(KERN_INFO "HrTimer cancel,module keep %d hrtimer for now\n", + kernel_wtimer_num); } /** * @brief cancel all work - * + * */ void cancel_all_work(void) { int i = 0; @@ -179,7 +212,7 @@ void cancel_all_work(void) { /** * @brief destory all work - * + * */ void cancel_destory_all_work(void) { int i = 0; diff --git a/source/module/monitor_timer.h b/source/module/monitor_timer.h index c8b5df5..5b522d7 100644 --- a/source/module/monitor_timer.h +++ b/source/module/monitor_timer.h @@ -32,6 +32,8 @@ typedef struct { unsigned long long time_ns; // hrTimer time interval (ns) struct hrtimer hr_timer; // hrTimer ktime_t kt; // hrTimer time + struct task_struct *task; // task pointer + // one timer one task(process) unsigned sentinel; // sentinel kernel_watch_arg k_watch_args[TIMER_MAX_WATCH_NUM]; // all watched kernel_watch_arg @@ -40,8 +42,6 @@ typedef struct { int threshold_buffer[TIMER_MAX_WATCH_NUM]; // struct work_struct wk; // for handle unsigned long long tv; // time - struct task_struct *task; // task pointer - // one timer one task(process) } kernel_watch_timer; // Global variable @@ -59,7 +59,7 @@ unsigned char del_all_kwarg_by_pid(pid_t pid); #define TIMER_CANCEL(timer) (hrtimer_cancel(&timer->hr_timer)) // for timer -kernel_watch_timer *get_timer(unsigned long long time_ns); +kernel_watch_timer *get_timer(pid_t tid, unsigned long long time_ns); unsigned char timer_add_watch(kernel_watch_timer *timer, kernel_watch_arg k_watch_arg); unsigned char timer_del_watch_by_pid(kernel_watch_timer *timer, pid_t pid); |
