summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClark Williams <williams@redhat.com>2011-09-01 09:41:37 -0500
committerClark Williams <williams@redhat.com>2011-09-01 09:41:37 -0500
commitee95ac26879e79b88ecf56d4b35c3bb0e23a74d9 (patch)
tree872f8e70fa44cabebb784e21c849248775af67e3
parent3e55619c86c2604638c06c31c87881084f643274 (diff)
downloadrt-tests-ee95ac26879e79b88ecf56d4b35c3bb0e23a74d9.tar.gz
commit WIP for rostedt
Signed-off-by: Clark Williams <williams@redhat.com>
-rw-r--r--src/cyclictest/cyclictest.c75
-rw-r--r--src/include/rt-utils.h9
-rw-r--r--src/lib/rt-utils.c161
3 files changed, 200 insertions, 45 deletions
diff --git a/src/cyclictest/cyclictest.c b/src/cyclictest/cyclictest.c
index 6be5521..0f3e981 100644
--- a/src/cyclictest/cyclictest.c
+++ b/src/cyclictest/cyclictest.c
@@ -114,6 +114,7 @@ enum {
IRQPREEMPTOFF,
WAKEUP,
WAKEUPRT,
+ LATENCY,
CUSTOM,
};
@@ -154,7 +155,7 @@ struct thread_stat {
static int shutdown;
static int tracelimit = 0;
-static int ftrace = 1;
+static int ftrace = 0;
static int kernelversion;
static int verbose = 0;
static int oscope_reduction = 1;
@@ -172,6 +173,7 @@ static pthread_mutex_t refresh_on_max_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t break_thread_id_lock = PTHREAD_MUTEX_INITIALIZER;
static pid_t break_thread_id = 0;
+static uint64_t break_thread_value = 0;
/* Backup of kernel variables that we modify */
static struct kvars {
@@ -369,44 +371,11 @@ void tracing(int on)
static int settracer(char *tracer)
{
- char filename[MAX_PATH];
- char tracers[MAX_PATH];
- char *name;
- FILE *fp;
- int ret = -1;
- int len;
- const char *delim = " \t\n";
- char *prefix = get_debugfileprefix();
-
- /* Make sure tracer is available */
- strncpy(filename, prefix, sizeof(filename));
- strncat(filename, "available_tracers",
- sizeof(filename) - strlen(prefix));
-
- fp = fopen(filename, "r");
- if (!fp)
- return -1;
-
- if (!(len = fread(tracers, 1, sizeof(tracers), fp))) {
- fclose(fp);
- return -1;
- }
- tracers[len] = '\0';
- fclose(fp);
-
- name = strtok(tracers, delim);
- while (name) {
- if (strcmp(name, tracer) == 0) {
- ret = 0;
- break;
- }
- name = strtok(NULL, delim);
- }
-
- if (!ret)
+ if (valid_tracer(tracer)) {
setkernvar("current_tracer", tracer);
-
- return ret;
+ return 0;
+ }
+ return -1;
}
static void setup_tracer(void)
@@ -414,6 +383,9 @@ static void setup_tracer(void)
if (!tracelimit)
return;
+ if (mount_debugfs(NULL))
+ fatal("could not mount debugfs");
+
if (kernelversion >= KV_26_33) {
char testname[MAX_PATH];
@@ -447,10 +419,8 @@ static void setup_tracer(void)
switch (tracetype) {
case NOTRACE:
- if (ftrace)
- ret = settracer(functiontracer);
- else
- ret = 0;
+ setkernvar("events/enable", "1");
+ ret = settracer("nop");
break;
case IRQSOFF:
ret = settracer("irqsoff");
@@ -463,11 +433,20 @@ static void setup_tracer(void)
break;
case EVENTS:
/* per rostedt: use nop tracer with event tracing */
- setkernvar("events/enable", "1");
ret = settracer("nop");
+ /* turn on all events */
+ event_enable_all();
break;
case CTXTSWITCH:
- ret = settracer("sched_switch");
+ if (valid_tracer("sched_switch"))
+ ret = settracer("sched_switch");
+ else {
+ if ((ret = settracer("nop")))
+ break;
+ if ((ret = event_enable("sched/sched_wakeup")))
+ break;
+ ret = event_enable("sched/sched_switch");
+ }
break;
case WAKEUP:
ret = settracer("wakeup");
@@ -745,6 +724,7 @@ void *timerthread(void *param)
pthread_mutex_lock(&break_thread_id_lock);
if (break_thread_id == 0)
break_thread_id = stat->tid;
+ break_thread_value = diff;
pthread_mutex_unlock(&break_thread_id_lock);
}
stat->act = diff;
@@ -1533,8 +1513,10 @@ int main(int argc, char **argv)
if (tracelimit) {
print_tids(parameters, num_threads);
- if (break_thread_id)
+ if (break_thread_id) {
printf("# Break thread: %d\n", break_thread_id);
+ printf("# Break value: %lu\n", break_thread_value);
+ }
}
@@ -1561,6 +1543,9 @@ int main(int argc, char **argv)
if (trace_fd >= 0)
close(trace_fd);
+ /* turn off all events */
+ event_disable_all();
+
/* unlock everything */
if (lockall)
munlockall();
diff --git a/src/include/rt-utils.h b/src/include/rt-utils.h
index 68857f3..730344e 100644
--- a/src/include/rt-utils.h
+++ b/src/include/rt-utils.h
@@ -8,6 +8,15 @@
int check_privs(void);
char *get_debugfileprefix(void);
+int mount_debugfs(char *);
+int get_tracers(char ***);
+int valid_tracer(char *);
+
+int setevent(char *event, char *val);
+int event_enable(char *event);
+int event_disable(char *event);
+int event_enable_all(void);
+int event_disable_all(void);
void warn(char *fmt, ...);
void fatal(char *fmt, ...);
diff --git a/src/lib/rt-utils.c b/src/lib/rt-utils.c
index da27a3a..952ad7f 100644
--- a/src/lib/rt-utils.c
+++ b/src/lib/rt-utils.c
@@ -11,6 +11,8 @@
#include <string.h>
#include <sched.h>
#include <stdarg.h>
+#include <errno.h>
+#include <fcntl.h>
#include "rt-utils.h"
static char debugfileprefix[MAX_PATH];
@@ -50,6 +52,165 @@ char *get_debugfileprefix(void)
return debugfileprefix;
}
+int mount_debugfs(char *path)
+{
+ char *mountpoint = path;
+ char cmd[MAX_PATH];
+ int ret;
+
+ if (get_debugfileprefix())
+ return 0;
+
+ if (!mountpoint)
+ mountpoint = "/sys/kernel/debug";
+
+ sprintf(cmd, "mount -t debugfs debugfs %s", mountpoint);
+ ret = system(cmd);
+ if (ret != 0) {
+ fprintf(stderr, "Error mounting debugfs at %s: %s\n", mountpoint, strerror(errno));
+ return -1;
+ }
+ return 0;
+
+}
+
+static char **tracer_list;
+static char *tracer_buffer;
+static int num_tracers;
+#define CHUNKSZ 1024
+
+/*
+ * return a list of the tracers configured into the running kernel
+ */
+
+int get_tracers(char ***list)
+{
+ int ret;
+ FILE *fp;
+ char buffer[CHUNKSZ];
+ char *prefix = get_debugfileprefix();
+ char *tmpbuf = NULL;
+ char *ptr;
+ int tmpsz = 0;
+
+ /* if we've already parse it, return what we have */
+ if (tracer_list) {
+ *list = tracer_list;
+ return num_tracers;
+ }
+
+ /* open the tracing file available_tracers */
+ sprintf(buffer, "%savailable_tracers", prefix);
+ if ((fp = fopen(buffer, "r")) == NULL)
+ fatal ("Can't open %s for reading\n", buffer);
+
+ /* allocate initial buffer */
+ ptr = tmpbuf = malloc(CHUNKSZ);
+ if (ptr == NULL)
+ fatal("error allocating initial space for tracer list\n");
+
+ /* read in the list of available tracers */
+ while((ret = fread(buffer, sizeof(char), CHUNKSZ, fp))) {
+ if ((ptr+ret+1) > (tmpbuf+tmpsz)) {
+ tmpbuf = realloc(tmpbuf, tmpsz + CHUNKSZ);
+ if (tmpbuf == NULL)
+ fatal("error allocating space for list of valid tracers\n");
+ tmpsz += CHUNKSZ;
+ }
+ strncpy(ptr, buffer, ret);
+ ptr += ret;
+ }
+ fclose(fp);
+ if (tmpsz == 0)
+ fatal("error reading available tracers\n");
+
+ tracer_buffer = tmpbuf;
+
+ /* get a buffer for the pointers to tracers */
+ if (!(tracer_list = malloc(sizeof(char *))))
+ fatal ("error allocatinging tracer list buffer\n");
+
+ /* parse the buffer */
+ ptr = strtok(tmpbuf, " \t\n\r");
+ do {
+ tracer_list[num_tracers++] = ptr;
+ tracer_list = realloc(tracer_list, sizeof(char*)*(num_tracers+1));
+ tracer_list[num_tracers] = NULL;
+ } while ((ptr = strtok(NULL, " \t\n\r")) != NULL);
+
+ /* return the list and number of tracers */
+ *list = tracer_list;
+ return num_tracers;
+}
+
+
+/*
+ * return zero if tracername is not a valid tracer, non-zero if it is
+ */
+
+int valid_tracer(char *tracername)
+{
+ char **list;
+ int ntracers;
+ int i;
+
+ ntracers = get_tracers(&list);
+ if (ntracers == 0 || tracername == NULL)
+ return 0;
+ for (i = 0; i < ntracers; i++)
+ if (strncmp(list[i], tracername, strlen(list[i])) == 0)
+ return 1;
+ return 0;
+}
+
+/*
+ * enable event tracepoint
+ */
+int setevent(char *event, char *val)
+{
+ char *prefix = get_debugfileprefix();
+ char buffer[MAX_PATH];
+ int fd;
+ int ret;
+
+ sprintf(buffer, "%s%s", prefix, event);
+ if ((fd = open(buffer, O_WRONLY)) < 0) {
+ warn("unable to open %s\n", buffer);
+ return -1;
+ }
+ if ((ret = write(fd, val, strlen(val))) < 0) {
+ warn("unable to write %s to %s\n", val, buffer);
+ close(fd);
+ return -1;
+ }
+ close(fd);
+ return 0;
+}
+
+int event_enable_all(void)
+{
+ return setevent("events/enable", "1");
+}
+
+int event_disable_all(void)
+{
+ return setevent("events/enable", "0");
+}
+
+int event_enable(char *event)
+{
+ char path[MAX_PATH];
+ sprintf(path, "events/%s/enable", event);
+ return setevent(path, "1");
+}
+
+int event_disable(char *event)
+{
+ char path[MAX_PATH];
+ sprintf(path, "events/%s/enable", event);
+ return setevent(path, "0");
+}
+
int check_privs(void)
{
int policy = sched_getscheduler(0);