From 1235a665a5e00dc762e6646c01381b3ed5019d86 Mon Sep 17 00:00:00 2001 From: Glenn Elliott Date: Wed, 9 Jan 2013 17:00:54 -0500 Subject: Enable sched_trace log injection from userspace --- include/litmus/rt_param.h | 22 ++++++++++++++ include/litmus/unistd_32.h | 6 ++-- include/litmus/unistd_64.h | 5 +++- litmus/litmus.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 3 deletions(-) diff --git a/include/litmus/rt_param.h b/include/litmus/rt_param.h index c8ee64569dbb..43daaf84101d 100644 --- a/include/litmus/rt_param.h +++ b/include/litmus/rt_param.h @@ -47,6 +47,28 @@ typedef enum { AUX_FUTURE = (AUX_CURRENT<<2) } aux_flags_t; +/* mirror of st_event_record_type_t + * Assume all are UNsupported, unless otherwise stated. */ +typedef enum { + ST_INJECT_NAME = 1, /* supported */ + ST_INJECT_PARAM, /* supported */ + ST_INJECT_RELEASE, /* supported */ + ST_INJECT_ASSIGNED, + ST_INJECT_SWITCH_TO, + ST_INJECT_SWITCH_AWAY, + ST_INJECT_COMPLETION, /* supported */ + ST_INJECT_BLOCK, + ST_INJECT_RESUME, + ST_INJECT_ACTION, + ST_INJECT_SYS_RELEASE, /* supported */ +} sched_trace_injection_events_t; + +struct st_inject_args { + lt_t release; + lt_t deadline; + unsigned int job_no; +}; + /* We use the common priority interpretation "lower index == higher priority", * which is commonly used in fixed-priority schedulability analysis papers. * So, a numerically lower priority value implies higher scheduling priority, diff --git a/include/litmus/unistd_32.h b/include/litmus/unistd_32.h index 7265ffadf555..d1fe84a5d574 100644 --- a/include/litmus/unistd_32.h +++ b/include/litmus/unistd_32.h @@ -20,6 +20,8 @@ #define __NR_litmus_dgl_lock __LSC(12) #define __NR_litmus_dgl_unlock __LSC(13) -#define __NR_set_aux_tasks _LSC(14) +#define __NR_set_aux_tasks __LSC(14) -#define NR_litmus_syscalls 15 +#define __NR_sched_trace_event __LSC(15) + +#define NR_litmus_syscalls 16 diff --git a/include/litmus/unistd_64.h b/include/litmus/unistd_64.h index 51e730124dde..75f9fcb897f5 100644 --- a/include/litmus/unistd_64.h +++ b/include/litmus/unistd_64.h @@ -37,4 +37,7 @@ __SYSCALL(__NR_litmus_dgl_unlock, sys_litmus_dgl_unlock) #define __NR_set_aux_tasks __LSC(14) __SYSCALL(__NR_set_aux_tasks, sys_set_aux_tasks) -#define NR_litmus_syscalls 15 +#define __NR_sched_trace_event __LSC(15) +__SYSCALL(__NR_sched_trace_event, sys_sched_trace_event) + +#define NR_litmus_syscalls 16 diff --git a/litmus/litmus.c b/litmus/litmus.c index 1b4b9d25dbdc..6a1095aa7725 100644 --- a/litmus/litmus.c +++ b/litmus/litmus.c @@ -310,6 +310,79 @@ asmlinkage long sys_null_call(cycles_t __user *ts) return ret; } + +asmlinkage long sys_sched_trace_event(int event, struct st_inject_args __user *__args) +{ + long retval = 0; + struct task_struct* t = current; + + struct st_inject_args args; + + if (is_realtime(t)) { + printk(KERN_WARNING "Only non-real-time tasks may inject sched_trace events.\n"); + retval = -EINVAL; + goto out; + } + + if (__args && copy_from_user(&args, __args, sizeof(args))) { + retval = -EFAULT; + goto out; + } + + switch(event) { + /*************************************/ + /* events that don't need parameters */ + /*************************************/ + case ST_INJECT_NAME: + sched_trace_task_name(t); + break; + case ST_INJECT_PARAM: + /* presumes sporadic_task_ns() has already been called + * and valid data has been initialized even if the calling + * task is SCHED_NORMAL. */ + sched_trace_task_param(t); + break; + + /*******************************/ + /* events that need parameters */ + /*******************************/ + case ST_INJECT_COMPLETION: + if (!__args) { + retval = -EINVAL; + goto out; + } + + /* slam in the data */ + t->rt_param.job_params.job_no = args.job_no; + + sched_trace_task_completion(t, 0); + break; + case ST_INJECT_RELEASE: + if (!__args) { + retval = -EINVAL; + goto out; + } + + /* slam in the data */ + tsk_rt(t)->job_params.release = args.release; + tsk_rt(t)->job_params.deadline = args.deadline; + + sched_trace_task_release(t); + break; + + /**********************/ + /* unsupported events */ + /**********************/ + default: + retval = -EINVAL; + break; + } + +out: + return retval; +} + + #if defined(CONFIG_LITMUS_NVIDIA) && defined(CONFIG_LITMUS_AFFINITY_LOCKING) void init_gpu_affinity_state(struct task_struct* p) { -- cgit v1.2.2