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 | ||
