-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request lkl#34 from alexandrasandulescu/tracer-assignment
Add tracer assignment
- Loading branch information
Showing
15 changed files
with
1,475 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
objects = _test/tracer_test.o | ||
|
||
.PHONY: all clean | ||
|
||
all: tracer_test | ||
|
||
tracer_test: | ||
$(CC) -Wall -g -m32 -static -o $@ $(objects) | ||
|
||
|
||
run: all | ||
./run_tests.bash | ||
|
||
clean: | ||
-rm -f tracer_test *~ tracer_helper.ko |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
= KPROBE BASED TRACER TEST SUITE == | ||
|
||
Test suite for kprobe based tracer | ||
|
||
== FILES == | ||
|
||
README | ||
* this file | ||
|
||
Makefile.checker | ||
* Makefile for automating the build process | ||
|
||
_checker | ||
* script to run all tests defined in _test/tracer_test.c | ||
|
||
_test/Makefile | ||
* test suite internal Makefile (creates necessary object files) | ||
|
||
_test/tracer_test.c | ||
* test suite for Kprobe Based Tracer | ||
|
||
_test/tracer_test.h | ||
* test suite header file | ||
|
||
_test/tracer.h | ||
* kprobe tracer header file (macros and structures) | ||
|
||
_test/test.h | ||
* useful macros for testing | ||
|
||
_test/debug.h | ||
* debugging macros | ||
|
||
_test/util.h | ||
* useful macros for generic use (error processing) | ||
|
||
_helper/tracer_helper.c | ||
* helper kernel module for simulating kprobed ops | ||
|
||
== BUILDING == | ||
|
||
Use the Makefile to properly build the tracer_test executable and | ||
the tracer_helper.ko module: | ||
|
||
make -f Makefile.checker | ||
|
||
== RUNNING == | ||
|
||
Copy your tracer.ko module and _checker, tracer_test and tracer_helper.ko | ||
to fsimg/root directory on your QEMU/KVM virtual machine. | ||
|
||
In order to run the test suite you can either use the _checker | ||
script or run the tracer_test executable. | ||
|
||
The _checker script runs all tests and computes assignment grade: | ||
|
||
./_checker | ||
|
||
In order to run a specific test pass the test number (1 .. 10) to the | ||
tracer_test executable. | ||
|
||
./tracer_test 5 | ||
|
||
== TESTS == | ||
|
||
Tests are basically unit tests. A single function in the test_fun_array (see | ||
tracer_test.c) is called each time the tracer_test executable is invoked, | ||
testing a single functionality (and assuming previous tests have been run and | ||
passed). | ||
|
||
The EXIT_IF_FAIL macro (see test.h) is unnecessary since after each test, the | ||
program completes. | ||
|
||
Each test function follows the unit test pattern: initialization, action, | ||
evaluation. The test macro (see test.h) is invoked at the end of each test | ||
for evaluating and grading the test. | ||
|
||
== DEBUGGING == | ||
|
||
The debug.h header file consists of several macros useful for debugging | ||
(dprintf, dlog). There are multiple uses of these macros throughout the above | ||
files. | ||
|
||
In order to turn debug messages on, you must define the DEBUG macro, either in | ||
a header file, or, I suggest, in the Makefile. The LOG_LEVEL macro limits the | ||
log message types that are to be printed, by default LOG_WARNING (see enum in | ||
debug.h). You may redefine it in a header file or in the Makefile. | ||
|
||
Rapid enabling of debug messages is achieved by commenting out the CPPFLAGS | ||
line in the Makefile. It turns on debugging and enables all log messages | ||
(LOG_DEBUG). | ||
|
||
== OTHER == | ||
|
||
srand48() and drand48() are used for generating random numbers. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#!/bin/sh | ||
|
||
first_test=1 | ||
last_test=10 | ||
executable=tracer_test | ||
|
||
for i in $(seq $first_test $last_test); do | ||
./"$executable" $i | ||
done | tee results.txt | ||
|
||
cat results.txt | grep '\[.*\]$' | awk -F '[] /[]+' ' | ||
BEGIN { | ||
sum=0 | ||
} | ||
{ | ||
sum += $2; | ||
} | ||
END { | ||
printf "\n%66s [%03d/100]\n", "Total:", sum; | ||
}' | ||
|
||
rm -f results.txt |
4 changes: 4 additions & 0 deletions
4
tools/labs/templates/tracer_assignment/checker/_helper/Kbuild
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
EXTRA_CFLAGS = -Wall -g | ||
|
||
obj-m = tracer_helper.o | ||
|
35 changes: 35 additions & 0 deletions
35
tools/labs/templates/tracer_assignment/checker/_helper/helper.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#ifndef _HELPER__ | ||
#define _HELPER__ | ||
|
||
#include <asm/ioctl.h> | ||
|
||
#define NAMESIZE 64 | ||
#define MCOUNT 128 | ||
|
||
#define PREPARE_TEST _IOW('t', 19, unsigned int) | ||
#define START_TEST _IOW('t', 20, unsigned int) | ||
#define STOP_TEST _IOW('t', 21, unsigned int) | ||
|
||
/*XXX match test_params with tracers_stats | ||
* perhaps use the same struct | ||
*/ | ||
struct test_params { | ||
pid_t pid; | ||
char thread_name[NAMESIZE]; | ||
int idx; /* index for multi-kthreaded test */ | ||
/* | ||
* kcalls: 5 | ||
* alloc : [1024] [8] [128] [10] [128] | ||
* free : [0] [0] [1] [0] [1] | ||
*/ | ||
int kcalls; /* number of kmalloc calls */ | ||
int alloc[MCOUNT]; /* sizes of kmalloc allocations */ | ||
int free[MCOUNT]; /* intmap for which allocations to free */ | ||
int sched; | ||
int up; | ||
int down; | ||
int lock; | ||
int unlock; | ||
}; | ||
|
||
#endif |
201 changes: 201 additions & 0 deletions
201
tools/labs/templates/tracer_assignment/checker/_helper/tracer_helper.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
#include <linux/kernel.h> | ||
#include <linux/init.h> | ||
#include <linux/module.h> | ||
#include <linux/kprobes.h> | ||
#include <linux/semaphore.h> | ||
#include <linux/mutex.h> | ||
#include <linux/kthread.h> | ||
#include <linux/sched.h> | ||
#include <linux/delay.h> | ||
#include <linux/slab.h> | ||
#include <linux/miscdevice.h> | ||
#include <linux/fs.h> | ||
#include <asm/ioctl.h> | ||
#include <linux/uaccess.h> | ||
#include <linux/semaphore.h> | ||
#include <linux/mutex.h> | ||
|
||
#include "helper.h" | ||
|
||
|
||
#define HELPER_MINOR 30 | ||
|
||
/* number of paralel kernel threads */ | ||
static wait_queue_head_t wq[MCOUNT]; | ||
|
||
/*XXX: this looks like a poor design, please refactor */ | ||
static int thread_prepared[MCOUNT] = {0, }; | ||
static int thread_running[MCOUNT] = {0, }; | ||
static int thread_should_stop[MCOUNT] = {0, }; | ||
static struct task_struct *t[MCOUNT] = {NULL, }; | ||
|
||
static struct test_params tp[MCOUNT]; | ||
static int tcount; | ||
|
||
void do_work(void) | ||
{ | ||
int i, j; | ||
int a = 0; | ||
|
||
for (i = 0; i < 1000; i++) | ||
for (j = 0; j < 1000; j++) | ||
a = i * j; | ||
} | ||
|
||
int thread_fn(void *data) | ||
{ | ||
int i; | ||
|
||
void *k_addr[MCOUNT]; | ||
struct semaphore sem; | ||
struct mutex lock; | ||
|
||
struct test_params *tp; | ||
|
||
tp = (struct test_params *)data; | ||
|
||
thread_prepared[tp->idx] = 1; | ||
wake_up_interruptible(&wq[tp->idx]); | ||
|
||
wait_event_interruptible(wq[tp->idx], thread_running[tp->idx] == 1); | ||
|
||
for (i = 0; i < tp->kcalls; i++) | ||
k_addr[i] = kmalloc(tp->alloc[i], GFP_KERNEL); | ||
|
||
/*XXX: do proper cleanup, avoid memory leaks */ | ||
for (i = 0; i < tp->kcalls; i++) | ||
if (tp->free[i] && k_addr[i]) | ||
kfree(k_addr[i]); | ||
|
||
for (i = 0; i < tp->sched; i++) | ||
schedule(); | ||
|
||
/* TODO: use tp->down for down_interruptible */ | ||
sema_init(&sem, 1); | ||
for (i = 0; i < tp->up; i++) { | ||
up(&sem); | ||
do_work(); | ||
down_interruptible(&sem); | ||
} | ||
/* TODO: use to->unlock for mutex_unlock */ | ||
mutex_init(&lock); | ||
for (i = 0; i < tp->lock; i++) { | ||
mutex_lock(&lock); | ||
do_work(); | ||
mutex_unlock(&lock); | ||
} | ||
|
||
wait_event_interruptible(wq[tp->idx], thread_should_stop[tp->idx] == 1); | ||
|
||
/* reset state machine */ | ||
thread_prepared[tp->idx] = 0; | ||
thread_running[tp->idx] = 0; | ||
thread_should_stop[tp->idx] = 0; | ||
|
||
return 0; | ||
} | ||
static int helper_open(struct inode *inode, struct file *file) | ||
{ | ||
#ifdef DEBUG | ||
pr_info("tracer-helper: open\n"); | ||
#endif | ||
return 0; | ||
} | ||
|
||
static int helper_release(struct inode *inode, struct file *file) | ||
{ | ||
#ifdef DEBUG | ||
pr_info("tracer-helper: close\n"); | ||
#endif | ||
return 0; | ||
} | ||
|
||
static long helper_ioctl(struct file *filp, unsigned int cmd, | ||
unsigned long arg) | ||
{ | ||
int ret = 0; | ||
|
||
switch (cmd) { | ||
case PREPARE_TEST: | ||
if (copy_from_user(&tp[tcount], (struct test_param *)arg, | ||
sizeof(tp[tcount]))) { | ||
pr_info("Error copy to user\n"); | ||
return -EFAULT; | ||
} | ||
t[tp[tcount].idx] = kthread_run(thread_fn, &tp[tcount], "%s", | ||
tp[tcount].thread_name); | ||
if (!t[tp[tcount].idx]) { | ||
pr_info("Could not create thread!\n"); | ||
return -ENOMEM; | ||
} | ||
|
||
ret = t[tp[tcount].idx]->pid; | ||
wait_event_interruptible(wq[tp[tcount].idx], | ||
thread_prepared[tp[tcount].idx] == 1); | ||
tcount++; | ||
break; | ||
case START_TEST: | ||
#if 0 | ||
pr_info("%s: start test for idx %lu\n", __func__, arg); | ||
#endif | ||
thread_running[arg] = 1; | ||
wake_up_interruptible(&wq[arg]); | ||
break; | ||
case STOP_TEST: | ||
#if 0 | ||
pr_info("%s: stop test for idx %lu\n", __func__, arg); | ||
#endif | ||
thread_should_stop[arg] = 1; | ||
wake_up_interruptible(&wq[arg]); | ||
kthread_stop(t[arg]); | ||
break; | ||
default: | ||
break; | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
static const struct file_operations tracer_fops = { | ||
.open = helper_open, | ||
.unlocked_ioctl = helper_ioctl, | ||
.release = helper_release, | ||
}; | ||
|
||
static struct miscdevice helper_dev = { | ||
.minor = HELPER_MINOR, | ||
.name = "helper", | ||
.fops = &tracer_fops, | ||
}; | ||
|
||
static int __init tracer_helper_init(void) | ||
{ | ||
int rc, i; | ||
|
||
rc = misc_register(&helper_dev); | ||
if (rc < 0) { | ||
pr_err("misc_register: fail\n"); | ||
return rc; | ||
} | ||
|
||
for (i = 0; i < MCOUNT; i++) | ||
init_waitqueue_head(&wq[i]); | ||
#ifdef DEBUG | ||
pr_info("tracer-helper: init\n"); | ||
#endif | ||
return 0; | ||
} | ||
|
||
static void __exit tracer_helper_exit(void) | ||
{ | ||
misc_deregister(&helper_dev); | ||
#ifdef DEBUG | ||
pr_info("tracer-helper: exit\n"); | ||
#endif | ||
} | ||
|
||
MODULE_AUTHOR("Daniel Baluta"); | ||
MODULE_LICENSE("GPL"); | ||
|
||
module_init(tracer_helper_init); | ||
module_exit(tracer_helper_exit); |
11 changes: 11 additions & 0 deletions
11
tools/labs/templates/tracer_assignment/checker/_test/Makefile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#CPPFLAGS = -DDEBUG -DLOG_LEVEL=LOG_DEBUG | ||
CFLAGS = -Wall -g -static -m32 | ||
|
||
.PHONY: all clean | ||
|
||
all: tracer_test.o | ||
|
||
stp_test.o: tracer_test.c tracer_test.h tracer.h test.h util.h debug.h | ||
|
||
clean: | ||
-rm -f *~ *.o |
Oops, something went wrong.