diff options
| author | zy <[email protected]> | 2023-11-09 21:48:24 -0500 |
|---|---|---|
| committer | zy <[email protected]> | 2023-11-09 21:48:24 -0500 |
| commit | 3ffa6340f4ca518e4d425e8b1ae3033a0bc4e90a (patch) | |
| tree | 0c36bc2cf4c12bee07fd9ffffb9dcba2af9ffa01 | |
| parent | acf7a2f402312dc30bba199c24e40fde390ffd42 (diff) | |
fix clear_watch bug, now all cleaning;
fix read_and_compare bug, now it work fine
| -rw-r--r-- | helloworld.c | 55 | ||||
| -rw-r--r-- | watch.c | 10 | ||||
| -rw-r--r-- | watch_module.c | 20 | ||||
| -rw-r--r-- | watch_module.h | 2 | ||||
| -rw-r--r-- | watch_module_lib.c | 56 |
5 files changed, 99 insertions, 44 deletions
diff --git a/helloworld.c b/helloworld.c index 3996a0f..9e4b71c 100644 --- a/helloworld.c +++ b/helloworld.c @@ -1,29 +1,48 @@ #include "watch.h" #include <stdio.h> #include <unistd.h> +#include <string.h> -int temp = 100; +#define NUM_VARS 100 int main() { - int temp = 100; - - watch_arg watch_arg = { - .task_id = getpid(), - .ptr = &temp, - .name = "temp", - .length_byte = sizeof(int), - .threshold = 105, - .unsigned_flag = 1, - .greater_flag = 1, - .time_ns = 2000, // on hyper-v, 1us will block all system. 2us just fine, maybe 1us is too short for hyper-v - }; - - start_watch(watch_arg); - while (temp < 107) + int i = 0; + int temps[NUM_VARS] = {0}; + watch_arg watch_args[NUM_VARS] = {0}; + + cancel_all_watch(); + + for (i = 0; i < NUM_VARS; i++) + { + temps[i] = 100; + + watch_args[i] = (watch_arg){ + .task_id = getpid(), + .ptr = &temps[i], + .name = "temp", + .length_byte = sizeof(int), + .threshold = 150 + i, + .unsigned_flag = 0, + .greater_flag = 1, + .time_ns = 2000 + (i / 33) * 5000, // on hyper-v, 1us will block all system. 2us just fine, maybe 1us is too short for hyper-v + }; + char name[20]; + snprintf(name, sizeof(name), "temp%d", i); + // 拷贝字符串 + strncpy(watch_args[i].name, name, (MAX_NAME_LEN + 1)); + + start_watch(watch_args[i]); + } + + while (temps[NUM_VARS - 1] < 205) { - printf("Value: %d\n", (temp)); - (temp)++; + for (i = 0; i < NUM_VARS; i++) + { + temps[i]++; + } + printf("Value of variable %d: %d", i, temps[0]); + printf("\n"); sleep(1); } @@ -12,7 +12,10 @@ int file_desc = -1; /// @return 0 means success, other means fail int start_watch(watch_arg w_arg) { - file_desc = open(DEVICE, 0); + if (file_desc < 0) + { + file_desc = open(DEVICE, 0); + } if (file_desc < 0) { printf("Can't open device file: %s\n", DEVICE); @@ -34,10 +37,15 @@ int cancel_all_watch() { if (file_desc < 0) { + file_desc = open(DEVICE, 0); + } + if (file_desc < 0) + { printf("Device not open: %s,%d \n", DEVICE, file_desc); return file_desc; } close(file_desc); + file_desc = -1; return 0; } diff --git a/watch_module.c b/watch_module.c index a6b900e..3b81378 100644 --- a/watch_module.c +++ b/watch_module.c @@ -21,18 +21,15 @@ static int device_open(struct inode *inode, struct file *file) static int device_release(struct inode *inode, struct file *file) { - printk(KERN_INFO "%s\n", __FUNCTION__); - // unmap and release the page - free_page_list(); - // cancel timer - cancel_all_hrTimer(); + // printk(KERN_INFO "%s\n", __FUNCTION__); + clear_watch(); return 0; } static long device_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioctl_param) { watch_arg warg; - void *ptr; + void *kptr; kernel_watch_timer *timer = NULL; kernel_watch_arg k_watch_arg; // copy watch_arg @@ -41,11 +38,11 @@ static long device_ioctl(struct file *file, unsigned int ioctl_num, unsigned lon return -EACCES; } - printk(KERN_INFO "Received: task_id=%d, name=%s, ptr=%p, length_byte=%d, time_ns=%ld, threshold=%lld\n", + printk(KERN_INFO "Watch_arg: task_id=%d, name=%s, ptr=%p, length_byte=%d, time_ns=%ld, threshold=%lld\n", warg.task_id, warg.name, warg.ptr, warg.length_byte, warg.time_ns, warg.threshold); // user space address to kernel space address - ptr = access_user_space_ptr(warg.task_id, (unsigned long)warg.ptr); - if (ptr == NULL) + kptr = access_user_space_ptr(warg.task_id, (unsigned long)warg.ptr); + if (kptr == NULL) { printk(KERN_ERR "Cannot access user space\n"); return -EACCES; @@ -57,9 +54,10 @@ static long device_ioctl(struct file *file, unsigned int ioctl_num, unsigned lon return -EINVAL; } // k_watch_arg init - w_arg2k_w_arg(ptr, warg, &k_watch_arg); + w_arg2k_w_arg(kptr, warg, &k_watch_arg); timer = get_timer(warg.time_ns); // get a valuable timer + printk(KERN_INFO "ptr transform kptr: %p\n", kptr); printk(KERN_INFO "timer: %p\n", timer); printk(KERN_INFO "timer->sentinel: %d, timer->time_ns: %lld\n", timer->sentinel, timer->time_ns); printk(KERN_INFO "timer->hr_timer: %p\n", &timer->hr_timer); @@ -68,7 +66,7 @@ static long device_ioctl(struct file *file, unsigned int ioctl_num, unsigned lon timer_add_watch(timer, k_watch_arg); TIMER_START(timer); - printk(KERN_INFO "Start watching\n"); + printk(KERN_INFO "Start watching var: %s\n", warg.name); return 0; } diff --git a/watch_module.h b/watch_module.h index 41a49ff..9074a72 100644 --- a/watch_module.h +++ b/watch_module.h @@ -158,3 +158,5 @@ static void print_all_task_stack(void) while_each_thread(g, p); rcu_read_unlock(); // unlock run queue } + +void clear_watch(void);
\ No newline at end of file diff --git a/watch_module_lib.c b/watch_module_lib.c index 43eb08b..34624cb 100644 --- a/watch_module_lib.c +++ b/watch_module_lib.c @@ -25,7 +25,8 @@ kernel_watch_timer *get_timer(unsigned long long time_ns) { timer = &kernel_wtimer_list[i]; - if (TIMER_EMPTY(timer)){ + if (TIMER_EMPTY(timer)) + { break; } if ((timer->time_ns == time_ns) && (!TIMER_FILLED(timer))) @@ -43,7 +44,7 @@ kernel_watch_timer *get_timer(unsigned long long time_ns) if (i > kernel_wtimer_num - 1) { printk(KERN_INFO "New timer\n"); - + kernel_wtimer_list[i].time_ns = time_ns; kernel_wtimer_list[i].sentinel = 0; @@ -54,7 +55,7 @@ kernel_watch_timer *get_timer(unsigned long long time_ns) kernel_wtimer_num = i + 1; } - + printk(KERN_INFO "now, we have %d timers\n", kernel_wtimer_num); return &kernel_wtimer_list[i]; } @@ -137,8 +138,8 @@ void *access_user_space_ptr(pid_t pid, unsigned long addr) // Map the page to kernel space node->kaddr = kmap(node->page); list_add_tail(&node->entry, &watch_local_memory_list); // add to list - printk(KERN_INFO "node->kaddr: %p, aligned_addr: %ld, offset: %ld\n", node->kaddr, aligned_addr, offset); - return (node->kaddr) + offset; + // printk(KERN_INFO "node->kaddr: %p, aligned_addr: %ld, offset: %ld\n", node->kaddr, aligned_addr, offset); + return (void *)((unsigned long)(node->kaddr) + offset); } /// @brief free all page in watch_local_memory_list @@ -175,6 +176,10 @@ enum hrtimer_restart hrtimer_hander(struct hrtimer *timer) snprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), "%s ,", k_watch_timer->k_watch_args[i].name); j++; + + printk(KERN_INFO "j: name %s, threshold: %lld\n", k_watch_timer->k_watch_args[i].name, + k_watch_timer->k_watch_args[i].threshold); + printk(KERN_INFO "j: %d\n", j); } } if (j > 0) // if any threshold reached @@ -232,40 +237,50 @@ typedef unsigned char (*compare_func)(void *, long long); unsigned char compare_1_byte_signed(void *ptr, long long threshold) { + // printk("compare_1_byte_signed: value %d, biss: %lld\n", *(char *)ptr, threshold); return *(char *)ptr > threshold; } unsigned char compare_1_byte_unsigned(void *ptr, long long threshold) { + // printk("compare_1_byte_unsigned: value %d, biss: %lld\n", *(unsigned char *)ptr, threshold); return *(unsigned char *)ptr > threshold; } unsigned char compare_2_byte_signed(void *ptr, long long threshold) { + // printk("compare_2_byte_signed: value %d, biss: %lld\n", *(short int *)ptr, threshold); return *(short int *)ptr > threshold; } unsigned char compare_2_byte_unsigned(void *ptr, long long threshold) { + // printk("compare_2_byte_unsigned: value %d, biss: %lld\n", *(unsigned short int *)ptr, threshold); return *(unsigned short int *)ptr > threshold; } unsigned char compare_4_byte_signed(void *ptr, long long threshold) { + // printk("compare_4_byte_signed: value %d, biss: %lld\n", *(int *)ptr, threshold); return *(int *)ptr > threshold; } unsigned char compare_4_byte_unsigned(void *ptr, long long threshold) { + // printk("compare_4_byte_unsigned: value %d, biss: %lld\n", *(unsigned int *)ptr, threshold); return *(unsigned int *)ptr > threshold; } unsigned char compare_8_byte_signed(void *ptr, long long threshold) { + // printk("compare_8_byte_signed: value %lld, biss: %lld\n", *(long long *)ptr, threshold); return *(long long *)ptr > threshold; } unsigned char compare_8_byte_unsigned(void *ptr, long long threshold) { + // printk("compare_8_byte_unsigned: value %lld, biss: %lld\n", *(unsigned long long *)ptr, threshold); return *(unsigned long long *)ptr > threshold; } // list of compare functions -static compare_func compare_funcs[2][4] = { - {compare_1_byte_signed, compare_2_byte_signed, compare_4_byte_signed, compare_8_byte_signed}, - {compare_1_byte_unsigned, compare_2_byte_unsigned, compare_4_byte_unsigned, compare_8_byte_unsigned}}; +static compare_func compare_funcs[8] = {compare_1_byte_signed, compare_2_byte_signed, compare_4_byte_signed, + compare_8_byte_signed, compare_1_byte_unsigned, compare_2_byte_unsigned, + compare_4_byte_unsigned, compare_8_byte_unsigned}; + +static int func_indices[2][9] = {{0, 0, 1, 0, 2, 0, 0, 0, 3}, {0, 4, 5, 0, 6, 0, 0, 0, 7}}; /// @brief read k_arg->kptr and compare with threshold /// @param k_arg @@ -279,13 +294,16 @@ unsigned char read_and_compare(kernel_watch_arg *k_arg) unsigned char result = 0; - if (len != 1 && len != 2 && len != 4 && len != 8) - { - printk(KERN_ERR "Invalid length\n"); - return 0; - } + // if (len != 1 && len != 2 && len != 4 && len != 8) + // { + // printk(KERN_ERR "Invalid length\n"); + // return 0; + // } - result = compare_funcs[is_unsigned][len - 1](ptr, threshold); + result = compare_funcs[func_indices[is_unsigned][len]](ptr, threshold); + + // printk(KERN_INFO "read_and_compare: name %s, value %d, biss: %lld, result: %d \n", k_arg->name, *(int *)ptr, + // threshold, result); if (k_arg->greater_flag) return result; @@ -309,4 +327,14 @@ int kallsyms_init_symbol(void) return -EINVAL; } return 0; +} + +void clear_watch(void){ + // unmap and release the page + free_page_list(); + // cancel timer + cancel_all_hrTimer(); + // clear timer + kernel_wtimer_num = 0; + memset(kernel_wtimer_list, 0, sizeof(kernel_wtimer_list)); }
\ No newline at end of file |
