diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-12-13 11:44:23 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-12-13 11:44:23 -0500 |
commit | 4ea2c9490eaf9df55ccbfe6f4c56518fc4bdce8f (patch) | |
tree | 02ddf7315fb52960dd72654010ccc10d5833327a | |
parent | 2ccc2c4cc981a68e703082e6e32f5483ad87b61c (diff) |
Fix klmirqd plugin switching to not panic.
-rw-r--r-- | litmus/Kconfig | 13 | ||||
-rw-r--r-- | litmus/litmus.c | 23 | ||||
-rw-r--r-- | litmus/litmus_softirq.c | 27 | ||||
-rw-r--r-- | litmus/nvidia_info.c | 5 |
4 files changed, 35 insertions, 33 deletions
diff --git a/litmus/Kconfig b/litmus/Kconfig index 9aeae659ae32..8ca66b4d687c 100644 --- a/litmus/Kconfig +++ b/litmus/Kconfig | |||
@@ -443,19 +443,6 @@ config NV_DEVICE_NUM | |||
443 | Should be (<= to the number of CPUs) and | 443 | Should be (<= to the number of CPUs) and |
444 | (<= to the number of GPUs) in your system. | 444 | (<= to the number of GPUs) in your system. |
445 | 445 | ||
446 | config NV_MAX_SIMULT_USERS | ||
447 | int "Maximum number of threads sharing a GPU simultanously" | ||
448 | depends on LITMUS_NVIDIA | ||
449 | range 1 3 | ||
450 | default "2" | ||
451 | help | ||
452 | Should be at least equal to the #copy_engines + #execution_engines | ||
453 | of the GPUs in your system. | ||
454 | |||
455 | Scientific/Professional GPUs = 3 (ex. M2070, Quadro 6000?) | ||
456 | Consumer Fermi/Kepler GPUs = 2 (GTX-4xx thru -6xx) | ||
457 | Older = 1 (ex. GTX-2xx) | ||
458 | |||
459 | choice | 446 | choice |
460 | prompt "CUDA/Driver Version Support" | 447 | prompt "CUDA/Driver Version Support" |
461 | default CUDA_5_0 | 448 | default CUDA_5_0 |
diff --git a/litmus/litmus.c b/litmus/litmus.c index fa244ba53e22..f98aa9d778a2 100644 --- a/litmus/litmus.c +++ b/litmus/litmus.c | |||
@@ -445,8 +445,8 @@ long __litmus_admit_task(struct task_struct* tsk) | |||
445 | #endif | 445 | #endif |
446 | #ifdef CONFIG_LITMUS_SOFTIRQD | 446 | #ifdef CONFIG_LITMUS_SOFTIRQD |
447 | /* not an interrupt thread by default */ | 447 | /* not an interrupt thread by default */ |
448 | tsk_rt(tsk)->is_interrupt_thread = 0; | 448 | //tsk_rt(tsk)->is_interrupt_thread = 0; |
449 | tsk_rt(tsk)->klmirqd_info = NULL; | 449 | //tsk_rt(tsk)->klmirqd_info = NULL; |
450 | #endif | 450 | #endif |
451 | 451 | ||
452 | retval = litmus->admit_task(tsk); | 452 | retval = litmus->admit_task(tsk); |
@@ -523,11 +523,6 @@ static void synch_on_plugin_switch(void* info) | |||
523 | cpu_relax(); | 523 | cpu_relax(); |
524 | } | 524 | } |
525 | 525 | ||
526 | /* Switching a plugin in use is tricky. | ||
527 | * We must watch out that no real-time tasks exists | ||
528 | * (and that none is created in parallel) and that the plugin is not | ||
529 | * currently in use on any processor (in theory). | ||
530 | */ | ||
531 | int switch_sched_plugin(struct sched_plugin* plugin) | 526 | int switch_sched_plugin(struct sched_plugin* plugin) |
532 | { | 527 | { |
533 | //unsigned long flags; | 528 | //unsigned long flags; |
@@ -535,20 +530,21 @@ int switch_sched_plugin(struct sched_plugin* plugin) | |||
535 | 530 | ||
536 | BUG_ON(!plugin); | 531 | BUG_ON(!plugin); |
537 | 532 | ||
533 | #ifdef CONFIG_LITMUS_SOFTIRQD | ||
534 | if (!klmirqd_is_dead()) { | ||
535 | kill_klmirqd(); | ||
536 | } | ||
537 | #endif | ||
538 | |||
538 | /* forbid other cpus to use the plugin */ | 539 | /* forbid other cpus to use the plugin */ |
539 | atomic_set(&cannot_use_plugin, 1); | 540 | atomic_set(&cannot_use_plugin, 1); |
540 | /* send IPI to force other CPUs to synch with us */ | 541 | /* send IPI to force other CPUs to synch with us */ |
541 | smp_call_function(synch_on_plugin_switch, NULL, 0); | 542 | smp_call_function(synch_on_plugin_switch, NULL, 0); |
542 | 543 | ||
543 | /* wait until all other CPUs have started synch */ | 544 | /* wait until all other CPUs have started synch */ |
544 | while (atomic_read(&cannot_use_plugin) < num_online_cpus()) | 545 | while (atomic_read(&cannot_use_plugin) < num_online_cpus()) { |
545 | cpu_relax(); | 546 | cpu_relax(); |
546 | |||
547 | #ifdef CONFIG_LITMUS_SOFTIRQD | ||
548 | if (!klmirqd_is_dead()) { | ||
549 | kill_klmirqd(); | ||
550 | } | 547 | } |
551 | #endif | ||
552 | 548 | ||
553 | /* stop task transitions */ | 549 | /* stop task transitions */ |
554 | //raw_spin_lock_irqsave(&task_transition_lock, flags); | 550 | //raw_spin_lock_irqsave(&task_transition_lock, flags); |
@@ -571,6 +567,7 @@ int switch_sched_plugin(struct sched_plugin* plugin) | |||
571 | out: | 567 | out: |
572 | //raw_spin_unlock_irqrestore(&task_transition_lock, flags); | 568 | //raw_spin_unlock_irqrestore(&task_transition_lock, flags); |
573 | atomic_set(&cannot_use_plugin, 0); | 569 | atomic_set(&cannot_use_plugin, 0); |
570 | |||
574 | return ret; | 571 | return ret; |
575 | } | 572 | } |
576 | 573 | ||
diff --git a/litmus/litmus_softirq.c b/litmus/litmus_softirq.c index 44e2d38ad982..9c5ecab5e8d9 100644 --- a/litmus/litmus_softirq.c +++ b/litmus/litmus_softirq.c | |||
@@ -79,6 +79,7 @@ void kill_klmirqd(void) | |||
79 | { | 79 | { |
80 | unsigned long flags; | 80 | unsigned long flags; |
81 | struct list_head *pos; | 81 | struct list_head *pos; |
82 | struct list_head *q; | ||
82 | 83 | ||
83 | raw_spin_lock_irqsave(&klmirqd_state.lock, flags); | 84 | raw_spin_lock_irqsave(&klmirqd_state.lock, flags); |
84 | 85 | ||
@@ -86,7 +87,7 @@ void kill_klmirqd(void) | |||
86 | 87 | ||
87 | klmirqd_state.shuttingdown = 1; | 88 | klmirqd_state.shuttingdown = 1; |
88 | 89 | ||
89 | list_for_each(pos, &klmirqd_state.threads) { | 90 | list_for_each_safe(pos, q, &klmirqd_state.threads) { |
90 | struct klmirqd_info* info = list_entry(pos, struct klmirqd_info, klmirqd_reg); | 91 | struct klmirqd_info* info = list_entry(pos, struct klmirqd_info, klmirqd_reg); |
91 | 92 | ||
92 | if(info->terminating != 1) | 93 | if(info->terminating != 1) |
@@ -96,7 +97,9 @@ void kill_klmirqd(void) | |||
96 | flush_pending(info->klmirqd); | 97 | flush_pending(info->klmirqd); |
97 | 98 | ||
98 | /* signal termination */ | 99 | /* signal termination */ |
100 | raw_spin_unlock_irqrestore(&klmirqd_state.lock, flags); | ||
99 | kthread_stop(info->klmirqd); | 101 | kthread_stop(info->klmirqd); |
102 | raw_spin_lock_irqsave(&klmirqd_state.lock, flags); | ||
100 | } | 103 | } |
101 | } | 104 | } |
102 | 105 | ||
@@ -219,7 +222,7 @@ int launch_klmirqd_thread(int cpu, klmirqd_callback_t* cb) | |||
219 | #define KLMIRQD_SLICE_NR_JIFFIES 1 | 222 | #define KLMIRQD_SLICE_NR_JIFFIES 1 |
220 | #define KLMIRQD_SLICE_NS ((NSEC_PER_SEC / HZ) * KLMIRQD_SLICE_NR_JIFFIES) | 223 | #define KLMIRQD_SLICE_NS ((NSEC_PER_SEC / HZ) * KLMIRQD_SLICE_NR_JIFFIES) |
221 | 224 | ||
222 | static int set_litmus_daemon_sched(struct task_struct* tsk) | 225 | static int become_litmus_daemon(struct task_struct* tsk) |
223 | { | 226 | { |
224 | int ret = 0; | 227 | int ret = 0; |
225 | 228 | ||
@@ -249,6 +252,16 @@ static int set_litmus_daemon_sched(struct task_struct* tsk) | |||
249 | return ret; | 252 | return ret; |
250 | } | 253 | } |
251 | 254 | ||
255 | static int become_normal_daemon(struct task_struct* tsk) | ||
256 | { | ||
257 | int ret = 0; | ||
258 | |||
259 | struct sched_param param = { .sched_priority = 0}; | ||
260 | sched_setscheduler_nocheck(tsk, SCHED_NORMAL, ¶m); | ||
261 | |||
262 | return ret; | ||
263 | } | ||
264 | |||
252 | static int register_klmirqd(struct task_struct* tsk) | 265 | static int register_klmirqd(struct task_struct* tsk) |
253 | { | 266 | { |
254 | int retval = 0; | 267 | int retval = 0; |
@@ -318,6 +331,7 @@ static int unregister_klmirqd(struct task_struct* tsk) | |||
318 | 331 | ||
319 | /* remove the entry in the klmirqd thread list */ | 332 | /* remove the entry in the klmirqd thread list */ |
320 | list_del(&info->klmirqd_reg); | 333 | list_del(&info->klmirqd_reg); |
334 | mb(); | ||
321 | --klmirqd_state.nr_threads; | 335 | --klmirqd_state.nr_threads; |
322 | 336 | ||
323 | /* remove link to klmirqd info from thread */ | 337 | /* remove link to klmirqd info from thread */ |
@@ -687,7 +701,7 @@ static int run_klmirqd(void* callback) | |||
687 | struct klmirqd_info* info = NULL; | 701 | struct klmirqd_info* info = NULL; |
688 | klmirqd_callback_t* cb = (klmirqd_callback_t*)(callback); | 702 | klmirqd_callback_t* cb = (klmirqd_callback_t*)(callback); |
689 | 703 | ||
690 | retval = set_litmus_daemon_sched(current); | 704 | retval = become_litmus_daemon(current); |
691 | if (retval != 0) { | 705 | if (retval != 0) { |
692 | TRACE_CUR("%s: Failed to transition to rt-task.\n", __FUNCTION__); | 706 | TRACE_CUR("%s: Failed to transition to rt-task.\n", __FUNCTION__); |
693 | goto failed; | 707 | goto failed; |
@@ -696,7 +710,7 @@ static int run_klmirqd(void* callback) | |||
696 | retval = register_klmirqd(current); | 710 | retval = register_klmirqd(current); |
697 | if (retval != 0) { | 711 | if (retval != 0) { |
698 | TRACE_CUR("%s: Failed to become a klmirqd thread.\n", __FUNCTION__); | 712 | TRACE_CUR("%s: Failed to become a klmirqd thread.\n", __FUNCTION__); |
699 | goto failed; | 713 | goto failed_sched_normal; |
700 | } | 714 | } |
701 | 715 | ||
702 | if (cb && cb->func) { | 716 | if (cb && cb->func) { |
@@ -781,9 +795,10 @@ failed_unregister: | |||
781 | /* remove our registration from klmirqd */ | 795 | /* remove our registration from klmirqd */ |
782 | unregister_klmirqd(current); | 796 | unregister_klmirqd(current); |
783 | 797 | ||
784 | failed: | 798 | failed_sched_normal: |
785 | litmus_exit_task(current); | 799 | become_normal_daemon(current); |
786 | 800 | ||
801 | failed: | ||
787 | return retval; | 802 | return retval; |
788 | } | 803 | } |
789 | 804 | ||
diff --git a/litmus/nvidia_info.c b/litmus/nvidia_info.c index 7883296a7a18..3d38b168d9ba 100644 --- a/litmus/nvidia_info.c +++ b/litmus/nvidia_info.c | |||
@@ -322,7 +322,10 @@ int init_nvidia_info(void) | |||
322 | else | 322 | else |
323 | { | 323 | { |
324 | TRACE("%s : Could not find NVIDIA module! Loaded?\n", __FUNCTION__); | 324 | TRACE("%s : Could not find NVIDIA module! Loaded?\n", __FUNCTION__); |
325 | return(-1); | 325 | |
326 | init_nv_device_reg(); | ||
327 | return(0); | ||
328 | // return(-1); | ||
326 | } | 329 | } |
327 | } | 330 | } |
328 | 331 | ||