kernel_watch_timer add *task
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user