From 0582049eb884469ad8e7b0a0f57317efe7a1f164 Mon Sep 17 00:00:00 2001 From: Luis Gerhorst <luis.gerhorst@fau.de> Date: Mon, 25 Jun 2018 15:51:02 +0200 Subject: [PATCH] Prepare/do/postprocess trigger --- arch/arm/measuremore/trigger.c | 129 ++++++++++++++++++++++++++------- 1 file changed, 102 insertions(+), 27 deletions(-) diff --git a/arch/arm/measuremore/trigger.c b/arch/arm/measuremore/trigger.c index 29ed3b0..b1ab2e0 100644 --- a/arch/arm/measuremore/trigger.c +++ b/arch/arm/measuremore/trigger.c @@ -139,15 +139,15 @@ enum memo_delay_type { static char *delay_type_map_strings[] = {"udelay\n", "usleep_range\n", NULL}; static enum memo_delay_type delay_type_map[] = {MMDT_UDELAY, MMDT_USLEEP_RANGE}; -static const char *option_delay_type_str = "udelay\n"; -static enum memo_delay_type option_delay_type = MMDT_UDELAY; +static const char *debugfs_delay_type_str = "udelay\n"; +static enum memo_delay_type debugfs_delay_type = MMDT_UDELAY; static ssize_t delay_type_read(struct file *fp, char __user *user_buffer, size_t count, loff_t *position) { return simple_read_from_buffer(user_buffer, count, position, - option_delay_type_str, - strlen(option_delay_type_str)); + debugfs_delay_type_str, + strlen(debugfs_delay_type_str)); } static ssize_t delay_type_write(struct file *fp, const char __user *user_buffer, @@ -161,8 +161,8 @@ static ssize_t delay_type_write(struct file *fp, const char __user *user_buffer, for (int i = 0; delay_type_map_strings[i]; i++) { if (strcmp(delay_type_map_strings[i], buf) == 0) { - option_delay_type = delay_type_map[i]; - option_delay_type_str = delay_type_map_strings[i]; + debugfs_delay_type = delay_type_map[i]; + debugfs_delay_type_str = delay_type_map_strings[i]; return count; } } @@ -181,7 +181,7 @@ static const struct file_operations debugfs_delay_type_fops = { * Vars Exposed Through Sysfs * ******************************/ -static u64 debugfs_trigger_since_boot = 0; +static u64 debugfs_do_trigger_since_boot = 0; static u64 debugfs_delay_ms = 20; static u64 debugfs_reps = 1000; static u64 debugfs_cp_capacity = 25; @@ -226,24 +226,71 @@ static void memo_trigger_interrupt(void) gpio_set_value(GPIO_OUT, 0); } -static int memo_trigger(void) { - debugfs_trigger_since_boot++; +enum memo_trigger_state { + MMTS_PREPARED, + MMTS_DONE, + MMTS_POSTPROCESSED +}; + +static enum memo_trigger_state current_trigger_state = MMTS_POSTPROCESSED; + +/* Prepare Trigger */ + +static int memo_prepare_trigger(void) { + if (current_trigger_state != MMTS_POSTPROCESSED) { + return -1; + } + current_trigger_state = MMTS_PREPARED; + + const unsigned long reps = debugfs_reps; + const unsigned long cp_capacity = debugfs_cp_capacity; + return memo_start_benchmark(reps, cp_capacity); +} + +static ssize_t prepare_trigger_write(struct file *file, const char __user *addr, + size_t len, loff_t *pos) +{ + int err = memo_prepare_trigger(); + if (err) { + pr_err("prepare_trigger failed with error %d\n", err); + } + return len; +} + +static ssize_t memo_empty_read(struct file *fp, char __user *user_buffer, + size_t count, loff_t *position) +{ + return simple_read_from_buffer(user_buffer, count, position, "", 0); +} + +static const struct file_operations prepare_trigger_fops = { + .write = prepare_trigger_write, + .read = memo_empty_read, + .llseek = noop_llseek, /* TODO: via fs.c gcov_reset_fops, not sure why */ +}; + +/* Do Trigger */ + +static int memo_do_trigger(void) { + if (current_trigger_state != MMTS_PREPARED) { + return -1; + } + current_trigger_state = MMTS_DONE; + + debugfs_do_trigger_since_boot++; const uint64_t delay_ms = debugfs_delay_ms; const uint64_t delay_us = delay_ms*1000; const uint64_t delay_ns = delay_ms*1000*1000; const unsigned long reps = debugfs_reps; - const unsigned long cp_capacity = debugfs_cp_capacity; - const enum memo_delay_type delay_type_function = option_delay_type; - memo_start_benchmark(reps, cp_capacity); for (uint64_t i = 0; i < reps; i++) { memo_start_run(); memo_checkpoint("checkpoint_1"); memo_checkpoint("checkpoint_2"); memo_checkpoint("checkpoint_3"); memo_trigger_interrupt(); - switch (delay_type_function) { + switch (debugfs_delay_type) { case MMDT_USLEEP_RANGE: usleep_range(delay_us, delay_us); break; @@ -256,30 +303,53 @@ static int memo_trigger(void) { } memo_stop_run(); } - memo_stop_benchmark(); + return 0; /* TODO: Signal error. */ } -static ssize_t trigger_write(struct file *file, const char __user *addr, +static ssize_t do_trigger_write(struct file *file, const char __user *addr, size_t len, loff_t *pos) { - pr_info("trigger write\n"); - int err = memo_trigger(); + int err = memo_do_trigger(); if (err) { - pr_err("trigger failed with error %d\n", err); + pr_err("do_trigger failed with error %d\n", err); } return len; } -static ssize_t memo_empty_read(struct file *fp, char __user *user_buffer, - size_t count, loff_t *position) +/* TODO: Does block when logging in, triggering, logging out, triggering again. */ +static const struct file_operations do_trigger_fops = { + .write = do_trigger_write, + .read = memo_empty_read, + .llseek = noop_llseek, /* TODO: via fs.c gcov_reset_fops, not sure why */ +}; + +/* Postprocess Trigger */ + +static int memo_postprocess_trigger(void) { + if (current_trigger_state != MMTS_DONE) { + return -1; + } + current_trigger_state = MMTS_POSTPROCESSED; + + memo_stop_benchmark(); + return 0; +} + +static ssize_t postprocess_trigger_write(struct file *file, + const char __user *addr, size_t len, + loff_t *pos) { - return simple_read_from_buffer(user_buffer, count, position, "", 0); + + int err = memo_postprocess_trigger(); + if (err) { + pr_err("postprocess_trigger failed with error %d\n", err); + } + return len; } -/* TODO: Does block when logging in, triggering, logging out, triggering again. */ -static const struct file_operations trigger_fops = { - .write = trigger_write, +static const struct file_operations postprocess_trigger_fops = { + .write = postprocess_trigger_write, .read = memo_empty_read, .llseek = noop_llseek, /* TODO: via fs.c gcov_reset_fops, not sure why */ }; @@ -312,8 +382,8 @@ static int create_files(void) debugfs_create_bool("vmalloc_checkpoint_matrix", 0400, memo_root, &debugfs_vmalloc_cp_matrix); - debugfs_create_u64("trigger_since_boot", 0600, memo_root, - &debugfs_trigger_since_boot); + debugfs_create_u64("do_trigger_since_boot", 0600, memo_root, + &debugfs_do_trigger_since_boot); debugfs_create_u64("delay_ms", 0600, memo_root, &debugfs_delay_ms); debugfs_create_u64("reps", 0600, memo_root, &debugfs_reps); @@ -331,7 +401,12 @@ static int create_files(void) * those calls to remove would deadlock. TODO: Not sure whether this is * the right solution, maybe, to be completely correct, we must use * debugfs_use_file_start/finish() inside the write function. */ - debugfs_create_file_unsafe("trigger", 0600, memo_root, NULL, &trigger_fops); + debugfs_create_file("prepare_trigger", 0600, memo_root, NULL, + &prepare_trigger_fops); + debugfs_create_file("do_trigger", 0600, memo_root, NULL, + &do_trigger_fops); + debugfs_create_file_unsafe("postprocess_trigger", 0600, memo_root, NULL, + &postprocess_trigger_fops); return 0; } -- GitLab