diff options
author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2009-04-23 09:30:22 -0400 |
---|---|---|
committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2009-04-23 09:30:22 -0400 |
commit | 83d29b3352ab9de77b3324ecaff3435dc02f504b (patch) | |
tree | f0d183dbc40d135c254e16c8df2116bf6353423b | |
parent | f957276cf4ee163f74b669f81c5fc10c6f517f44 (diff) |
litmus proc: add release_master interface
Let user space set which CPU should handle releases. It is up
to plugins to make use of this information.
-rw-r--r-- | include/litmus/litmus.h | 3 | ||||
-rw-r--r-- | litmus/litmus.c | 67 |
2 files changed, 67 insertions, 3 deletions
diff --git a/include/litmus/litmus.h b/include/litmus/litmus.h index 590b63ed24..1b99049eb1 100644 --- a/include/litmus/litmus.h +++ b/include/litmus/litmus.h | |||
@@ -9,8 +9,7 @@ | |||
9 | #include <linux/jiffies.h> | 9 | #include <linux/jiffies.h> |
10 | #include <litmus/sched_trace.h> | 10 | #include <litmus/sched_trace.h> |
11 | 11 | ||
12 | /* RT mode start time */ | 12 | extern atomic_t release_master_cpu; |
13 | extern volatile unsigned long rt_start_time; | ||
14 | 13 | ||
15 | extern atomic_t __log_seq_no; | 14 | extern atomic_t __log_seq_no; |
16 | 15 | ||
diff --git a/litmus/litmus.c b/litmus/litmus.c index 548fe6d3e2..33ae0c3281 100644 --- a/litmus/litmus.c +++ b/litmus/litmus.c | |||
@@ -26,6 +26,9 @@ static DEFINE_SPINLOCK(task_transition_lock); | |||
26 | /* Give log messages sequential IDs. */ | 26 | /* Give log messages sequential IDs. */ |
27 | atomic_t __log_seq_no = ATOMIC_INIT(0); | 27 | atomic_t __log_seq_no = ATOMIC_INIT(0); |
28 | 28 | ||
29 | /* current master CPU for handling timer IRQs */ | ||
30 | atomic_t release_master_cpu = ATOMIC_INIT(NO_CPU); | ||
31 | |||
29 | /* To send signals from the scheduler | 32 | /* To send signals from the scheduler |
30 | * Must drop locks first. | 33 | * Must drop locks first. |
31 | */ | 34 | */ |
@@ -763,10 +766,61 @@ static int proc_write_curr(struct file *file, | |||
763 | } | 766 | } |
764 | 767 | ||
765 | 768 | ||
769 | static int proc_read_release_master(char *page, char **start, | ||
770 | off_t off, int count, | ||
771 | int *eof, void *data) | ||
772 | { | ||
773 | int len, master; | ||
774 | master = atomic_read(&release_master_cpu); | ||
775 | if (master == NO_CPU) | ||
776 | len = snprintf(page, PAGE_SIZE, "NO_CPU\n"); | ||
777 | else | ||
778 | len = snprintf(page, PAGE_SIZE, "%d\n", master); | ||
779 | return len; | ||
780 | } | ||
781 | |||
782 | static int proc_write_release_master(struct file *file, | ||
783 | const char *buffer, | ||
784 | unsigned long count, | ||
785 | void *data) | ||
786 | { | ||
787 | int cpu, err, online = 0; | ||
788 | char msg[64]; | ||
789 | |||
790 | if (count > 63) | ||
791 | return -EINVAL; | ||
792 | |||
793 | if (copy_from_user(msg, buffer, count)) | ||
794 | return -EFAULT; | ||
795 | |||
796 | /* terminate */ | ||
797 | msg[count] = '\0'; | ||
798 | /* chomp */ | ||
799 | if (count > 1 && msg[count - 1] == '\n') | ||
800 | msg[count - 1] = '\0'; | ||
801 | |||
802 | if (strcmp(msg, "NO_CPU") == 0) { | ||
803 | atomic_set(&release_master_cpu, NO_CPU); | ||
804 | return count; | ||
805 | } else { | ||
806 | err = sscanf(msg, "%d", &cpu); | ||
807 | if (err == 1 && cpu >= 0 && (online = cpu_online(cpu))) { | ||
808 | atomic_set(&release_master_cpu, cpu); | ||
809 | return count; | ||
810 | } else { | ||
811 | TRACE("invalid release master: '%s' " | ||
812 | "(err:%d cpu:%d online:%d)\n", | ||
813 | msg, err, cpu, online); | ||
814 | return -EINVAL; | ||
815 | } | ||
816 | } | ||
817 | } | ||
818 | |||
766 | static struct proc_dir_entry *litmus_dir = NULL, | 819 | static struct proc_dir_entry *litmus_dir = NULL, |
767 | *curr_file = NULL, | 820 | *curr_file = NULL, |
768 | *stat_file = NULL, | 821 | *stat_file = NULL, |
769 | *plugs_file = NULL; | 822 | *plugs_file = NULL, |
823 | *release_master_file = NULL; | ||
770 | 824 | ||
771 | static int __init init_litmus_proc(void) | 825 | static int __init init_litmus_proc(void) |
772 | { | 826 | { |
@@ -788,6 +842,17 @@ static int __init init_litmus_proc(void) | |||
788 | curr_file->read_proc = proc_read_curr; | 842 | curr_file->read_proc = proc_read_curr; |
789 | curr_file->write_proc = proc_write_curr; | 843 | curr_file->write_proc = proc_write_curr; |
790 | 844 | ||
845 | release_master_file = create_proc_entry("release_master", | ||
846 | 0644, litmus_dir); | ||
847 | if (!release_master_file) { | ||
848 | printk(KERN_ERR "Could not allocate release_master " | ||
849 | "procfs entry.\n"); | ||
850 | return -ENOMEM; | ||
851 | } | ||
852 | release_master_file->owner = THIS_MODULE; | ||
853 | release_master_file->read_proc = proc_read_release_master; | ||
854 | release_master_file->write_proc = proc_write_release_master; | ||
855 | |||
791 | stat_file = create_proc_read_entry("stats", 0444, litmus_dir, | 856 | stat_file = create_proc_read_entry("stats", 0444, litmus_dir, |
792 | proc_read_stats, NULL); | 857 | proc_read_stats, NULL); |
793 | 858 | ||