diff options
Diffstat (limited to 'litmus/color_proc.c')
-rw-r--r-- | litmus/color_proc.c | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/litmus/color_proc.c b/litmus/color_proc.c index 4cb6c9ac89bb..0ac533f96d3e 100644 --- a/litmus/color_proc.c +++ b/litmus/color_proc.c | |||
@@ -2,17 +2,30 @@ | |||
2 | #include <linux/sysctl.h> | 2 | #include <linux/sysctl.h> |
3 | #include <linux/slab.h> | 3 | #include <linux/slab.h> |
4 | 4 | ||
5 | #include <litmus/sched_trace.h> | ||
5 | #include <litmus/color.h> | 6 | #include <litmus/color.h> |
6 | 7 | ||
8 | #define SPERIOD_LEN 7 | ||
9 | #define SPERIOD_FILE "period" | ||
10 | #define SWCET_LEN 5 | ||
11 | #define SWCET_FILE "wcet" | ||
12 | |||
7 | extern int color_sysctl_add_pages_data; /* litmus/color.c */ | 13 | extern int color_sysctl_add_pages_data; /* litmus/color.c */ |
8 | 14 | ||
9 | static int zero = 0; | 15 | static int zero = 0; |
10 | static int one = 1; | 16 | static int one = 1; |
11 | 17 | ||
18 | static unsigned long *server_wcet; | ||
19 | static unsigned long *server_period; | ||
20 | |||
12 | #define NR_PAGES_INDEX 0 /* location of nr_pages in the table below */ | 21 | #define NR_PAGES_INDEX 0 /* location of nr_pages in the table below */ |
13 | static struct ctl_table color_table[] = | 22 | static struct ctl_table color_table[] = |
14 | { | 23 | { |
15 | { | 24 | { |
25 | .procname = "servers", | ||
26 | .mode = 0555, | ||
27 | }, | ||
28 | { | ||
16 | /* you MUST update NR_PAGES_INDEX if you move this entry */ | 29 | /* you MUST update NR_PAGES_INDEX if you move this entry */ |
17 | .procname = "nr_pages", | 30 | .procname = "nr_pages", |
18 | .mode = 0444, | 31 | .mode = 0444, |
@@ -41,6 +54,7 @@ static struct ctl_table litmus_table[] = | |||
41 | }, | 54 | }, |
42 | { } | 55 | { } |
43 | }; | 56 | }; |
57 | |||
44 | static struct ctl_table litmus_dir_table[] = { | 58 | static struct ctl_table litmus_dir_table[] = { |
45 | { | 59 | { |
46 | .procname = "litmus", | 60 | .procname = "litmus", |
@@ -50,6 +64,26 @@ static struct ctl_table litmus_dir_table[] = { | |||
50 | { } | 64 | { } |
51 | }; | 65 | }; |
52 | 66 | ||
67 | int color_server_params(int cpu, unsigned long *wcet, unsigned long *period) | ||
68 | { | ||
69 | if (cpu >= num_online_cpus()) { | ||
70 | printk(KERN_WARNING "Cannot access illegal CPU: %d\n", cpu); | ||
71 | return -EFAULT; | ||
72 | } | ||
73 | |||
74 | if (server_wcet[cpu] == 0 || server_period[cpu] == 0) { | ||
75 | printk(KERN_WARNING "Server %d is uninitialized!\n", cpu); | ||
76 | return -EPERM; | ||
77 | } | ||
78 | |||
79 | *wcet = server_wcet[cpu]; | ||
80 | *period = server_period[cpu]; | ||
81 | |||
82 | TRACE("For %d: %lu, %lu\n", cpu, server_wcet[cpu], server_period[cpu]); | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
53 | extern unsigned long nr_colors; /* litmus/color.c */ | 87 | extern unsigned long nr_colors; /* litmus/color.c */ |
54 | 88 | ||
55 | /* must be called AFTER nr_colors is set */ | 89 | /* must be called AFTER nr_colors is set */ |
@@ -67,11 +101,101 @@ out: | |||
67 | return ret; | 101 | return ret; |
68 | } | 102 | } |
69 | 103 | ||
104 | static void __init init_server_entry(struct ctl_table *entry, | ||
105 | unsigned long *parameter, | ||
106 | char *name) | ||
107 | { | ||
108 | entry->procname = name; | ||
109 | entry->mode = 0666; | ||
110 | entry->proc_handler = proc_doulongvec_minmax; | ||
111 | entry->data = parameter; | ||
112 | entry->maxlen = sizeof(unsigned long); | ||
113 | } | ||
114 | |||
115 | static int __init init_cpu_entry(struct ctl_table *cpu_table, int cpu) | ||
116 | { | ||
117 | char *name; | ||
118 | size_t size; | ||
119 | struct ctl_table *server_table, *entry; | ||
120 | |||
121 | server_wcet[cpu] = 0; | ||
122 | server_period[cpu] = 0; | ||
123 | |||
124 | printk(KERN_INFO "Creating cpu %d\n", cpu); | ||
125 | |||
126 | size = sizeof(ctl_table) * 3; | ||
127 | server_table = kmalloc(size, GFP_ATOMIC); | ||
128 | if (!server_table) { | ||
129 | printk(KERN_WARNING "Could not allocate " | ||
130 | "color server proc for CPU %d.\n", cpu); | ||
131 | return -ENOMEM; | ||
132 | } | ||
133 | memset(server_table, 0, size); | ||
134 | |||
135 | /* Server WCET */ | ||
136 | name = kmalloc(SWCET_LEN, GFP_ATOMIC); | ||
137 | if (!name) { | ||
138 | return -ENOMEM; | ||
139 | } | ||
140 | strcpy(name, SWCET_FILE); | ||
141 | entry = &server_table[0]; | ||
142 | init_server_entry(entry, &server_wcet[cpu], name); | ||
143 | |||
144 | |||
145 | /* Server period */ | ||
146 | name = kmalloc(SPERIOD_LEN, GFP_ATOMIC); | ||
147 | if (!name) { | ||
148 | return -ENOMEM; | ||
149 | } | ||
150 | strcpy(name, SPERIOD_FILE); | ||
151 | entry = &server_table[1]; | ||
152 | init_server_entry(entry, &server_period[cpu], name); | ||
153 | |||
154 | name = kmalloc(3, GFP_ATOMIC); | ||
155 | if (!name) { | ||
156 | return -ENOMEM; | ||
157 | } | ||
158 | snprintf(name, 2, "%d", cpu); | ||
159 | cpu_table->procname = name; | ||
160 | cpu_table->mode = 0555; | ||
161 | cpu_table->child = server_table; | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static int __init init_server_entries(struct ctl_table *cpu_tables) | ||
167 | { | ||
168 | size_t size; | ||
169 | int ret, cpu; | ||
170 | struct ctl_table *cpu_table; | ||
171 | |||
172 | size = sizeof(unsigned long) * num_online_cpus(); | ||
173 | server_wcet = kmalloc(size, GFP_ATOMIC); | ||
174 | server_period = kmalloc(size, GFP_ATOMIC); | ||
175 | if (!server_wcet || !server_period) { | ||
176 | printk(KERN_WARNING "Could not allocate server parameters.\n"); | ||
177 | return -ENOMEM; | ||
178 | } | ||
179 | |||
180 | for_each_online_cpu(cpu) { | ||
181 | cpu_table = &cpu_tables[cpu]; | ||
182 | ret = init_cpu_entry(cpu_table, cpu); | ||
183 | if (ret) { | ||
184 | return ret; | ||
185 | } | ||
186 | } | ||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | |||
70 | static struct ctl_table_header *litmus_sysctls; | 191 | static struct ctl_table_header *litmus_sysctls; |
71 | 192 | ||
72 | static int __init litmus_sysctl_init(void) | 193 | static int __init litmus_sysctl_init(void) |
73 | { | 194 | { |
74 | int ret = 0; | 195 | int ret = 0; |
196 | size_t size; | ||
197 | struct ctl_table *cpu_tables; | ||
198 | |||
75 | printk(KERN_INFO "Registering LITMUS^RT proc sysctl.\n"); | 199 | printk(KERN_INFO "Registering LITMUS^RT proc sysctl.\n"); |
76 | litmus_sysctls = register_sysctl_table(litmus_dir_table); | 200 | litmus_sysctls = register_sysctl_table(litmus_dir_table); |
77 | if (!litmus_sysctls) { | 201 | if (!litmus_sysctls) { |
@@ -80,6 +204,25 @@ static int __init litmus_sysctl_init(void) | |||
80 | goto out; | 204 | goto out; |
81 | } | 205 | } |
82 | ret = init_sysctl_nr_colors(); | 206 | ret = init_sysctl_nr_colors(); |
207 | if (ret) | ||
208 | goto out; | ||
209 | |||
210 | |||
211 | size = sizeof(ctl_table) * (num_online_cpus() + 2); | ||
212 | cpu_tables = kmalloc(size, GFP_ATOMIC); | ||
213 | if (!cpu_tables) { | ||
214 | printk(KERN_WARNING "Could not allocate color CPU proc.\n"); | ||
215 | ret = -ENOMEM; | ||
216 | goto out; | ||
217 | } | ||
218 | memset(cpu_tables, 0, size); | ||
219 | |||
220 | ret = init_server_entries(cpu_tables); | ||
221 | if (ret) | ||
222 | goto out; | ||
223 | |||
224 | color_table[0].child = cpu_tables; | ||
225 | |||
83 | out: | 226 | out: |
84 | return ret; | 227 | return ret; |
85 | } | 228 | } |