From cc9f46d0ce73ae30e3918999976ef587b0e8a04d Mon Sep 17 00:00:00 2001 From: Glenn Elliott Date: Fri, 18 Jan 2013 11:13:07 -0500 Subject: /proc hooks for locking protocols. RSM locks only make use of /proc for now. --- include/litmus/litmus_proc.h | 7 ++ include/litmus/locking.h | 17 ++++ include/litmus/rsm_lock.h | 3 +- litmus/ikglp_lock.c | 3 +- litmus/kfmlp_lock.c | 1 + litmus/litmus_proc.c | 39 ++++++++ litmus/locking.c | 93 ++++++++++++++---- litmus/nvidia_info.c | 18 ---- litmus/rsm_lock.c | 222 ++++++++++++++++++++++++++++++++++++------- litmus/sched_cedf.c | 6 +- litmus/sched_gsn_edf.c | 1 + litmus/sched_pfp.c | 4 + litmus/srp.c | 1 + 13 files changed, 339 insertions(+), 76 deletions(-) diff --git a/include/litmus/litmus_proc.h b/include/litmus/litmus_proc.h index 6800e725d48c..0c5c07ea0ef5 100644 --- a/include/litmus/litmus_proc.h +++ b/include/litmus/litmus_proc.h @@ -23,3 +23,10 @@ void remove_plugin_proc_dir(struct sched_plugin* plugin); * -EFAULT. */ int copy_and_chomp(char *kbuf, unsigned long ksize, __user const char* ubuf, unsigned long ulength); + + +#ifdef CONFIG_LITMUS_LOCKING +struct proc_dir_entry* litmus_add_proc_lock(struct litmus_lock *l, read_proc_t func); +void litmus_remove_proc_lock(struct litmus_lock* l); +#endif + diff --git a/include/litmus/locking.h b/include/litmus/locking.h index 4a5f198a0407..22f7372bf621 100644 --- a/include/litmus/locking.h +++ b/include/litmus/locking.h @@ -24,6 +24,11 @@ static inline struct task_struct* top_priority(struct binheap* handle) { void print_hp_waiters(struct binheap_node* n, int depth); #endif +#define LOCK_NAME_LEN 16 +struct litmus_lock_proc_ops { + void (*add)(struct litmus_lock *l); + void (*remove)(struct litmus_lock *l); +}; /* Generic base struct for LITMUS^RT userspace semaphores. * This structure should be embedded in protocol-specific semaphores. @@ -41,6 +46,10 @@ struct litmus_lock { struct lock_class_key key; //#endif #endif + + struct litmus_lock_proc_ops *proc; + struct proc_dir_entry *proc_entry; + char name[LOCK_NAME_LEN]; }; #ifdef CONFIG_LITMUS_DGL_SUPPORT @@ -131,12 +140,16 @@ struct litmus_lock_ops { /* DGL requires a big lock to implement nested inheritance */ #define lock_global_irqsave(lock, flags) raw_spin_lock_irqsave((lock), (flags)) #define lock_global(lock) raw_spin_lock((lock)) +#define trylock_global_irqsave(lock, flags) raw_spin_trylock_irqsave((lock), (flags)) +#define trylock_global(lock) raw_spin_trylock((lock)) #define unlock_global_irqrestore(lock, flags) raw_spin_unlock_irqrestore((lock), (flags)) #define unlock_global(lock) raw_spin_unlock((lock)) /* fine-grain locking are no-ops with DGL support */ #define lock_fine_irqsave(lock, flags) #define lock_fine(lock) +#define trylock_fine_irqsave(lock, flags) +#define trylock_fine(lock) #define unlock_fine_irqrestore(lock, flags) #define unlock_fine(lock) @@ -145,11 +158,15 @@ struct litmus_lock_ops { /* global locking are no-ops without DGL support */ #define lock_global_irqsave(lock, flags) #define lock_global(lock) +#define trylock_global_irqsave(lock, flags) +#define trylock_global(lock) #define unlock_global_irqrestore(lock, flags) #define unlock_global(lock) #define lock_fine_irqsave(lock, flags) raw_spin_lock_irqsave((lock), (flags)) #define lock_fine(lock) raw_spin_lock((lock)) +#define trylock_fine_irqsave(lock, flags) raw_spin_trylock_irqsave((lock), (flags)) +#define trylock_fine(lock) raw_spin_trylock((lock)) #define unlock_fine_irqrestore(lock, flags) raw_spin_unlock_irqrestore((lock), (flags)) #define unlock_fine(lock) raw_spin_unlock((lock)) diff --git a/include/litmus/rsm_lock.h b/include/litmus/rsm_lock.h index a15189683de4..f0d263322a69 100644 --- a/include/litmus/rsm_lock.h +++ b/include/litmus/rsm_lock.h @@ -51,4 +51,5 @@ void rsm_mutex_free(struct litmus_lock* l); struct litmus_lock* rsm_mutex_new(struct litmus_lock_ops*); -#endif \ No newline at end of file +#endif + diff --git a/litmus/ikglp_lock.c b/litmus/ikglp_lock.c index a4ae74331782..aa6b659e437d 100644 --- a/litmus/ikglp_lock.c +++ b/litmus/ikglp_lock.c @@ -1768,6 +1768,7 @@ struct litmus_lock* ikglp_new(int m, { return NULL; } + memset(sem, 0, sizeof(*sem)); sem->fifo_queues = kmalloc(sizeof(struct fifo_queue)*nr_replicas, GFP_KERNEL); if(!sem->fifo_queues) @@ -2484,7 +2485,7 @@ ikglp_donee_heap_node_t* gpu_ikglp_advise_donee_selection( if(temp_distance < distance || donee_node == NULL) { int dist_from_head = IKGLP_INVAL_DISTANCE; - TRACE_CUR("searching for donor on GPU %d", i); + TRACE_CUR("searching for donor on GPU %d\n", i); // visit each queue and pick a donee. bail as soon as we find // one for this class. diff --git a/litmus/kfmlp_lock.c b/litmus/kfmlp_lock.c index 785a095275e6..377e5a8f7456 100644 --- a/litmus/kfmlp_lock.c +++ b/litmus/kfmlp_lock.c @@ -486,6 +486,7 @@ struct litmus_lock* kfmlp_new(struct litmus_lock_ops* ops, void* __user args) { return(NULL); } + memset(sem, 0, sizeof(*sem)); sem->queues = kmalloc(sizeof(struct kfmlp_queue)*num_resources, GFP_KERNEL); if(!sem->queues) diff --git a/litmus/litmus_proc.c b/litmus/litmus_proc.c index 136fecfb0b8b..be62d04da376 100644 --- a/litmus/litmus_proc.c +++ b/litmus/litmus_proc.c @@ -10,6 +10,10 @@ #include +#ifdef CONFIG_LITMUS_LOCKING +#include +#endif + /* in litmus/litmus.c */ extern atomic_t rt_task_count; @@ -22,6 +26,9 @@ static struct proc_dir_entry *litmus_dir = NULL, #endif #ifdef CONFIG_LITMUS_SOFTIRQD *klmirqd_file = NULL, +#endif +#ifdef CONFIG_LITMUS_LOCKING + *locks_dir = NULL, #endif *plugs_file = NULL; @@ -187,6 +194,15 @@ int __init init_litmus_proc(void) plugs_file = create_proc_read_entry("loaded", 0444, plugs_dir, proc_read_plugins, NULL); +#ifdef CONFIG_LITMUS_LOCKING + locks_dir = proc_mkdir("locks", litmus_dir); + if (!locks_dir) { + printk(KERN_ERR "Could not allocate locks directory " + "procfs entry.\n"); + return -ENOMEM; + } +#endif + return 0; } @@ -196,6 +212,8 @@ void exit_litmus_proc(void) remove_proc_entry("loaded", plugs_dir); if (plugs_dir) remove_proc_entry("plugins", litmus_dir); + if (locks_dir) + remove_proc_entry("locks", litmus_dir); if (stat_file) remove_proc_entry("stats", litmus_dir); if (curr_file) @@ -362,3 +380,24 @@ struct proc_dir_entry* create_cluster_file(struct proc_dir_entry* parent, return cluster_file; } +#ifdef CONFIG_LITMUS_LOCKING +struct proc_dir_entry* litmus_add_proc_lock(struct litmus_lock* l, read_proc_t func) +{ + struct proc_dir_entry* entry = NULL; + + if (locks_dir) + entry = create_proc_read_entry(l->name, 0444, locks_dir, func, l); + + return entry; +} + +void litmus_remove_proc_lock(struct litmus_lock* l) +{ + if (locks_dir) + remove_proc_entry(l->name, locks_dir); +} +#endif + + + + diff --git a/litmus/locking.c b/litmus/locking.c index c21ec1ae36d7..b7f02f0e6b24 100644 --- a/litmus/locking.c +++ b/litmus/locking.c @@ -28,7 +28,7 @@ struct fdso_ops generic_lock_ops = { .create = create_generic_lock, .open = open_generic_lock, .close = close_generic_lock, - .destroy = destroy_generic_lock + .destroy = destroy_generic_lock, }; static atomic_t lock_id_gen = ATOMIC_INIT(0); @@ -59,12 +59,18 @@ static int create_generic_lock(void** obj_ref, obj_type_t type, void* __user ar INIT_BINHEAP_NODE(&lock->nest.hp_binheap_node); if(!lock->nest.hp_waiter_ptr) { TRACE_CUR("BEWARE: hp_waiter_ptr should probably not be NULL in " - "most uses. (exception: IKGLP donors)\n"); + "most cases. (exception: IKGLP donors)\n"); } #endif lock->type = type; lock->ident = atomic_inc_return(&lock_id_gen); *obj_ref = lock; + + TRACE_CUR("Lock %d created. Type = %d\n.", lock->ident, type); + + if (lock->proc && lock->proc->add) { + lock->proc->add(lock); + } } return err; } @@ -81,8 +87,14 @@ static int open_generic_lock(struct od_table_entry* entry, void* __user arg) static int close_generic_lock(struct od_table_entry* entry) { struct litmus_lock* lock = get_lock(entry); - if (lock->ops->close) + if (lock->ops->close) { + + if (lock->proc && lock->proc->remove) { + lock->proc->remove(lock); + } + return lock->ops->close(lock); + } else return 0; /* default: closing succeeds */ } @@ -109,8 +121,11 @@ asmlinkage long sys_litmus_lock(int lock_od) if (entry && is_lock(entry)) { l = get_lock(entry); //TRACE_CUR("attempts to lock 0x%p\n", l); - TRACE_CUR("attempts to lock %d\n", l->ident); + TRACE_CUR("Attempts to lock %d\n", l->ident); err = l->ops->lock(l); + if (!err) { + TRACE_CUR("Got lock %d\n", l->ident); + } } /* Note: task my have been suspended or preempted in between! Take @@ -138,8 +153,11 @@ asmlinkage long sys_litmus_unlock(int lock_od) if (entry && is_lock(entry)) { l = get_lock(entry); //TRACE_CUR("attempts to unlock 0x%p\n", l); - TRACE_CUR("attempts to unlock %d\n", l->ident); + TRACE_CUR("Attempts to unlock %d\n", l->ident); err = l->ops->unlock(l); + if (!err) { + TRACE_CUR("Unlocked %d\n", l->ident); + } } /* Note: task my have been preempted in between! Take this into @@ -285,22 +303,50 @@ void init_dgl_waitqueue_entry(wait_queue_t *wq_node, dgl_wait_state_t* dgl_wait) wq_node->func = dgl_wake_up; } +#ifdef CONFIG_SCHED_DEBUG_TRACE +static void snprintf_dgl(char* buf, size_t bsz, struct litmus_lock* dgl_locks[], int sz) +{ + int i; + char* ptr; + + ptr = buf; + for(i = 0; i < sz && ptr < buf+bsz; ++i) + { + struct litmus_lock *l = dgl_locks[i]; + int remaining = bsz - (ptr-buf); + int written; + + if(i == 0) + written = snprintf(ptr, remaining, "%d ", l->ident); + else if(i == sz - 1) + written = snprintf(ptr, remaining, " %d", l->ident); + else + written = snprintf(ptr, remaining, " %d ", l->ident); + ptr += written; + } +} +#endif static long do_litmus_dgl_lock(dgl_wait_state_t *dgl_wait) { int i; unsigned long irqflags; //, dummyflags; - raw_spinlock_t *dgl_lock = litmus->get_dgl_spinlock(dgl_wait->task); + raw_spinlock_t *dgl_lock; + +#ifdef CONFIG_SCHED_DEBUG_TRACE + char dglstr[CONFIG_LITMUS_MAX_DGL_SIZE*5]; + snprintf_dgl(dglstr, sizeof(dglstr), dgl_wait->locks, dgl_wait->size); + TRACE_CUR("Locking DGL with size %d: %s\n", dgl_wait->size, dglstr); +#endif + + dgl_lock = litmus->get_dgl_spinlock(dgl_wait->task); BUG_ON(dgl_wait->task != current); raw_spin_lock_irqsave(dgl_lock, irqflags); - dgl_wait->nr_remaining = dgl_wait->size; - TRACE_CUR("Locking DGL with size %d\n", dgl_wait->size); - // try to acquire each lock. enqueue (non-blocking) if it is unavailable. for(i = 0; i < dgl_wait->size; ++i) { struct litmus_lock *l = dgl_wait->locks[i]; @@ -347,7 +393,8 @@ static long do_litmus_dgl_lock(dgl_wait_state_t *dgl_wait) raw_spin_unlock_irqrestore(dgl_lock, irqflags); // free dgl_lock before suspending - schedule(); // suspend!!! + suspend_for_lock(); // suspend!!! + //schedule(); // suspend!!! TS_DGL_LOCK_RESUME; @@ -443,7 +490,11 @@ static long do_litmus_dgl_unlock(struct litmus_lock* dgl_locks[], int dgl_size) int i; long err = 0; - TRACE_CUR("Unlocking a DGL of %d size\n", dgl_size); +#ifdef CONFIG_SCHED_DEBUG_TRACE + char dglstr[CONFIG_LITMUS_MAX_DGL_SIZE*5]; + snprintf_dgl(dglstr, sizeof(dglstr), dgl_locks, dgl_size); + TRACE_CUR("Unlocking a DGL with size %d: %s\n", dgl_size, dglstr); +#endif for(i = dgl_size - 1; i >= 0; --i) { // unlock in reverse order @@ -573,16 +624,16 @@ void suspend_for_lock(void) unsigned int gpu_hide; #endif -//#ifdef CONFIG_REALTIME_AUX_TASKS -// if (tsk_rt(t)->has_aux_tasks) { -// /* hide from aux tasks so they can't inherit our priority when we block -// * for a litmus lock. inheritance is already going to a litmus lock -// * holder. */ -// aux_hide = tsk_rt(t)->hide_from_aux_tasks; -// aux_restore = 1; -// tsk_rt(t)->hide_from_aux_tasks = 1; -// } -//#endif +#ifdef CONFIG_REALTIME_AUX_TASKS + if (tsk_rt(t)->has_aux_tasks) { + /* hide from aux tasks so they can't inherit our priority when we block + * for a litmus lock. inheritance is already going to a litmus lock + * holder. */ + aux_hide = tsk_rt(t)->hide_from_aux_tasks; + aux_restore = 1; + tsk_rt(t)->hide_from_aux_tasks = 1; + } +#endif #ifdef CONFIG_LITMUS_NVIDIA if (tsk_rt(t)->held_gpus) { diff --git a/litmus/nvidia_info.c b/litmus/nvidia_info.c index ae4ad446408b..be0c09b19c6d 100644 --- a/litmus/nvidia_info.c +++ b/litmus/nvidia_info.c @@ -320,7 +320,6 @@ int init_nvidia_info(void) init_nv_device_reg(); return(0); -// return(-1); } } @@ -650,7 +649,6 @@ static int gpu_klmirqd_decrease_priority(struct task_struct *klmirqd, struct tas long enable_gpu_owner(struct task_struct *t) { long retval = 0; -// unsigned long flags; int gpu; nv_device_registry_t *reg; @@ -675,8 +673,6 @@ long enable_gpu_owner(struct task_struct *t) /* update the registration (and maybe klmirqd) */ reg = &NV_DEVICE_REG[gpu]; -// raw_spin_lock_irqsave(®->lock, flags); - binheap_add(&tsk_rt(t)->gpu_owner_node, ®->owners, struct rt_param, gpu_owner_node); @@ -693,8 +689,6 @@ long enable_gpu_owner(struct task_struct *t) } #endif -// raw_spin_unlock_irqsave(®->lock, flags); - out: return retval; } @@ -703,7 +697,6 @@ out: long disable_gpu_owner(struct task_struct *t) { long retval = 0; -// unsigned long flags; int gpu; nv_device_registry_t *reg; @@ -731,9 +724,6 @@ long disable_gpu_owner(struct task_struct *t) reg = &NV_DEVICE_REG[gpu]; -// raw_spin_lock_irqsave(®->lock, flags); - - #ifdef CONFIG_LITMUS_SOFTIRQD hp = container_of(binheap_top_entry(®->owners, struct rt_param, gpu_owner_node), struct task_struct, rt_param); @@ -761,9 +751,6 @@ long disable_gpu_owner(struct task_struct *t) binheap_delete(&tsk_rt(t)->gpu_owner_node, ®->owners); #endif -// raw_spin_unlock_irqsave(®->lock, flags); - - out: return retval; } @@ -792,15 +779,11 @@ int gpu_owner_increase_priority(struct task_struct *t) gpu = find_first_bit(&tsk_rt(t)->held_gpus, sizeof(tsk_rt(t)->held_gpus)); if (!binheap_is_in_heap(&tsk_rt(t)->gpu_owner_node)) { - WARN_ON(!is_running(t) && !tsk_rt(t)->hide_from_gpu); TRACE_CUR("nv klmirqd may not inherit from %s/%d on GPU %d\n", t->comm, t->pid, gpu); goto out; } - - - TRACE_CUR("task %s/%d on GPU %d increasing priority.\n", t->comm, t->pid, gpu); reg = &NV_DEVICE_REG[gpu]; @@ -842,7 +825,6 @@ int gpu_owner_decrease_priority(struct task_struct *t) gpu = find_first_bit(&tsk_rt(t)->held_gpus, sizeof(tsk_rt(t)->held_gpus)); if (!binheap_is_in_heap(&tsk_rt(t)->gpu_owner_node)) { - WARN_ON(!is_running(t) && !tsk_rt(t)->hide_from_gpu); TRACE_CUR("nv klmirqd may not inherit from %s/%d on GPU %d\n", t->comm, t->pid, gpu); goto out; diff --git a/litmus/rsm_lock.c b/litmus/rsm_lock.c index 3dfd8ae9d221..ae6dd3fb237b 100644 --- a/litmus/rsm_lock.c +++ b/litmus/rsm_lock.c @@ -5,6 +5,8 @@ #include #include +#include + //#include #if defined(CONFIG_LITMUS_AFFINITY_LOCKING) && defined(CONFIG_LITMUS_NVIDIA) @@ -14,43 +16,43 @@ /* caller is responsible for locking */ static struct task_struct* rsm_mutex_find_hp_waiter(struct rsm_mutex *mutex, - struct task_struct* skip) + struct task_struct* skip) { - wait_queue_t *q; - struct list_head *pos; - struct task_struct *queued = NULL, *found = NULL; + wait_queue_t *q; + struct list_head *pos; + struct task_struct *queued = NULL, *found = NULL; #ifdef CONFIG_LITMUS_DGL_SUPPORT - dgl_wait_state_t *dgl_wait = NULL; + dgl_wait_state_t *dgl_wait = NULL; #endif - list_for_each(pos, &mutex->wait.task_list) { - q = list_entry(pos, wait_queue_t, task_list); + list_for_each(pos, &mutex->wait.task_list) { + q = list_entry(pos, wait_queue_t, task_list); #ifdef CONFIG_LITMUS_DGL_SUPPORT - if(q->func == dgl_wake_up) { - dgl_wait = (dgl_wait_state_t*) q->private; - if(tsk_rt(dgl_wait->task)->blocked_lock == &mutex->litmus_lock) { - queued = dgl_wait->task; - } - else { - queued = NULL; // skip it. - } - } - else { - queued = (struct task_struct*) q->private; - } + if(q->func == dgl_wake_up) { + dgl_wait = (dgl_wait_state_t*) q->private; + if(tsk_rt(dgl_wait->task)->blocked_lock == &mutex->litmus_lock) { + queued = dgl_wait->task; + } + else { + queued = NULL; // skip it. + } + } + else { + queued = (struct task_struct*) q->private; + } #else - queued = (struct task_struct*) q->private; + queued = (struct task_struct*) q->private; #endif - /* Compare task prios, find high prio task. */ - //if (queued && queued != skip && edf_higher_prio(queued, found)) { + /* Compare task prios, find high prio task. */ + //if (queued && queued != skip && edf_higher_prio(queued, found)) { if (queued && queued != skip && litmus->compare(queued, found)) { - found = queued; - } - } - return found; + found = queued; + } + } + return found; } @@ -76,7 +78,8 @@ int rsm_mutex_dgl_lock(struct litmus_lock *l, dgl_wait_state_t* dgl_wait, BUG_ON(t != current); if (mutex->owner) { - TRACE_TASK(t, "Enqueuing on lock %d.\n", l->ident); + TRACE_TASK(t, "Enqueuing on lock %d (held by %s/%d).\n", + l->ident, mutex->owner->comm, mutex->owner->pid); init_dgl_waitqueue_entry(wq_node, dgl_wait); @@ -205,7 +208,8 @@ int rsm_mutex_lock(struct litmus_lock* l) lock_fine_irqsave(&mutex->lock, flags); if (mutex->owner) { - TRACE_TASK(t, "Blocking on lock %d.\n", l->ident); + TRACE_TASK(t, "Blocking on lock %d (held by %s/%d).\n", + l->ident, mutex->owner->comm, mutex->owner->pid); #if defined(CONFIG_LITMUS_AFFINITY_LOCKING) && defined(CONFIG_LITMUS_NVIDIA) // KLUDGE: don't count this suspension as time in the critical gpu @@ -358,7 +362,7 @@ int rsm_mutex_unlock(struct litmus_lock* l) top_priority(&tsk_rt(t)->hp_blocked_tasks); if((new_max_eff_prio == NULL) || - /* there was a change in eff prio */ + /* there was a change in eff prio */ ( (new_max_eff_prio != old_max_eff_prio) && /* and owner had the old eff prio */ (effective_priority(t) == old_max_eff_prio)) ) @@ -402,7 +406,7 @@ int rsm_mutex_unlock(struct litmus_lock* l) if (next) { /* next becomes the resouce holder */ mutex->owner = next; - TRACE_CUR("lock ownership passed to %s/%d\n", next->comm, next->pid); + TRACE_CUR("lock %d ownership passed to %s/%d\n", l->ident, next->comm, next->pid); /* determine new hp_waiter if necessary */ if (next == mutex->hp_waiter) { @@ -459,7 +463,7 @@ int rsm_mutex_unlock(struct litmus_lock* l) #endif /* It is possible that 'next' *should* be the hp_waiter, but isn't - * because that update hasn't yet executed (update operation is + * because that update hasn't yet executed (update operation is * probably blocked on mutex->lock). So only inherit if the top of * 'next's top heap node is indeed the effective prio. of hp_waiter. * (We use l->hp_waiter_eff_prio instead of effective_priority(hp_waiter) @@ -693,7 +697,7 @@ void rsm_mutex_propagate_decrease_inheritance(struct litmus_lock* l, } // beware: recursion - litmus->nested_decrease_prio(owner, decreased_prio, &mutex->lock, irqflags); // will unlock mutex->lock + litmus->nested_decrease_prio(owner, decreased_prio, &mutex->lock, irqflags); // will unlock mutex->lock } else { raw_spin_unlock(&tsk_rt(owner)->hp_blocked_tasks_lock); @@ -754,8 +758,11 @@ int rsm_mutex_close(struct litmus_lock* l) unlock_fine_irqrestore(&mutex->lock, flags); unlock_global_irqrestore(dgl_lock, flags); + /* + TODO: Currently panic. FIX THIS! if (owner) rsm_mutex_unlock(l); + */ return 0; } @@ -765,6 +772,154 @@ void rsm_mutex_free(struct litmus_lock* lock) kfree(rsm_mutex_from_lock(lock)); } + +/* The following may race if DGLs are enabled. Only examine /proc if things + appear to be locked up. TODO: FIX THIS! Must find an elegant way to transmit + DGL lock to function. */ +static int rsm_proc_print(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + struct rsm_mutex *mutex = rsm_mutex_from_lock((struct litmus_lock*)data); + + int attempts = 0; + const int max_attempts = 10; + int locked = 0; + unsigned long flags; + + int size = count; + char *next = page; + int w; + + while(attempts < max_attempts) + { + locked = raw_spin_trylock_irqsave(&mutex->lock, flags); + + if (unlikely(!locked)) { + ++attempts; + cpu_relax(); + } + else { + break; + } + } + + if (locked) { + w = scnprintf(next, size, "%s:\n", mutex->litmus_lock.name); + size -= w; + next += w; + + w = scnprintf(next, size, + "owner: %s/%d (inh: %s/%d)\n", + (mutex->owner) ? + mutex->owner->comm : "nil", + (mutex->owner) ? + mutex->owner->pid : -1, + (mutex->owner && tsk_rt(mutex->owner)->inh_task) ? + tsk_rt(mutex->owner)->inh_task->comm : "nil", + (mutex->owner && tsk_rt(mutex->owner)->inh_task) ? + tsk_rt(mutex->owner)->inh_task->pid : -1); + size -= w; + next += w; + + w = scnprintf(next, size, + "hp waiter: %s/%d (inh: %s/%d)\n", + (mutex->hp_waiter) ? + mutex->hp_waiter->comm : "nil", + (mutex->hp_waiter) ? + mutex->hp_waiter->pid : -1, + (mutex->hp_waiter && tsk_rt(mutex->hp_waiter)->inh_task) ? + tsk_rt(mutex->hp_waiter)->inh_task->comm : "nil", + (mutex->hp_waiter && tsk_rt(mutex->hp_waiter)->inh_task) ? + tsk_rt(mutex->hp_waiter)->inh_task->pid : -1); + size -= w; + next += w; + + w = scnprintf(next, size, "\nblocked tasks, front to back:\n"); + size -= w; + next += w; + + if (waitqueue_active(&mutex->wait)) { + wait_queue_t *q; + struct list_head *pos; +#ifdef CONFIG_LITMUS_DGL_SUPPORT + dgl_wait_state_t *dgl_wait = NULL; +#endif + list_for_each(pos, &mutex->wait.task_list) { + struct task_struct *blocked_task; +#ifdef CONFIG_LITMUS_DGL_SUPPORT + int enabled = 1; +#endif + q = list_entry(pos, wait_queue_t, task_list); + +#ifdef CONFIG_LITMUS_DGL_SUPPORT + if(q->func == dgl_wake_up) { + dgl_wait = (dgl_wait_state_t*) q->private; + blocked_task = dgl_wait->task; + + if(tsk_rt(blocked_task)->blocked_lock != &mutex->litmus_lock) + enabled = 0; + } + else { + blocked_task = (struct task_struct*) q->private; + } +#else + blocked_task = (struct task_struct*) q->private; +#endif + + w = scnprintf(next, size, + "\t%s/%d (inh: %s/%d)" +#ifdef CONFIG_LITMUS_DGL_SUPPORT + " DGL enabled: %d" +#endif + "\n", + blocked_task->comm, blocked_task->pid, + (tsk_rt(blocked_task)->inh_task) ? + tsk_rt(blocked_task)->inh_task->comm : "nil", + (tsk_rt(blocked_task)->inh_task) ? + tsk_rt(blocked_task)->inh_task->pid : -1 +#ifdef CONFIG_LITMUS_DGL_SUPPORT + , enabled +#endif + ); + size -= w; + next += w; + } + } + else { + w = scnprintf(next, size, "\t\n"); + size -= w; + next += w; + } + + raw_spin_unlock_irqrestore(&mutex->lock, flags); + } + else { + w = scnprintf(next, size, "%s is busy.\n", mutex->litmus_lock.name); + size -= w; + next += w; + } + + return count - size; +} + +static void rsm_proc_add(struct litmus_lock* l) +{ + snprintf(l->name, LOCK_NAME_LEN, "rsm-%d", l->ident); + + l->proc_entry = litmus_add_proc_lock(l, rsm_proc_print); +} + +static void rsm_proc_remove(struct litmus_lock* l) +{ + litmus_remove_proc_lock(l); +} + +static struct litmus_lock_proc_ops rsm_proc_ops = +{ + .add = rsm_proc_add, + .remove = rsm_proc_remove +}; + + struct litmus_lock* rsm_mutex_new(struct litmus_lock_ops* ops) { struct rsm_mutex* mutex; @@ -772,6 +927,7 @@ struct litmus_lock* rsm_mutex_new(struct litmus_lock_ops* ops) mutex = kmalloc(sizeof(*mutex), GFP_KERNEL); if (!mutex) return NULL; + memset(mutex, 0, sizeof(*mutex)); mutex->litmus_lock.ops = ops; mutex->owner = NULL; @@ -791,6 +947,8 @@ struct litmus_lock* rsm_mutex_new(struct litmus_lock_ops* ops) ((struct litmus_lock*)mutex)->nest.hp_waiter_ptr = &mutex->hp_waiter; + ((struct litmus_lock*)mutex)->proc = &rsm_proc_ops; + return &mutex->litmus_lock; } diff --git a/litmus/sched_cedf.c b/litmus/sched_cedf.c index db47f4413329..2ec919dc850c 100644 --- a/litmus/sched_cedf.c +++ b/litmus/sched_cedf.c @@ -1068,7 +1068,7 @@ static void cedf_task_block(struct task_struct *t) #ifdef CONFIG_LITMUS_NVIDIA if (tsk_rt(t)->held_gpus && !tsk_rt(t)->hide_from_gpu) { - TRACE_CUR("%s/%d is blocked so aux tasks may inherit.\n", t->comm, t->pid); + TRACE_CUR("%s/%d is blocked so klmirqd threads may inherit.\n", t->comm, t->pid); enable_gpu_owner(t); } #endif @@ -1118,7 +1118,7 @@ static void cedf_task_exit(struct task_struct * t) raw_spin_unlock_irqrestore(&cluster->cluster_lock, flags); BUG_ON(!is_realtime(t)); - TRACE_TASK(t, "RIP\n"); + TRACE_TASK(t, "RIP\n"); } static long cedf_admit_task(struct task_struct* tsk) @@ -1128,7 +1128,7 @@ static long cedf_admit_task(struct task_struct* tsk) edf_max_heap_base_priority_order); #endif - return task_cpu(tsk) == tsk->rt_param.task_params.cpu ? 0 : -EINVAL; + return (task_cpu(tsk) == tsk->rt_param.task_params.cpu) ? 0 : -EINVAL; } diff --git a/litmus/sched_gsn_edf.c b/litmus/sched_gsn_edf.c index 01791a18e8f3..b3309ee2561e 100644 --- a/litmus/sched_gsn_edf.c +++ b/litmus/sched_gsn_edf.c @@ -1720,6 +1720,7 @@ static struct litmus_lock* gsnedf_new_fmlp(void) sem = kmalloc(sizeof(*sem), GFP_KERNEL); if (!sem) return NULL; + memset(sem, 0, sizeof(*sem)); sem->owner = NULL; sem->hp_waiter = NULL; diff --git a/litmus/sched_pfp.c b/litmus/sched_pfp.c index a96c2b1aa26f..a435ed6621cf 100644 --- a/litmus/sched_pfp.c +++ b/litmus/sched_pfp.c @@ -692,6 +692,7 @@ static struct litmus_lock* pfp_new_fmlp(void) sem = kmalloc(sizeof(*sem), GFP_KERNEL); if (!sem) return NULL; + memset(sem, 0, sizeof(*sem)); sem->owner = NULL; init_waitqueue_head(&sem->wait); @@ -971,6 +972,7 @@ static struct litmus_lock* pfp_new_mpcp(int vspin) sem = kmalloc(sizeof(*sem), GFP_KERNEL); if (!sem) return NULL; + memset(sem, 0, sizeof(*sem)); sem->owner = NULL; init_waitqueue_head(&sem->wait); @@ -1362,6 +1364,7 @@ static struct litmus_lock* pfp_new_pcp(int on_cpu) sem = kmalloc(sizeof(*sem), GFP_KERNEL); if (!sem) return NULL; + memset(sem, 0, sizeof(*sem)); sem->litmus_lock.ops = &pfp_pcp_lock_ops; pcp_init_semaphore(sem, on_cpu); @@ -1552,6 +1555,7 @@ static struct litmus_lock* pfp_new_dpcp(int on_cpu) sem = kmalloc(sizeof(*sem), GFP_KERNEL); if (!sem) return NULL; + memset(sem, 0, sizeof(*sem)); sem->litmus_lock.ops = &pfp_dpcp_lock_ops; sem->owner_cpu = NO_CPU; diff --git a/litmus/srp.c b/litmus/srp.c index 2ed4ec12a9d3..5ffdc9e7dc5b 100644 --- a/litmus/srp.c +++ b/litmus/srp.c @@ -219,6 +219,7 @@ struct srp_semaphore* allocate_srp_semaphore(void) sem = kmalloc(sizeof(*sem), GFP_KERNEL); if (!sem) return NULL; + memset(sem, 0, sizeof(*sem)); INIT_LIST_HEAD(&sem->ceiling.list); sem->ceiling.priority = 0; -- cgit v1.2.2