kernel_watch_timer add *task

This commit is contained in:
zy
2023-12-19 22:28:35 -05:00
parent 46a03f0357
commit f2c70efbd5
2 changed files with 49 additions and 16 deletions

View File

@@ -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;

View File

@@ -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);