diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-12-13 18:39:27 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-12-13 18:39:27 -0500 |
commit | fa1229f9776c7ecc99baa187e0b485ebdbfdd78c (patch) | |
tree | 91da6c45685c436ddcc299117df0dab03933caf7 | |
parent | 8f4bc19471bd49f4dcf6ab20254b7c71ec12e4e2 (diff) |
Allow klmirqd threads to be given names.wip-klmirqd-to-aux
-rw-r--r-- | include/litmus/litmus_softirq.h | 7 | ||||
-rw-r--r-- | litmus/Kconfig | 3 | ||||
-rw-r--r-- | litmus/litmus.c | 12 | ||||
-rw-r--r-- | litmus/litmus_softirq.c | 84 | ||||
-rw-r--r-- | litmus/nvidia_info.c | 5 | ||||
-rw-r--r-- | litmus/sched_gsn_edf.c | 2 |
6 files changed, 80 insertions, 33 deletions
diff --git a/include/litmus/litmus_softirq.h b/include/litmus/litmus_softirq.h index 52e3f7e74ab1..cfef08187464 100644 --- a/include/litmus/litmus_softirq.h +++ b/include/litmus/litmus_softirq.h | |||
@@ -57,8 +57,13 @@ typedef struct | |||
57 | data will be initialized. | 57 | data will be initialized. |
58 | 58 | ||
59 | cpu == -1 for no affinity | 59 | cpu == -1 for no affinity |
60 | |||
61 | provide a name at most 31 (32, + null terminator) characters long. | ||
62 | name == NULL for a default name. (all names are appended with | ||
63 | base-CPU affinity) | ||
60 | */ | 64 | */ |
61 | int launch_klmirqd_thread(int cpu, klmirqd_callback_t* cb); | 65 | #define MAX_KLMIRQD_NAME_LEN 31 |
66 | int launch_klmirqd_thread(char* name, int cpu, klmirqd_callback_t* cb); | ||
62 | 67 | ||
63 | 68 | ||
64 | /* Flushes all pending work out to the OS for regular | 69 | /* Flushes all pending work out to the OS for regular |
diff --git a/litmus/Kconfig b/litmus/Kconfig index b704e893e9be..c05405094ea4 100644 --- a/litmus/Kconfig +++ b/litmus/Kconfig | |||
@@ -476,7 +476,8 @@ config LITMUS_NV_KLMIRQD_DEBUG | |||
476 | default n | 476 | default n |
477 | help | 477 | help |
478 | Causes tasklets to be sporadically dispatched to waiting klmirqd | 478 | Causes tasklets to be sporadically dispatched to waiting klmirqd |
479 | threads. | 479 | threads. WARNING! Kernel panic may occur if you switch between |
480 | LITMUS plugins! | ||
480 | 481 | ||
481 | endmenu | 482 | endmenu |
482 | 483 | ||
diff --git a/litmus/litmus.c b/litmus/litmus.c index 1aada57176de..1b4b9d25dbdc 100644 --- a/litmus/litmus.c +++ b/litmus/litmus.c | |||
@@ -556,14 +556,16 @@ int switch_sched_plugin(struct sched_plugin* plugin) | |||
556 | ret = litmus->deactivate_plugin(); | 556 | ret = litmus->deactivate_plugin(); |
557 | if (0 != ret) | 557 | if (0 != ret) |
558 | goto out; | 558 | goto out; |
559 | ret = plugin->activate_plugin(); | 559 | |
560 | litmus = plugin; // switch | ||
561 | mb(); // make sure it's seen everywhere. | ||
562 | ret = litmus->activate_plugin(); | ||
560 | if (0 != ret) { | 563 | if (0 != ret) { |
561 | printk(KERN_INFO "Can't activate %s (%d).\n", | 564 | printk(KERN_INFO "Can't activate %s (%d).\n", |
562 | plugin->plugin_name, ret); | 565 | litmus->plugin_name, ret); |
563 | plugin = &linux_sched_plugin; | 566 | litmus = &linux_sched_plugin; |
564 | } | 567 | } |
565 | printk(KERN_INFO "Switching to LITMUS^RT plugin %s.\n", plugin->plugin_name); | 568 | printk(KERN_INFO "Switching to LITMUS^RT plugin %s.\n", litmus->plugin_name); |
566 | litmus = plugin; | ||
567 | } else | 569 | } else |
568 | ret = -EBUSY; | 570 | ret = -EBUSY; |
569 | out: | 571 | out: |
diff --git a/litmus/litmus_softirq.c b/litmus/litmus_softirq.c index be06405021c5..464a78d780ad 100644 --- a/litmus/litmus_softirq.c +++ b/litmus/litmus_softirq.c | |||
@@ -34,7 +34,7 @@ struct klmirqd_registration | |||
34 | struct list_head threads; | 34 | struct list_head threads; |
35 | }; | 35 | }; |
36 | 36 | ||
37 | static atomic_t klmirqd_id_gen = ATOMIC_INIT(0); | 37 | static atomic_t klmirqd_id_gen = ATOMIC_INIT(-1); |
38 | 38 | ||
39 | static struct klmirqd_registration klmirqd_state; | 39 | static struct klmirqd_registration klmirqd_state; |
40 | 40 | ||
@@ -136,12 +136,11 @@ void kill_klmirqd_thread(struct task_struct* klmirqd_thread) | |||
136 | raw_spin_unlock_irqrestore(&klmirqd_state.lock, flags); | 136 | raw_spin_unlock_irqrestore(&klmirqd_state.lock, flags); |
137 | } | 137 | } |
138 | 138 | ||
139 | |||
140 | |||
141 | struct klmirqd_launch_data | 139 | struct klmirqd_launch_data |
142 | { | 140 | { |
143 | int cpu_affinity; | 141 | int cpu_affinity; |
144 | klmirqd_callback_t* cb; | 142 | klmirqd_callback_t* cb; |
143 | char name[MAX_KLMIRQD_NAME_LEN+1]; | ||
145 | struct work_struct work; | 144 | struct work_struct work; |
146 | }; | 145 | }; |
147 | 146 | ||
@@ -156,47 +155,76 @@ static void __launch_klmirqd_thread(struct work_struct *work) | |||
156 | struct klmirqd_launch_data* launch_data = | 155 | struct klmirqd_launch_data* launch_data = |
157 | container_of(work, struct klmirqd_launch_data, work); | 156 | container_of(work, struct klmirqd_launch_data, work); |
158 | 157 | ||
159 | TRACE("%s: Creating klmirqd thread\n", __FUNCTION__); | 158 | TRACE("Creating klmirqd thread\n"); |
159 | |||
160 | 160 | ||
161 | id = atomic_inc_return(&klmirqd_id_gen); | ||
162 | 161 | ||
163 | if (launch_data->cpu_affinity != -1) { | 162 | if (launch_data->cpu_affinity != -1) { |
164 | thread = kthread_create( | 163 | if (launch_data->name[0] == '\0') { |
165 | run_klmirqd, | 164 | id = atomic_inc_return(&klmirqd_id_gen); |
166 | /* treat the affinity as a pointer, we'll cast it back later */ | 165 | TRACE("Launching klmirqd_th%d/%d\n", id, launch_data->cpu_affinity); |
167 | (void*)launch_data->cb, | 166 | |
168 | "klmirqd_th%d/%d", | 167 | thread = kthread_create( |
169 | id, | 168 | run_klmirqd, |
170 | launch_data->cpu_affinity); | 169 | /* treat the affinity as a pointer, we'll cast it back later */ |
170 | (void*)launch_data->cb, | ||
171 | "klmirqd_th%d/%d", | ||
172 | id, | ||
173 | launch_data->cpu_affinity); | ||
174 | } | ||
175 | else { | ||
176 | TRACE("Launching %s/%d\n", launch_data->name, launch_data->cpu_affinity); | ||
177 | |||
178 | thread = kthread_create( | ||
179 | run_klmirqd, | ||
180 | /* treat the affinity as a pointer, we'll cast it back later */ | ||
181 | (void*)launch_data->cb, | ||
182 | "%s/%d", | ||
183 | launch_data->name, | ||
184 | launch_data->cpu_affinity); | ||
185 | } | ||
171 | 186 | ||
172 | /* litmus will put is in the right cluster. */ | 187 | /* litmus will put is in the right cluster. */ |
173 | kthread_bind(thread, launch_data->cpu_affinity); | 188 | kthread_bind(thread, launch_data->cpu_affinity); |
174 | |||
175 | TRACE("%s: Launching klmirqd_th%d/%d\n", __FUNCTION__, id, launch_data->cpu_affinity); | ||
176 | } | 189 | } |
177 | else { | 190 | else { |
178 | thread = kthread_create( | 191 | if (launch_data->name[0] == '\0') { |
179 | run_klmirqd, | 192 | id = atomic_inc_return(&klmirqd_id_gen); |
180 | /* treat the affinity as a pointer, we'll cast it back later */ | 193 | TRACE("Launching klmirqd_th%d\n", id); |
181 | (void*)launch_data->cb, | 194 | |
182 | "klmirqd_th%d", | 195 | thread = kthread_create( |
183 | id); | 196 | run_klmirqd, |
184 | 197 | /* treat the affinity as a pointer, we'll cast it back later */ | |
185 | TRACE("%s: Launching klmirqd_th%d\n", __FUNCTION__, id); | 198 | (void*)launch_data->cb, |
199 | "klmirqd_th%d", | ||
200 | id); | ||
201 | |||
202 | } | ||
203 | else { | ||
204 | TRACE("Launching %s\n", launch_data->name); | ||
205 | |||
206 | thread = kthread_create( | ||
207 | run_klmirqd, | ||
208 | /* treat the affinity as a pointer, we'll cast it back later */ | ||
209 | (void*)launch_data->cb, | ||
210 | launch_data->name); | ||
211 | } | ||
212 | |||
213 | |||
186 | } | 214 | } |
187 | 215 | ||
188 | if (thread) { | 216 | if (thread) { |
189 | wake_up_process(thread); | 217 | wake_up_process(thread); |
190 | } | 218 | } |
191 | else { | 219 | else { |
192 | TRACE("Could not create klmirqd/%d thread!\n", id); | 220 | TRACE("Could not create thread!\n"); |
193 | } | 221 | } |
194 | 222 | ||
195 | kfree(launch_data); | 223 | kfree(launch_data); |
196 | } | 224 | } |
197 | 225 | ||
198 | 226 | ||
199 | int launch_klmirqd_thread(int cpu, klmirqd_callback_t* cb) | 227 | int launch_klmirqd_thread(char* name, int cpu, klmirqd_callback_t* cb) |
200 | { | 228 | { |
201 | struct klmirqd_launch_data* delayed_launch; | 229 | struct klmirqd_launch_data* delayed_launch; |
202 | 230 | ||
@@ -211,6 +239,14 @@ int launch_klmirqd_thread(int cpu, klmirqd_callback_t* cb) | |||
211 | delayed_launch->cpu_affinity = cpu; | 239 | delayed_launch->cpu_affinity = cpu; |
212 | delayed_launch->cb = cb; | 240 | delayed_launch->cb = cb; |
213 | INIT_WORK(&delayed_launch->work, __launch_klmirqd_thread); | 241 | INIT_WORK(&delayed_launch->work, __launch_klmirqd_thread); |
242 | |||
243 | if(name) { | ||
244 | snprintf(delayed_launch->name, MAX_KLMIRQD_NAME_LEN+1, "%s", name); | ||
245 | } | ||
246 | else { | ||
247 | delayed_launch->name[0] = '\0'; | ||
248 | } | ||
249 | |||
214 | schedule_work(&delayed_launch->work); | 250 | schedule_work(&delayed_launch->work); |
215 | 251 | ||
216 | return 0; | 252 | return 0; |
diff --git a/litmus/nvidia_info.c b/litmus/nvidia_info.c index 059a7e7ac715..5a63fb732e8b 100644 --- a/litmus/nvidia_info.c +++ b/litmus/nvidia_info.c | |||
@@ -496,6 +496,7 @@ static int gpu_owner_max_priority_order(struct binheap_node *a, | |||
496 | static int init_nv_device_reg(void) | 496 | static int init_nv_device_reg(void) |
497 | { | 497 | { |
498 | int i; | 498 | int i; |
499 | char name[MAX_KLMIRQD_NAME_LEN+1]; | ||
499 | 500 | ||
500 | #ifdef CONFIG_LITMUS_SOFTIRQD | 501 | #ifdef CONFIG_LITMUS_SOFTIRQD |
501 | if (!klmirqd_is_ready()) { | 502 | if (!klmirqd_is_ready()) { |
@@ -520,11 +521,13 @@ static int init_nv_device_reg(void) | |||
520 | { | 521 | { |
521 | int default_cpu = litmus->map_gpu_to_cpu(i); | 522 | int default_cpu = litmus->map_gpu_to_cpu(i); |
522 | 523 | ||
524 | snprintf(name, MAX_KLMIRQD_NAME_LEN, "nvklmirqd%d", i); | ||
525 | |||
523 | NV_DEVICE_REG[i].callback.func = nvidia_klmirqd_cb; | 526 | NV_DEVICE_REG[i].callback.func = nvidia_klmirqd_cb; |
524 | NV_DEVICE_REG[i].callback.arg = (void*)(long long)(i); | 527 | NV_DEVICE_REG[i].callback.arg = (void*)(long long)(i); |
525 | mb(); | 528 | mb(); |
526 | 529 | ||
527 | if(launch_klmirqd_thread(default_cpu, &NV_DEVICE_REG[i].callback) != 0) { | 530 | if(launch_klmirqd_thread(name, default_cpu, &NV_DEVICE_REG[i].callback) != 0) { |
528 | TRACE("Failed to create klmirqd thread for GPU %d\n", i); | 531 | TRACE("Failed to create klmirqd thread for GPU %d\n", i); |
529 | } | 532 | } |
530 | } | 533 | } |
diff --git a/litmus/sched_gsn_edf.c b/litmus/sched_gsn_edf.c index 4ac573a6f0f7..7eb44fee1861 100644 --- a/litmus/sched_gsn_edf.c +++ b/litmus/sched_gsn_edf.c | |||
@@ -1838,7 +1838,7 @@ UNSUPPORTED_AFF_OBS: | |||
1838 | #if defined(CONFIG_LITMUS_NVIDIA) && defined(CONFIG_LITMUS_SOFTIRQD) | 1838 | #if defined(CONFIG_LITMUS_NVIDIA) && defined(CONFIG_LITMUS_SOFTIRQD) |
1839 | static int gsnedf_map_gpu_to_cpu(int gpu) | 1839 | static int gsnedf_map_gpu_to_cpu(int gpu) |
1840 | { | 1840 | { |
1841 | return 0; // CPU_0 is default in all cases. | 1841 | return -1; // No CPU affinity needed. |
1842 | } | 1842 | } |
1843 | #endif | 1843 | #endif |
1844 | 1844 | ||