From b481f271ba0533618c7f161cf1ebcfdb24cb7641 Mon Sep 17 00:00:00 2001
From: derMihai <mihairenea@gmail.com>
Date: Sun, 17 Mar 2019 15:09:00 +0100
Subject: [PATCH] Call perf_event_kernel_counter() instead of
 perf_event_open(). Changed only to test includes, no functionality
 implemented.

---
 kernel/sched/perf_error_detection.c | 71 +++++++++++------------------
 kernel/sched/perf_error_detection.h | 13 ++++--
 2 files changed, 34 insertions(+), 50 deletions(-)

diff --git a/kernel/sched/perf_error_detection.c b/kernel/sched/perf_error_detection.c
index 0e1dd0fde030..ca8021c81ed8 100644
--- a/kernel/sched/perf_error_detection.c
+++ b/kernel/sched/perf_error_detection.c
@@ -1,20 +1,10 @@
 #include "perf_error_detection.h"
+#include <linux/smp.h>
 
 //initialize perf event for new task
 int init_perf_event(struct plan_entry plan_entry){
 	struct perf_event_attr pe;
-	struct sigaction sa;
-	int fd;
-
-	//setting the overflow handler
-	memset(&sa, 0, sizeof(struct sigaction));
-	sa.sa_sigaction = overflow_handler;
-	sa.sa_flags = SA_SIGINFO;
-
-	if (sigaction( SIGIO, &sa, NULL) < 0) {
-		printk(KERN_WARNING "Error setting up perf overflow handler\n");
-		return -1;
-	}
+	struct perf_event *event;
 
 	//set perf_event_attr for init perf event
 	memset(&pe,0,sizeof(struct perf_event_attr));
@@ -32,39 +22,35 @@ int init_perf_event(struct plan_entry plan_entry){
 
 	//perf_event_open(perf_event_attr,pid,cpu,groupfd,flags=0)
 	// cpu = -1 -> cpu indepented (assumed to be regulated by plan)
-	fd=perf_event_open(&pe,plan_entry.task_struct->pid,-1,-1,0);
-	if (fd<0) {
+	event = perf_event_open(&pe, smp_processor_id());
+
+	if (IS_ERR(event)) {
 			printk(KERN_WARNING "Error initializing perf event \n");
 			return -1;
 	}
 
-	ioctl(fd, PERF_EVENT_IOC_RESET, 0);
-
-
-	if (ioctl(fd, PERF_EVENT_IOC_ENABLE, 0)<0) {
-		printk(KERN_WARNING "Error enabling perf event \n");
-		return -1;
-	}
-
-
 	return fd;
 }
 
 //terminate perf event - return performance counter value
 long long terminate_perf_event(int fd, 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);
-	}
+//	if (ioctl(fd, PERF_EVENT_IOC_DISABLE, 0) != 0){
+//		printk(KERN_WARNING "could not disable perf event for task %llu",task_id);
+//	}
 	long long count;
-	read(fd, &count, sizeof(long long));
-	close(fd);
+//	read(fd, &count, sizeof(long long));
+//	close(fd);
 	return count;
 }
 
 
 
 //handle the perf overflow event -> task needed more instructions than planed
-void overflow_handler(int signum,siginfo_t *oh, void *blah) {
+void overflow_handler(
+		struct perf_event *,
+		struct perf_sample_data *,
+		struct pt_regs *regs)
+{
 	struct pb_rq *pb_rq;
 	int cpu;
 	int fd;
@@ -75,22 +61,17 @@ void overflow_handler(int signum,siginfo_t *oh, void *blah) {
 
 	printk(KERN_WARNING "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);
-	}
+//	if (ioctl(fd, PERF_EVENT_IOC_DISABLE, 0) != 0){
+//		printk(KERN_WARNING "could not disable perf event for cpu %d",cpu);
+//	}
 }
 
-int perf_event_open(struct perf_event_attr *hw_event_uptr, pid_t pid, int cpu, int group_fd, unsigned long flags) {
-	mm_segment_t fs;
-	int ret;
-
-	fs = get_fs();     /* save previous value */
-
-	set_fs (get_ds()); /* use kernel limit */
-
-	ret = syscall(__NR_perf_event_open,hw_event_uptr, pid, cpu, group_fd, flags);
-
-	set_fs(fs);
-
-	return ret;
+struct perf_event* perf_event_open(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? */);
 }
diff --git a/kernel/sched/perf_error_detection.h b/kernel/sched/perf_error_detection.h
index 970e8396d93f..7d93b245829a 100644
--- a/kernel/sched/perf_error_detection.h
+++ b/kernel/sched/perf_error_detection.h
@@ -3,9 +3,9 @@
 #include <linux/perf_event.h>
 //#include <linux/sched.h>
 #include "sched.h"
-#include "../../include/linux/signal.h"
-#include <linux/ioctl.h>
-#include "../../include/linux/fs.h"
+//#include "../../include/linux/signal.h"
+//#include <linux/ioctl.h>
+//#include "../../include/linux/fs.h"
 
 //#include <include/linux/smp.h>
 #endif
@@ -14,6 +14,9 @@ int init_perf_event(struct plan_entry);
 
 long long terminate_perf_event(int fd, u64 task_id);
 
-void overflow_handler(int,siginfo_t *oh, void *blah);
+void overflow_handler(
+		struct perf_event *,
+		struct perf_sample_data *,
+		struct pt_regs *regs);
 
-int perf_event_open(struct perf_event_attr *hw_event_uptr, pid_t, int, int, unsigned long);
+struct perf_event *perf_event_open(struct perf_event_attr *hw_event_uptr, int);
-- 
GitLab