#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
+#include "kbuffer.h"
+#include "event-parse.h"
#define PAGE_SIZE 0x400
/* Test for a little-endian machine */
#define ENDIAN KBUFFER_ENDIAN_BIG
#endif
-#include "kbuffer.h"
-#include "event-parse.h"
+#define DEBUGFS "/sys/kernel/debug/"
+
+#define ENABLE_RAS_MC_EVENT "ras:mc_event\n"
+#define DISABLE_RAS_MC_EVENT "!" ENABLE_RAS_MC_EVENT
/*
- * Tracing read code
+ * Tracing enable/disable code
*/
+static int toggle_ras_mc_event(int enable)
+{
+ int fd, rc;
+
+ /* Enable RAS events */
+ fd = open(DEBUGFS "tracing/set_event", O_RDWR | O_APPEND);
+ if (fd < 0) {
+ perror("Open set_event");
+ return errno;
+ }
+ if (enable)
+ rc = write(fd, ENABLE_RAS_MC_EVENT,
+ sizeof(ENABLE_RAS_MC_EVENT));
+ else
+ rc = write(fd, DISABLE_RAS_MC_EVENT,
+ sizeof(DISABLE_RAS_MC_EVENT));
+ if (rc < 0) {
+ perror("can't write to set_event");
+ close(fd);
+ return rc;
+ }
+ close(fd);
+ if (!rc) {
+ fprintf(stderr, "nothing was written on set_event\n");
+ return EIO;
+ }
+ if (enable)
+ printf("RAS events enabled\n");
+ else
+ printf("RAS events disabled\n");
+ return 0;
+}
+
+/*
+ * Tracing read code
+ */
static void parse_ras_data(struct pevent *pevent, struct kbuffer *kbuf, void *data, unsigned long long time_stamp)
{
struct pevent_record record;
}
/* FIXME: use select to open for all CPUs */
- fd = open("/sys/kernel/debug/tracing/per_cpu/cpu0/trace_pipe_raw",
+ fd = open(DEBUGFS "tracing/per_cpu/cpu0/trace_pipe_raw",
O_RDONLY);
if (fd < 0) {
perror("Can't open trace_pipe_raw");
struct pevent *pevent;
void *page;
+ /* Enable RAS events */
+ rc = toggle_ras_mc_event(1);
+
pevent = pevent_alloc();
if (!pevent) {
perror("Can't allocate pevent");
return errno;
}
- fd = open("/sys/kernel/debug/tracing/events/ras/mc_event/format",
+ fd = open(DEBUGFS "tracing/events/ras/mc_event/format",
O_RDONLY);
if (fd < 0) {
- perror("open ras format");
+ perror("Open ras format");
rc = errno;
goto free_pevent;
}
const char *argp_program_bug_address = "Mauro Carvalho Chehab <mchehab@redhat.com>";
struct arguments {
- int handle_events;
+ int handle_events, enable_ras;
};
static error_t parse_opt(int k, char *arg, struct argp_state *state)
case 'r':
args->handle_events++;
break;
+ case 'e':
+ args->enable_ras++;
+ break;
+ case 'd':
+ args->enable_ras--;
+ break;
default:
return ARGP_ERR_UNKNOWN;
}
struct arguments args;
int idx = -1;
const struct argp_option options[] = {
- {"read", 'r', 0, 0, "read RAS events", 0},
+ {"read", 'r', 0, 0, "read RAS events", 0},
+ {"enable", 'e', 0, 0, "enable RAS events", 0},
+ {"disable", 'd', 0, 0, "disable RAS events", 0},
+
{ 0, 0, 0, 0, 0, 0 }
};
const struct argp argp = {
return -1;
}
+ if (args.enable_ras > 0)
+ toggle_ras_mc_event(1);
+ else if (args.enable_ras < 0)
+ toggle_ras_mc_event(0);
+
if (args.handle_events)
handle_ras_events();