summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzy <[email protected]>2023-11-09 21:48:24 -0500
committerzy <[email protected]>2023-11-09 21:48:24 -0500
commit3ffa6340f4ca518e4d425e8b1ae3033a0bc4e90a (patch)
tree0c36bc2cf4c12bee07fd9ffffb9dcba2af9ffa01
parentacf7a2f402312dc30bba199c24e40fde390ffd42 (diff)
fix clear_watch bug, now all cleaning;
fix read_and_compare bug, now it work fine
-rw-r--r--helloworld.c55
-rw-r--r--watch.c10
-rw-r--r--watch_module.c20
-rw-r--r--watch_module.h2
-rw-r--r--watch_module_lib.c56
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);
}
diff --git a/watch.c b/watch.c
index dceb15f..f9c4436 100644
--- a/watch.c
+++ b/watch.c
@@ -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