From 4ea2c9490eaf9df55ccbfe6f4c56518fc4bdce8f Mon Sep 17 00:00:00 2001 From: Glenn Elliott Date: Thu, 13 Dec 2012 11:44:23 -0500 Subject: Fix klmirqd plugin switching to not panic. --- litmus/Kconfig | 13 ------------- litmus/litmus.c | 23 ++++++++++------------- litmus/litmus_softirq.c | 27 +++++++++++++++++++++------ 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 Should be (<= to the number of CPUs) and (<= to the number of GPUs) in your system. -config NV_MAX_SIMULT_USERS - int "Maximum number of threads sharing a GPU simultanously" - depends on LITMUS_NVIDIA - range 1 3 - default "2" - help - Should be at least equal to the #copy_engines + #execution_engines - of the GPUs in your system. - - Scientific/Professional GPUs = 3 (ex. M2070, Quadro 6000?) - Consumer Fermi/Kepler GPUs = 2 (GTX-4xx thru -6xx) - Older = 1 (ex. GTX-2xx) - choice prompt "CUDA/Driver Version Support" 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) #endif #ifdef CONFIG_LITMUS_SOFTIRQD /* not an interrupt thread by default */ - tsk_rt(tsk)->is_interrupt_thread = 0; - tsk_rt(tsk)->klmirqd_info = NULL; + //tsk_rt(tsk)->is_interrupt_thread = 0; + //tsk_rt(tsk)->klmirqd_info = NULL; #endif retval = litmus->admit_task(tsk); @@ -523,11 +523,6 @@ static void synch_on_plugin_switch(void* info) cpu_relax(); } -/* Switching a plugin in use is tricky. - * We must watch out that no real-time tasks exists - * (and that none is created in parallel) and that the plugin is not - * currently in use on any processor (in theory). - */ int switch_sched_plugin(struct sched_plugin* plugin) { //unsigned long flags; @@ -535,20 +530,21 @@ int switch_sched_plugin(struct sched_plugin* plugin) BUG_ON(!plugin); +#ifdef CONFIG_LITMUS_SOFTIRQD + if (!klmirqd_is_dead()) { + kill_klmirqd(); + } +#endif + /* forbid other cpus to use the plugin */ atomic_set(&cannot_use_plugin, 1); /* send IPI to force other CPUs to synch with us */ smp_call_function(synch_on_plugin_switch, NULL, 0); /* wait until all other CPUs have started synch */ - while (atomic_read(&cannot_use_plugin) < num_online_cpus()) + while (atomic_read(&cannot_use_plugin) < num_online_cpus()) { cpu_relax(); - -#ifdef CONFIG_LITMUS_SOFTIRQD - if (!klmirqd_is_dead()) { - kill_klmirqd(); } -#endif /* stop task transitions */ //raw_spin_lock_irqsave(&task_transition_lock, flags); @@ -571,6 +567,7 @@ int switch_sched_plugin(struct sched_plugin* plugin) out: //raw_spin_unlock_irqrestore(&task_transition_lock, flags); atomic_set(&cannot_use_plugin, 0); + return ret; } 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) { unsigned long flags; struct list_head *pos; + struct list_head *q; raw_spin_lock_irqsave(&klmirqd_state.lock, flags); @@ -86,7 +87,7 @@ void kill_klmirqd(void) klmirqd_state.shuttingdown = 1; - list_for_each(pos, &klmirqd_state.threads) { + list_for_each_safe(pos, q, &klmirqd_state.threads) { struct klmirqd_info* info = list_entry(pos, struct klmirqd_info, klmirqd_reg); if(info->terminating != 1) @@ -96,7 +97,9 @@ void kill_klmirqd(void) flush_pending(info->klmirqd); /* signal termination */ + raw_spin_unlock_irqrestore(&klmirqd_state.lock, flags); kthread_stop(info->klmirqd); + raw_spin_lock_irqsave(&klmirqd_state.lock, flags); } } @@ -219,7 +222,7 @@ int launch_klmirqd_thread(int cpu, klmirqd_callback_t* cb) #define KLMIRQD_SLICE_NR_JIFFIES 1 #define KLMIRQD_SLICE_NS ((NSEC_PER_SEC / HZ) * KLMIRQD_SLICE_NR_JIFFIES) -static int set_litmus_daemon_sched(struct task_struct* tsk) +static int become_litmus_daemon(struct task_struct* tsk) { int ret = 0; @@ -249,6 +252,16 @@ static int set_litmus_daemon_sched(struct task_struct* tsk) return ret; } +static int become_normal_daemon(struct task_struct* tsk) +{ + int ret = 0; + + struct sched_param param = { .sched_priority = 0}; + sched_setscheduler_nocheck(tsk, SCHED_NORMAL, ¶m); + + return ret; +} + static int register_klmirqd(struct task_struct* tsk) { int retval = 0; @@ -318,6 +331,7 @@ static int unregister_klmirqd(struct task_struct* tsk) /* remove the entry in the klmirqd thread list */ list_del(&info->klmirqd_reg); + mb(); --klmirqd_state.nr_threads; /* remove link to klmirqd info from thread */ @@ -687,7 +701,7 @@ static int run_klmirqd(void* callback) struct klmirqd_info* info = NULL; klmirqd_callback_t* cb = (klmirqd_callback_t*)(callback); - retval = set_litmus_daemon_sched(current); + retval = become_litmus_daemon(current); if (retval != 0) { TRACE_CUR("%s: Failed to transition to rt-task.\n", __FUNCTION__); goto failed; @@ -696,7 +710,7 @@ static int run_klmirqd(void* callback) retval = register_klmirqd(current); if (retval != 0) { TRACE_CUR("%s: Failed to become a klmirqd thread.\n", __FUNCTION__); - goto failed; + goto failed_sched_normal; } if (cb && cb->func) { @@ -781,9 +795,10 @@ failed_unregister: /* remove our registration from klmirqd */ unregister_klmirqd(current); -failed: - litmus_exit_task(current); +failed_sched_normal: + become_normal_daemon(current); +failed: return retval; } 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) else { TRACE("%s : Could not find NVIDIA module! Loaded?\n", __FUNCTION__); - return(-1); + + init_nv_device_reg(); + return(0); +// return(-1); } } -- cgit v1.2.2