Skip to content
Snippets Groups Projects
Commit f6d7821b authored by FKHals's avatar FKHals
Browse files

Use syscall to set process to measure

instead of measuring programs implicitly by name (task_struct->comm)
parent a9114ea4
No related branches found
No related tags found
No related merge requests found
......@@ -381,4 +381,5 @@
546 x32 preadv2 compat_sys_preadv64v2
547 x32 pwritev2 compat_sys_pwritev64v2
4919 64 pb_set_plan sys_pb_set_plan
\ No newline at end of file
4919 64 pb_set_plan sys_pb_set_plan
3141 64 pbm_set_root_proc sys_pbm_set_root_proc
\ No newline at end of file
......@@ -209,6 +209,7 @@ extern struct trace_event_functions exit_syscall_print_funcs;
asmlinkage long sys_pb_set_plan(struct pb_plan __user *plan);
asmlinkage long sys_pbm_set_root_proc(void);
asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special,
qid_t id, void __user *addr);
asmlinkage long sys_time(time_t __user *tloc);
......
......@@ -68,6 +68,8 @@ __SYSCALL(__NR_fremovexattr, sys_fremovexattr)
#define __NR_pb_set_plan 0x1337
__SYSCALL(__NR_pb_set_plan, sys_pb_set_plan)
#define __NR_pbm_set_root_proc 3141
__SYSCALL(__NR_pbm_set_root_proc, sys_pbm_set_root_proc)
/* fs/dcache.c */
#define __NR_getcwd 17
......
......@@ -3,6 +3,7 @@
#include <linux/perf_event.h>
#include <linux/kthread.h>
#include <linux/slab.h>
#include <linux/syscalls.h>
#ifndef CONFIG_SMP
#include <linux/mutex.h>
......@@ -11,6 +12,28 @@
#include "behave.h"
int is_initialized = 0;
pid_t root_proc;
/**
* Set the calling process as the root task of the PBM and initialize it
*/
SYSCALL_DEFINE0(pbm_set_root_proc) {
unsigned long irq_flags;
long res;
// avoid context switching during initialization by disabling interrupts
local_irq_save(irq_flags);
if (!is_initialized) {
pbm_init();
is_initialized = 1;
}
local_irq_restore(irq_flags);
root_proc = current->pid;
res = pbm_fork(current, current->real_parent->pid, NULL);
return 0;
}
/******************************************************************************
* Based on "libpbm" (see header file for more info)
......@@ -410,7 +433,6 @@ int pbm_task_end(PBM* pbm) {
* run (current == child) otherwise the perf counting will fail!
*/
int pbm_fork(struct task_struct* proc, pid_t parent_pid, pbm_NODE* fork_node) {
unsigned long irq_flags;
PBM* parent_pbm;
PBM* child_pbm;
......@@ -420,13 +442,6 @@ int pbm_fork(struct task_struct* proc, pid_t parent_pid, pbm_NODE* fork_node) {
* pbm_fork_parent_new_task() to not be called but pbm_fork() since the child is "mpirun" so we
* put the initialization in here instead of into pbm_fork_parent_new_task().
*/
// avoid context switching during initialization by disabling interrupts
local_irq_save(irq_flags);
if (!is_initialized) {
pbm_init();
is_initialized = 1;
}
local_irq_restore(irq_flags);
child_pbm = get_pbm_by_pid(proc->pid);
parent_pbm = get_pbm_by_pid(parent_pid);
......@@ -685,17 +700,18 @@ void _pbm_unvisit_node(pbm_NODE* node) {
/******************************************************************************/
int is_root_process(struct task_struct* p) {
return strcmp(p->comm, "mpirun") == 0;
return p->pid == root_proc;
}
int is_relevant_process(struct task_struct* p) {
struct task_struct* proc = p;
// check if mpirun is a parent, super-parent, ... until the root-parent ("swapper") is found
while (proc && !(strcmp(proc->comm, "swapper") == 0)) {
// check if mpirun is a parent, super-parent, ... until the linux root/idle-process
// (comm = "swapper", pid = 0) is found
while (proc->pid != 0) {
if (is_root_process(proc)) {
return 1;
}
//printk(KERN_WARNING "Searching relevant process: %s\n", proc->comm);
//printk(KERN_WARNING "Searching relevant process: %s [%u]\n", proc->comm, proc->pid);
proc = proc->real_parent;
}
return 0;
......
......@@ -11,7 +11,8 @@ gcc -static -o test_prog test_prog.c
gcc -static -o task_long task_long_test.c
gcc -static -o sysc_long syscall_long_test.c
mpicc -o mpi_test_prog mpi_test_prog.c
gcc -static -o measure measure.c
cp pb_submitter test_prog task_long sysc_long example_run.sh example_plan mpi_test_prog /root
cp pb_submitter measure test_prog task_long sysc_long example_run.sh example_plan mpi_test_prog /root
echo "All done. Run '/root/example_run.sh' within ./run_qemu.sh now"
#include <stdio.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <libgen.h>
#include <string.h>
// address of the syscall in the kernel syscall table
#define BEHAVE_SET_ROOT_PROC 3141
static void usage(void)
{
fputs("Usage: ./measure <prog_name> <argument_1> ...", stderr);
}
int main(int argc, char** argv)
{
int ret;
if (argc < 2) {
usage();
return -1;
}
// start the perf measuring
ret = syscall(BEHAVE_SET_ROOT_PROC);
if (ret != 0) {
fputs("BEHAVE_SET_ROOT_PROC failed", stderr);
return -1;
}
/**
* BEWARE:
* We also measure the execve call etc. which does not really
* belong to the program but as long as we do it in the forecast model
* (here) as well as in the runtime model the resulting models should be
* rather similiar).
*/
// pass the root proc pid to be able to be read using e.g. a bash pipe
char buffer[16];
snprintf(buffer, sizeof(buffer), "%d", getpid());
write(1 /*STDOUT*/, buffer, strlen(buffer));
/**
* BEWARE:
* Since we use the STDOUT to pass arguments to the a following program we
* must make sure that the measured program itself does NOT write to STDOUT
* but only to STDERR!
*/
// drop the first element of argv (the name of this program) so that only
// the name and arguments of the program to run remain
char ** args = &argv[1];
// replace this process with the chosen program since we want to keep using
// the same PID for simplicity purposes (forking a new process would have
// worked as well but this process is not needed anymore anyways)
ret = execvp(argv[1], args);
if (ret < 0) {
perror("execve");
return -1;
}
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment