From fa1229f9776c7ecc99baa187e0b485ebdbfdd78c Mon Sep 17 00:00:00 2001 From: Glenn Elliott Date: Thu, 13 Dec 2012 18:39:27 -0500 Subject: Allow klmirqd threads to be given names. --- include/litmus/litmus_softirq.h | 7 +++- litmus/Kconfig | 3 +- litmus/litmus.c | 12 +++--- litmus/litmus_softirq.c | 84 +++++++++++++++++++++++++++++------------ litmus/nvidia_info.c | 5 ++- 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 data will be initialized. cpu == -1 for no affinity + + provide a name at most 31 (32, + null terminator) characters long. + name == NULL for a default name. (all names are appended with + base-CPU affinity) */ -int launch_klmirqd_thread(int cpu, klmirqd_callback_t* cb); +#define MAX_KLMIRQD_NAME_LEN 31 +int launch_klmirqd_thread(char* name, int cpu, klmirqd_callback_t* cb); /* 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 default n help Causes tasklets to be sporadically dispatched to waiting klmirqd - threads. + threads. WARNING! Kernel panic may occur if you switch between + LITMUS plugins! endmenu 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) ret = litmus->deactivate_plugin(); if (0 != ret) goto out; - ret = plugin->activate_plugin(); + + litmus = plugin; // switch + mb(); // make sure it's seen everywhere. + ret = litmus->activate_plugin(); if (0 != ret) { printk(KERN_INFO "Can't activate %s (%d).\n", - plugin->plugin_name, ret); - plugin = &linux_sched_plugin; + litmus->plugin_name, ret); + litmus = &linux_sched_plugin; } - printk(KERN_INFO "Switching to LITMUS^RT plugin %s.\n", plugin->plugin_name); - litmus = plugin; + printk(KERN_INFO "Switching to LITMUS^RT plugin %s.\n", litmus->plugin_name); } else ret = -EBUSY; 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 struct list_head threads; }; -static atomic_t klmirqd_id_gen = ATOMIC_INIT(0); +static atomic_t klmirqd_id_gen = ATOMIC_INIT(-1); static struct klmirqd_registration klmirqd_state; @@ -136,12 +136,11 @@ void kill_klmirqd_thread(struct task_struct* klmirqd_thread) raw_spin_unlock_irqrestore(&klmirqd_state.lock, flags); } - - struct klmirqd_launch_data { int cpu_affinity; klmirqd_callback_t* cb; + char name[MAX_KLMIRQD_NAME_LEN+1]; struct work_struct work; }; @@ -156,47 +155,76 @@ static void __launch_klmirqd_thread(struct work_struct *work) struct klmirqd_launch_data* launch_data = container_of(work, struct klmirqd_launch_data, work); - TRACE("%s: Creating klmirqd thread\n", __FUNCTION__); + TRACE("Creating klmirqd thread\n"); + - id = atomic_inc_return(&klmirqd_id_gen); if (launch_data->cpu_affinity != -1) { - thread = kthread_create( - run_klmirqd, - /* treat the affinity as a pointer, we'll cast it back later */ - (void*)launch_data->cb, - "klmirqd_th%d/%d", - id, - launch_data->cpu_affinity); + if (launch_data->name[0] == '\0') { + id = atomic_inc_return(&klmirqd_id_gen); + TRACE("Launching klmirqd_th%d/%d\n", id, launch_data->cpu_affinity); + + thread = kthread_create( + run_klmirqd, + /* treat the affinity as a pointer, we'll cast it back later */ + (void*)launch_data->cb, + "klmirqd_th%d/%d", + id, + launch_data->cpu_affinity); + } + else { + TRACE("Launching %s/%d\n", launch_data->name, launch_data->cpu_affinity); + + thread = kthread_create( + run_klmirqd, + /* treat the affinity as a pointer, we'll cast it back later */ + (void*)launch_data->cb, + "%s/%d", + launch_data->name, + launch_data->cpu_affinity); + } /* litmus will put is in the right cluster. */ kthread_bind(thread, launch_data->cpu_affinity); - - TRACE("%s: Launching klmirqd_th%d/%d\n", __FUNCTION__, id, launch_data->cpu_affinity); } else { - thread = kthread_create( - run_klmirqd, - /* treat the affinity as a pointer, we'll cast it back later */ - (void*)launch_data->cb, - "klmirqd_th%d", - id); - - TRACE("%s: Launching klmirqd_th%d\n", __FUNCTION__, id); + if (launch_data->name[0] == '\0') { + id = atomic_inc_return(&klmirqd_id_gen); + TRACE("Launching klmirqd_th%d\n", id); + + thread = kthread_create( + run_klmirqd, + /* treat the affinity as a pointer, we'll cast it back later */ + (void*)launch_data->cb, + "klmirqd_th%d", + id); + + } + else { + TRACE("Launching %s\n", launch_data->name); + + thread = kthread_create( + run_klmirqd, + /* treat the affinity as a pointer, we'll cast it back later */ + (void*)launch_data->cb, + launch_data->name); + } + + } if (thread) { wake_up_process(thread); } else { - TRACE("Could not create klmirqd/%d thread!\n", id); + TRACE("Could not create thread!\n"); } kfree(launch_data); } -int launch_klmirqd_thread(int cpu, klmirqd_callback_t* cb) +int launch_klmirqd_thread(char* name, int cpu, klmirqd_callback_t* cb) { struct klmirqd_launch_data* delayed_launch; @@ -211,6 +239,14 @@ int launch_klmirqd_thread(int cpu, klmirqd_callback_t* cb) delayed_launch->cpu_affinity = cpu; delayed_launch->cb = cb; INIT_WORK(&delayed_launch->work, __launch_klmirqd_thread); + + if(name) { + snprintf(delayed_launch->name, MAX_KLMIRQD_NAME_LEN+1, "%s", name); + } + else { + delayed_launch->name[0] = '\0'; + } + schedule_work(&delayed_launch->work); 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, static int init_nv_device_reg(void) { int i; + char name[MAX_KLMIRQD_NAME_LEN+1]; #ifdef CONFIG_LITMUS_SOFTIRQD if (!klmirqd_is_ready()) { @@ -520,11 +521,13 @@ static int init_nv_device_reg(void) { int default_cpu = litmus->map_gpu_to_cpu(i); + snprintf(name, MAX_KLMIRQD_NAME_LEN, "nvklmirqd%d", i); + NV_DEVICE_REG[i].callback.func = nvidia_klmirqd_cb; NV_DEVICE_REG[i].callback.arg = (void*)(long long)(i); mb(); - if(launch_klmirqd_thread(default_cpu, &NV_DEVICE_REG[i].callback) != 0) { + if(launch_klmirqd_thread(name, default_cpu, &NV_DEVICE_REG[i].callback) != 0) { TRACE("Failed to create klmirqd thread for GPU %d\n", i); } } 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: #if defined(CONFIG_LITMUS_NVIDIA) && defined(CONFIG_LITMUS_SOFTIRQD) static int gsnedf_map_gpu_to_cpu(int gpu) { - return 0; // CPU_0 is default in all cases. + return -1; // No CPU affinity needed. } #endif -- cgit v1.2.2