Select Git revision
AbstractConfiguration.java
Forked from
DistributedSystems4Students / FUCoin
Source project has a limited visibility.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
perf_error_detection.c 2.13 KiB
#include "perf_error_detection.h"
#include <linux/smp.h>
#define PERF_SAMPLE_PERIOD_SIZE 100000
/*
* Our understanding of perf so far. Please correct as needed.
*
* An event in perf's terms is an instruction in our case.
* A sample is a fixed number of events that CAN trigger a wakeup_event (but not the only way).
* An overflow event is triggered by a fixed number of wakeup_event.
*
*/
//initialize perf event for new task
int init_perf_event(struct plan_entry plan_entry, struct perf_event **pevent){
struct perf_event_attr pe;
//set perf_event_attr for init perf event
memset(&pe, 0, sizeof(struct perf_event_attr));
pe.type = PERF_TYPE_HARDWARE;
pe.size = sizeof(struct perf_event_attr);
pe.config = PERF_COUNT_HW_INSTRUCTIONS;
pe.sample_period = plan_entry.n_instr;
pe.disabled = 0; // start the counter as soon as we're in userland
pe.pinned = 1; // ?
pe.exclude_kernel = 1;
pe.exclude_hv = 1;
pe.precise_ip = 2; // 2 SAMPLE_IP requested to have 0 skid.
/* Not needed on 3.2? */
pe.wakeup_events = 1;
// cpu = -1 -> cpu indepented (assumed to be regulated by plan)
*pevent = perf_event_create(&pe, smp_processor_id());
if (IS_ERR(pevent)) {
printk(KERN_WARNING "PB ERROR INITIALISING PERF EVENT\n");
return -1;
}
return 0;
}
/*
* Must not be called after the event is terminated.
*/
u64 get_perf_counter(struct perf_event *pevent, u64 *perf_counter)
{
return perf_event_read_local(pevent, perf_counter);
}
u64 terminate_perf_event(struct perf_event *pevent)
{
return perf_event_release_kernel(pevent);
}
//handle the perf overflow event -> task needed more instructions than planed
void overflow_handler(
struct perf_event *event,
struct perf_sample_data *data,
struct pt_regs *regs)
{
struct pb_rq *pb_rq;
int cpu;
cpu = smp_processor_id();
pb_rq = &cpu_rq(cpu)->pb;
printk(KERN_WARNING "PB TASK %llu RAN TOO LONG\n",pb_rq->plan[pb_rq->c_entry].task_id);
}
struct perf_event* perf_event_create(struct perf_event_attr *hw_event_uptr, int cpu)
{
return perf_event_create_kernel_counter(
hw_event_uptr,
cpu,
NULL, /* per CPU */
&overflow_handler,
NULL /* Was ist eigentlich context? */);
}