aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/locking.c
diff options
context:
space:
mode:
Diffstat (limited to 'litmus/locking.c')
-rw-r--r--litmus/locking.c93
1 files changed, 72 insertions, 21 deletions
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 = {
28 .create = create_generic_lock, 28 .create = create_generic_lock,
29 .open = open_generic_lock, 29 .open = open_generic_lock,
30 .close = close_generic_lock, 30 .close = close_generic_lock,
31 .destroy = destroy_generic_lock 31 .destroy = destroy_generic_lock,
32}; 32};
33 33
34static atomic_t lock_id_gen = ATOMIC_INIT(0); 34static 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
59 INIT_BINHEAP_NODE(&lock->nest.hp_binheap_node); 59 INIT_BINHEAP_NODE(&lock->nest.hp_binheap_node);
60 if(!lock->nest.hp_waiter_ptr) { 60 if(!lock->nest.hp_waiter_ptr) {
61 TRACE_CUR("BEWARE: hp_waiter_ptr should probably not be NULL in " 61 TRACE_CUR("BEWARE: hp_waiter_ptr should probably not be NULL in "
62 "most uses. (exception: IKGLP donors)\n"); 62 "most cases. (exception: IKGLP donors)\n");
63 } 63 }
64#endif 64#endif
65 lock->type = type; 65 lock->type = type;
66 lock->ident = atomic_inc_return(&lock_id_gen); 66 lock->ident = atomic_inc_return(&lock_id_gen);
67 *obj_ref = lock; 67 *obj_ref = lock;
68
69 TRACE_CUR("Lock %d created. Type = %d\n.", lock->ident, type);
70
71 if (lock->proc && lock->proc->add) {
72 lock->proc->add(lock);
73 }
68 } 74 }
69 return err; 75 return err;
70} 76}
@@ -81,8 +87,14 @@ static int open_generic_lock(struct od_table_entry* entry, void* __user arg)
81static int close_generic_lock(struct od_table_entry* entry) 87static int close_generic_lock(struct od_table_entry* entry)
82{ 88{
83 struct litmus_lock* lock = get_lock(entry); 89 struct litmus_lock* lock = get_lock(entry);
84 if (lock->ops->close) 90 if (lock->ops->close) {
91
92 if (lock->proc && lock->proc->remove) {
93 lock->proc->remove(lock);
94 }
95
85 return lock->ops->close(lock); 96 return lock->ops->close(lock);
97 }
86 else 98 else
87 return 0; /* default: closing succeeds */ 99 return 0; /* default: closing succeeds */
88} 100}
@@ -109,8 +121,11 @@ asmlinkage long sys_litmus_lock(int lock_od)
109 if (entry && is_lock(entry)) { 121 if (entry && is_lock(entry)) {
110 l = get_lock(entry); 122 l = get_lock(entry);
111 //TRACE_CUR("attempts to lock 0x%p\n", l); 123 //TRACE_CUR("attempts to lock 0x%p\n", l);
112 TRACE_CUR("attempts to lock %d\n", l->ident); 124 TRACE_CUR("Attempts to lock %d\n", l->ident);
113 err = l->ops->lock(l); 125 err = l->ops->lock(l);
126 if (!err) {
127 TRACE_CUR("Got lock %d\n", l->ident);
128 }
114 } 129 }
115 130
116 /* Note: task my have been suspended or preempted in between! Take 131 /* Note: task my have been suspended or preempted in between! Take
@@ -138,8 +153,11 @@ asmlinkage long sys_litmus_unlock(int lock_od)
138 if (entry && is_lock(entry)) { 153 if (entry && is_lock(entry)) {
139 l = get_lock(entry); 154 l = get_lock(entry);
140 //TRACE_CUR("attempts to unlock 0x%p\n", l); 155 //TRACE_CUR("attempts to unlock 0x%p\n", l);
141 TRACE_CUR("attempts to unlock %d\n", l->ident); 156 TRACE_CUR("Attempts to unlock %d\n", l->ident);
142 err = l->ops->unlock(l); 157 err = l->ops->unlock(l);
158 if (!err) {
159 TRACE_CUR("Unlocked %d\n", l->ident);
160 }
143 } 161 }
144 162
145 /* Note: task my have been preempted in between! Take this into 163 /* 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)
285 wq_node->func = dgl_wake_up; 303 wq_node->func = dgl_wake_up;
286} 304}
287 305
306#ifdef CONFIG_SCHED_DEBUG_TRACE
307static void snprintf_dgl(char* buf, size_t bsz, struct litmus_lock* dgl_locks[], int sz)
308{
309 int i;
310 char* ptr;
311
312 ptr = buf;
313 for(i = 0; i < sz && ptr < buf+bsz; ++i)
314 {
315 struct litmus_lock *l = dgl_locks[i];
316 int remaining = bsz - (ptr-buf);
317 int written;
318
319 if(i == 0)
320 written = snprintf(ptr, remaining, "%d ", l->ident);
321 else if(i == sz - 1)
322 written = snprintf(ptr, remaining, " %d", l->ident);
323 else
324 written = snprintf(ptr, remaining, " %d ", l->ident);
325 ptr += written;
326 }
327}
328#endif
288 329
289static long do_litmus_dgl_lock(dgl_wait_state_t *dgl_wait) 330static long do_litmus_dgl_lock(dgl_wait_state_t *dgl_wait)
290{ 331{
291 int i; 332 int i;
292 unsigned long irqflags; //, dummyflags; 333 unsigned long irqflags; //, dummyflags;
293 raw_spinlock_t *dgl_lock = litmus->get_dgl_spinlock(dgl_wait->task); 334 raw_spinlock_t *dgl_lock;
335
336#ifdef CONFIG_SCHED_DEBUG_TRACE
337 char dglstr[CONFIG_LITMUS_MAX_DGL_SIZE*5];
338 snprintf_dgl(dglstr, sizeof(dglstr), dgl_wait->locks, dgl_wait->size);
339 TRACE_CUR("Locking DGL with size %d: %s\n", dgl_wait->size, dglstr);
340#endif
341
342 dgl_lock = litmus->get_dgl_spinlock(dgl_wait->task);
294 343
295 BUG_ON(dgl_wait->task != current); 344 BUG_ON(dgl_wait->task != current);
296 345
297 raw_spin_lock_irqsave(dgl_lock, irqflags); 346 raw_spin_lock_irqsave(dgl_lock, irqflags);
298 347
299
300 dgl_wait->nr_remaining = dgl_wait->size; 348 dgl_wait->nr_remaining = dgl_wait->size;
301 349
302 TRACE_CUR("Locking DGL with size %d\n", dgl_wait->size);
303
304 // try to acquire each lock. enqueue (non-blocking) if it is unavailable. 350 // try to acquire each lock. enqueue (non-blocking) if it is unavailable.
305 for(i = 0; i < dgl_wait->size; ++i) { 351 for(i = 0; i < dgl_wait->size; ++i) {
306 struct litmus_lock *l = dgl_wait->locks[i]; 352 struct litmus_lock *l = dgl_wait->locks[i];
@@ -347,7 +393,8 @@ static long do_litmus_dgl_lock(dgl_wait_state_t *dgl_wait)
347 393
348 raw_spin_unlock_irqrestore(dgl_lock, irqflags); // free dgl_lock before suspending 394 raw_spin_unlock_irqrestore(dgl_lock, irqflags); // free dgl_lock before suspending
349 395
350 schedule(); // suspend!!! 396 suspend_for_lock(); // suspend!!!
397 //schedule(); // suspend!!!
351 398
352 TS_DGL_LOCK_RESUME; 399 TS_DGL_LOCK_RESUME;
353 400
@@ -443,7 +490,11 @@ static long do_litmus_dgl_unlock(struct litmus_lock* dgl_locks[], int dgl_size)
443 int i; 490 int i;
444 long err = 0; 491 long err = 0;
445 492
446 TRACE_CUR("Unlocking a DGL of %d size\n", dgl_size); 493#ifdef CONFIG_SCHED_DEBUG_TRACE
494 char dglstr[CONFIG_LITMUS_MAX_DGL_SIZE*5];
495 snprintf_dgl(dglstr, sizeof(dglstr), dgl_locks, dgl_size);
496 TRACE_CUR("Unlocking a DGL with size %d: %s\n", dgl_size, dglstr);
497#endif
447 498
448 for(i = dgl_size - 1; i >= 0; --i) { // unlock in reverse order 499 for(i = dgl_size - 1; i >= 0; --i) { // unlock in reverse order
449 500
@@ -573,16 +624,16 @@ void suspend_for_lock(void)
573 unsigned int gpu_hide; 624 unsigned int gpu_hide;
574#endif 625#endif
575 626
576//#ifdef CONFIG_REALTIME_AUX_TASKS 627#ifdef CONFIG_REALTIME_AUX_TASKS
577// if (tsk_rt(t)->has_aux_tasks) { 628 if (tsk_rt(t)->has_aux_tasks) {
578// /* hide from aux tasks so they can't inherit our priority when we block 629 /* hide from aux tasks so they can't inherit our priority when we block
579// * for a litmus lock. inheritance is already going to a litmus lock 630 * for a litmus lock. inheritance is already going to a litmus lock
580// * holder. */ 631 * holder. */
581// aux_hide = tsk_rt(t)->hide_from_aux_tasks; 632 aux_hide = tsk_rt(t)->hide_from_aux_tasks;
582// aux_restore = 1; 633 aux_restore = 1;
583// tsk_rt(t)->hide_from_aux_tasks = 1; 634 tsk_rt(t)->hide_from_aux_tasks = 1;
584// } 635 }
585//#endif 636#endif
586 637
587#ifdef CONFIG_LITMUS_NVIDIA 638#ifdef CONFIG_LITMUS_NVIDIA
588 if (tsk_rt(t)->held_gpus) { 639 if (tsk_rt(t)->held_gpus) {