aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-12-13 18:39:27 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-12-13 18:39:27 -0500
commitfa1229f9776c7ecc99baa187e0b485ebdbfdd78c (patch)
tree91da6c45685c436ddcc299117df0dab03933caf7
parent8f4bc19471bd49f4dcf6ab20254b7c71ec12e4e2 (diff)
Allow klmirqd threads to be given names.wip-klmirqd-to-aux
-rw-r--r--include/litmus/litmus_softirq.h7
-rw-r--r--litmus/Kconfig3
-rw-r--r--litmus/litmus.c12
-rw-r--r--litmus/litmus_softirq.c84
-rw-r--r--litmus/nvidia_info.c5
-rw-r--r--litmus/sched_gsn_edf.c2
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 */
61int launch_klmirqd_thread(int cpu, klmirqd_callback_t* cb); 65#define MAX_KLMIRQD_NAME_LEN 31
66int 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
481endmenu 482endmenu
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;
569out: 571out:
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
37static atomic_t klmirqd_id_gen = ATOMIC_INIT(0); 37static atomic_t klmirqd_id_gen = ATOMIC_INIT(-1);
38 38
39static struct klmirqd_registration klmirqd_state; 39static 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
141struct klmirqd_launch_data 139struct 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
199int launch_klmirqd_thread(int cpu, klmirqd_callback_t* cb) 227int 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,
496static int init_nv_device_reg(void) 496static 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)
1839static int gsnedf_map_gpu_to_cpu(int gpu) 1839static 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