Skip to content
Snippets Groups Projects
Commit 62799805 authored by Mihai Renea's avatar Mihai Renea
Browse files

Switched to kernel internal calls for perf.

parent ea023b94
Branches
No related tags found
No related merge requests found
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
#include <linux/kthread.h> #include <linux/kthread.h>
#include "perf_error_detection.h" #include "perf_error_detection.h"
/*
* Kelvin's Testcode
*/
void set_pb_measure_on(struct pb_rq *pb) void set_pb_measure_on(struct pb_rq *pb)
{ {
pb->measure_k = PB_MEASURE_K_ON; pb->measure_k = PB_MEASURE_K_ON;
...@@ -14,6 +17,9 @@ void set_pb_measure_on(struct pb_rq *pb) ...@@ -14,6 +17,9 @@ void set_pb_measure_on(struct pb_rq *pb)
EXPORT_SYMBOL(set_pb_measure_on); EXPORT_SYMBOL(set_pb_measure_on);
/*
* Kelvin's Testcode
*/
void set_pb_measure_off(struct pb_rq *pb_rq) void set_pb_measure_off(struct pb_rq *pb_rq)
{ {
u64 runtime; u64 runtime;
...@@ -60,10 +66,7 @@ void init_pb_rq(struct pb_rq *pb_rq) ...@@ -60,10 +66,7 @@ void init_pb_rq(struct pb_rq *pb_rq)
pb_rq->c_entry = 0; pb_rq->c_entry = 0;
pb_rq->proxy_task = NULL; pb_rq->proxy_task = NULL;
pb_rq->size = 0; pb_rq->size = 0;
pb_rq->pevent = NULL;
//init perf fd as invalid, since it is not initialized
pb_rq->fd = -1;
pb_rq->measure_k = PB_MEASURE_K_OFF; pb_rq->measure_k = PB_MEASURE_K_OFF;
pb_rq->kstart = 0; pb_rq->kstart = 0;
pb_rq->ktime = 0; pb_rq->ktime = 0;
...@@ -112,32 +115,43 @@ static struct task_struct * pick_next_task_pb(struct rq *rq, ...@@ -112,32 +115,43 @@ static struct task_struct * pick_next_task_pb(struct rq *rq,
next_mode = determine_next_mode_pb(rq); next_mode = determine_next_mode_pb(rq);
pb->mode = next_mode; pb->mode = next_mode;
int perf_init_res;
// The mode does not change --> no behavior change is needed // The mode does not change --> no behavior change is needed
if (next_mode == PB_EXEC_MODE) if (next_mode == PB_EXEC_MODE)
{ {
if (current_mode == PB_EXEC_MODE){ if (current_mode == PB_EXEC_MODE){
int perf_counter = terminate_perf_event(pb->fd,pb->plan[pb->c_entry].task_id); int perf_counter = terminate_perf_event(pb->pevent, pb->plan[pb->c_entry].task_id);
//error detection //error detection
if (perf_counter < pb->plan[pb->c_entry].n_instr){ if (perf_counter < pb->plan[pb->c_entry].n_instr){
printk(KERN_WARNING "task %llu ran too short\n",pb->plan[pb->c_entry].task_id); printk(KERN_WARNING "PB TASK %llu RAN TOO SHORT\n",pb->plan[pb->c_entry].task_id);
} }
pb->c_entry++; pb->c_entry++;
if (pb->c_entry >= pb->size){ if (pb->c_entry >= pb->size){
printk(KERN_DEBUG "PLAN DONE\n"); printk(KERN_DEBUG "PLAN DONE\n");
pb->mode = PB_DISABLED_MODE; pb->mode = PB_DISABLED_MODE;
}else{ }else{
init_perf_event(pb->plan[pb->c_entry]); perf_init_res = init_perf_event(pb->plan[pb->c_entry], &pb->pevent);
printk(KERN_DEBUG "EXEC,START,%u,%llu\n", pb->c_entry, sched_clock()); if(perf_init_res < 0){
//initialization error detection/handling could happen here
printk(KERN_WARNING "PB EXEC,START,%u,%llu: FAILED OPEN PERF EVENT\n", pb->c_entry, sched_clock());
} else {
printk(KERN_DEBUG "PB EXEC,START,%u,%llu\n", pb->c_entry, sched_clock());
}
} }
}else if(current_mode == PB_ADMIN_MODE){ }else if(current_mode == PB_ADMIN_MODE){
printk(KERN_DEBUG "ADMIN,STOP,%u,%llu\n", pb->c_entry, sched_clock()); printk(KERN_DEBUG "PB ADMIN,STOP,%u,%llu\n", pb->c_entry, sched_clock());
}else{ }else{
pb->fd = init_perf_event(pb->plan[pb->c_entry]); perf_init_res = init_perf_event(pb->plan[pb->c_entry], &pb->pevent);
if(pb->fd < 0){
if(perf_init_res < 0){
//initialization error detection/handling could happen here //initialization error detection/handling could happen here
} printk(KERN_WARNING "PB INIT,%u,%llu: FAILED OPEN PERF EVENT\n", pb->c_entry, sched_clock());
} else {
printk(KERN_DEBUG "PB INIT,%u,%llu\n", pb->c_entry, sched_clock()); printk(KERN_DEBUG "PB INIT,%u,%llu\n", pb->c_entry, sched_clock());
}
} }
//TODO: pick next task from taskarray //TODO: pick next task from taskarray
picked = pb->proxy_task; picked = pb->proxy_task;
......
...@@ -2,9 +2,8 @@ ...@@ -2,9 +2,8 @@
#include <linux/smp.h> #include <linux/smp.h>
//initialize perf event for new task //initialize perf event for new task
int init_perf_event(struct plan_entry plan_entry){ int init_perf_event(struct plan_entry plan_entry, struct perf_event **pevent){
struct perf_event_attr pe; struct perf_event_attr pe;
struct perf_event *event;
//set perf_event_attr for init perf event //set perf_event_attr for init perf event
memset(&pe, 0, sizeof(struct perf_event_attr)); memset(&pe, 0, sizeof(struct perf_event_attr));
...@@ -20,12 +19,11 @@ int init_perf_event(struct plan_entry plan_entry){ ...@@ -20,12 +19,11 @@ int init_perf_event(struct plan_entry plan_entry){
/* Not needed on 3.2? */ /* Not needed on 3.2? */
pe.wakeup_events = 1; pe.wakeup_events = 1;
//perf_event_open(perf_event_attr,pid,cpu,groupfd,flags=0)
// cpu = -1 -> cpu indepented (assumed to be regulated by plan) // cpu = -1 -> cpu indepented (assumed to be regulated by plan)
event = perf_event_open(&pe, smp_processor_id()); *pevent = perf_event_create(&pe, smp_processor_id());
if (IS_ERR(event)) { if (IS_ERR(event)) {
printk(KERN_WARNING "Error initializing perf event \n"); printk(KERN_WARNING "PB ERROR INITIALISING PERF EVENT\n");
return -1; return -1;
} }
...@@ -33,14 +31,10 @@ int init_perf_event(struct plan_entry plan_entry){ ...@@ -33,14 +31,10 @@ int init_perf_event(struct plan_entry plan_entry){
} }
//terminate perf event - return performance counter value //terminate perf event - return performance counter value
long long terminate_perf_event(int fd, u64 task_id){ long long terminate_perf_event(struct perf_event *pevent, u64 task_id){
// if (ioctl(fd, PERF_EVENT_IOC_DISABLE, 0) != 0){
// printk(KERN_WARNING "could not disable perf event for task %llu",task_id); return perf_event_release_kernel(pevent);
// }
long long count;
// read(fd, &count, sizeof(long long));
// close(fd);
return count;
} }
...@@ -53,21 +47,16 @@ void overflow_handler( ...@@ -53,21 +47,16 @@ void overflow_handler(
{ {
struct pb_rq *pb_rq; struct pb_rq *pb_rq;
int cpu; int cpu;
// int fd;
cpu = smp_processor_id(); cpu = smp_processor_id();
// pb_rq = cpu_rq(cpu)->pb; pb_rq = &cpu_rq(cpu)->pb;
pb_rq = &cpu_rq(cpu)->pb; /* der compiler meckert: error: incompatible types when assigning to type ‘struct pb_rq *’ from type ‘struct pb_rq’ */
// fd =pb_rq->fd;
printk(KERN_WARNING "task %llu ran too long\n",pb_rq->plan[pb_rq->c_entry].task_id); printk(KERN_WARNING "PB TASK %llu RAN TOO LONG\n",pb_rq->plan[pb_rq->c_entry].task_id);
// if (ioctl(fd, PERF_EVENT_IOC_DISABLE, 0) != 0){
// printk(KERN_WARNING "could not disable perf event for cpu %d",cpu);
// }
} }
struct perf_event* perf_event_open(struct perf_event_attr *hw_event_uptr, int cpu) struct perf_event* perf_event_create(struct perf_event_attr *hw_event_uptr, int cpu)
{ {
return perf_event_create_kernel_counter( return perf_event_create_kernel_counter(
hw_event_uptr, hw_event_uptr,
......
...@@ -10,13 +10,13 @@ ...@@ -10,13 +10,13 @@
//#include <include/linux/smp.h> //#include <include/linux/smp.h>
#endif #endif
int init_perf_event(struct plan_entry); int init_perf_event(struct plan_entry, struct perf_event **pevent);
long long terminate_perf_event(int fd, u64 task_id); long long terminate_perf_event(struct perf_event *pevent, u64 task_id);
void overflow_handler( void overflow_handler(
struct perf_event *, struct perf_event *,
struct perf_sample_data *, struct perf_sample_data *,
struct pt_regs *regs); struct pt_regs *regs);
struct perf_event *perf_event_open(struct perf_event_attr *hw_event_uptr, int); struct perf_event *perf_event_create(struct perf_event_attr *hw_event_uptr, int);
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/irq_work.h> #include <linux/irq_work.h>
#include <linux/tick.h> #include <linux/tick.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/perf_event.h>
#ifdef CONFIG_PARAVIRT #ifdef CONFIG_PARAVIRT
#include <asm/paravirt.h> #include <asm/paravirt.h>
...@@ -551,13 +552,15 @@ struct pb_rq { ...@@ -551,13 +552,15 @@ struct pb_rq {
// one of PB_DISABLED_MODE, PB_EXEC_MODE, PB_ADMIN_MODE // one of PB_DISABLED_MODE, PB_EXEC_MODE, PB_ADMIN_MODE
int mode; int mode;
//file descriptor for perf event
int fd;
int measure_k; int measure_k;
u64 kstart; u64 kstart;
u64 ktime; u64 ktime;
u64 start; u64 start;
/*
* Per Core, nicht per Task
*/
struct perf_event *pevent;
}; };
/* Real-Time classes' related field in a runqueue: */ /* Real-Time classes' related field in a runqueue: */
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include "event.h" #include "event.h"
int perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu, int perf_event_create(struct perf_event_attr *attr, pid_t pid, int cpu,
int group_fd, unsigned long flags) int group_fd, unsigned long flags)
{ {
return syscall(__NR_perf_event_open, attr, pid, cpu, return syscall(__NR_perf_event_open, attr, pid, cpu,
...@@ -51,7 +51,7 @@ void event_init(struct event *e, u64 config) ...@@ -51,7 +51,7 @@ void event_init(struct event *e, u64 config)
int event_open_with_options(struct event *e, pid_t pid, int cpu, int group_fd) int event_open_with_options(struct event *e, pid_t pid, int cpu, int group_fd)
{ {
e->fd = perf_event_open(&e->attr, pid, cpu, group_fd, 0); e->fd = perf_event_create(&e->attr, pid, cpu, group_fd, 0);
if (e->fd == -1) { if (e->fd == -1) {
perror("perf_event_open"); perror("perf_event_open");
return -1; return -1;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment