diff options
Diffstat (limited to 'litmus/locking.c')
-rw-r--r-- | litmus/locking.c | 93 |
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 | ||
34 | static atomic_t lock_id_gen = ATOMIC_INIT(0); | 34 | 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 | |||
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) | |||
81 | static int close_generic_lock(struct od_table_entry* entry) | 87 | static 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 | ||
307 | static 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 | ||
289 | static long do_litmus_dgl_lock(dgl_wait_state_t *dgl_wait) | 330 | static 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) { |