aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-05-14 16:51:05 -0400
committerGlenn Elliott <gelliott@cs.unc.edu>2013-05-19 22:46:49 -0400
commit44326648c2ea81b9a32619644fe9c665ed0d9e0b (patch)
treeff1e00cf3cbc0e06f511a90c4f28aa8f7b40b12e /kernel
parentaf6eeb156c7da47ff5df03a3da04432c8ac4460c (diff)
Final GPUSync implementation.gpusync-rtss12
Diffstat (limited to 'kernel')
-rw-r--r--kernel/mutex.c48
-rw-r--r--kernel/sched.c4
-rw-r--r--kernel/softirq.c66
3 files changed, 76 insertions, 42 deletions
diff --git a/kernel/mutex.c b/kernel/mutex.c
index 2f363b9bfc1f..96bcecd385d3 100644
--- a/kernel/mutex.c
+++ b/kernel/mutex.c
@@ -511,12 +511,12 @@ void mutex_lock_sfx(struct mutex *lock,
511 struct task_struct *task = current; 511 struct task_struct *task = current;
512 struct mutex_waiter waiter; 512 struct mutex_waiter waiter;
513 unsigned long flags; 513 unsigned long flags;
514 514
515 preempt_disable(); 515 preempt_disable();
516 mutex_acquire(&lock->dep_map, subclass, 0, ip); 516 mutex_acquire(&lock->dep_map, subclass, 0, ip);
517 517
518 spin_lock_mutex(&lock->wait_lock, flags); 518 spin_lock_mutex(&lock->wait_lock, flags);
519 519
520 if(pre) 520 if(pre)
521 { 521 {
522 if(unlikely(pre(pre_arg))) 522 if(unlikely(pre(pre_arg)))
@@ -530,16 +530,16 @@ void mutex_lock_sfx(struct mutex *lock,
530 530
531 debug_mutex_lock_common(lock, &waiter); 531 debug_mutex_lock_common(lock, &waiter);
532 debug_mutex_add_waiter(lock, &waiter, task_thread_info(task)); 532 debug_mutex_add_waiter(lock, &waiter, task_thread_info(task));
533 533
534 /* add waiting tasks to the end of the waitqueue (FIFO): */ 534 /* add waiting tasks to the end of the waitqueue (FIFO): */
535 list_add_tail(&waiter.list, &lock->wait_list); 535 list_add_tail(&waiter.list, &lock->wait_list);
536 waiter.task = task; 536 waiter.task = task;
537 537
538 if (atomic_xchg(&lock->count, -1) == 1) 538 if (atomic_xchg(&lock->count, -1) == 1)
539 goto done; 539 goto done;
540 540
541 lock_contended(&lock->dep_map, ip); 541 lock_contended(&lock->dep_map, ip);
542 542
543 for (;;) { 543 for (;;) {
544 /* 544 /*
545 * Lets try to take the lock again - this is needed even if 545 * Lets try to take the lock again - this is needed even if
@@ -552,9 +552,9 @@ void mutex_lock_sfx(struct mutex *lock,
552 */ 552 */
553 if (atomic_xchg(&lock->count, -1) == 1) 553 if (atomic_xchg(&lock->count, -1) == 1)
554 break; 554 break;
555 555
556 __set_task_state(task, state); 556 __set_task_state(task, state);
557 557
558 /* didnt get the lock, go to sleep: */ 558 /* didnt get the lock, go to sleep: */
559 spin_unlock_mutex(&lock->wait_lock, flags); 559 spin_unlock_mutex(&lock->wait_lock, flags);
560 preempt_enable_no_resched(); 560 preempt_enable_no_resched();
@@ -562,22 +562,22 @@ void mutex_lock_sfx(struct mutex *lock,
562 preempt_disable(); 562 preempt_disable();
563 spin_lock_mutex(&lock->wait_lock, flags); 563 spin_lock_mutex(&lock->wait_lock, flags);
564 } 564 }
565 565
566done: 566done:
567 lock_acquired(&lock->dep_map, ip); 567 lock_acquired(&lock->dep_map, ip);
568 /* got the lock - rejoice! */ 568 /* got the lock - rejoice! */
569 mutex_remove_waiter(lock, &waiter, current_thread_info()); 569 mutex_remove_waiter(lock, &waiter, current_thread_info());
570 mutex_set_owner(lock); 570 mutex_set_owner(lock);
571 571
572 /* set it to 0 if there are no waiters left: */ 572 /* set it to 0 if there are no waiters left: */
573 if (likely(list_empty(&lock->wait_list))) 573 if (likely(list_empty(&lock->wait_list)))
574 atomic_set(&lock->count, 0); 574 atomic_set(&lock->count, 0);
575 575
576 if(post) 576 if(post)
577 post(post_arg); 577 post(post_arg);
578 578
579 spin_unlock_mutex(&lock->wait_lock, flags); 579 spin_unlock_mutex(&lock->wait_lock, flags);
580 580
581 debug_mutex_free_waiter(&waiter); 581 debug_mutex_free_waiter(&waiter);
582 preempt_enable(); 582 preempt_enable();
583} 583}
@@ -588,16 +588,16 @@ void mutex_unlock_sfx(struct mutex *lock,
588 side_effect_t post, unsigned long post_arg) 588 side_effect_t post, unsigned long post_arg)
589{ 589{
590 unsigned long flags; 590 unsigned long flags;
591 591
592 spin_lock_mutex(&lock->wait_lock, flags); 592 spin_lock_mutex(&lock->wait_lock, flags);
593 593
594 if(pre) 594 if(pre)
595 pre(pre_arg); 595 pre(pre_arg);
596 596
597 //mutex_release(&lock->dep_map, nested, _RET_IP_); 597 //mutex_release(&lock->dep_map, nested, _RET_IP_);
598 mutex_release(&lock->dep_map, 1, _RET_IP_); 598 mutex_release(&lock->dep_map, 1, _RET_IP_);
599 debug_mutex_unlock(lock); 599 debug_mutex_unlock(lock);
600 600
601 /* 601 /*
602 * some architectures leave the lock unlocked in the fastpath failure 602 * some architectures leave the lock unlocked in the fastpath failure
603 * case, others need to leave it locked. In the later case we have to 603 * case, others need to leave it locked. In the later case we have to
@@ -605,21 +605,21 @@ void mutex_unlock_sfx(struct mutex *lock,
605 */ 605 */
606 if (__mutex_slowpath_needs_to_unlock()) 606 if (__mutex_slowpath_needs_to_unlock())
607 atomic_set(&lock->count, 1); 607 atomic_set(&lock->count, 1);
608 608
609 if (!list_empty(&lock->wait_list)) { 609 if (!list_empty(&lock->wait_list)) {
610 /* get the first entry from the wait-list: */ 610 /* get the first entry from the wait-list: */
611 struct mutex_waiter *waiter = 611 struct mutex_waiter *waiter =
612 list_entry(lock->wait_list.next, 612 list_entry(lock->wait_list.next,
613 struct mutex_waiter, list); 613 struct mutex_waiter, list);
614 614
615 debug_mutex_wake_waiter(lock, waiter); 615 debug_mutex_wake_waiter(lock, waiter);
616 616
617 wake_up_process(waiter->task); 617 wake_up_process(waiter->task);
618 } 618 }
619 619
620 if(post) 620 if(post)
621 post(post_arg); 621 post(post_arg);
622 622
623 spin_unlock_mutex(&lock->wait_lock, flags); 623 spin_unlock_mutex(&lock->wait_lock, flags);
624} 624}
625EXPORT_SYMBOL(mutex_unlock_sfx); 625EXPORT_SYMBOL(mutex_unlock_sfx);
diff --git a/kernel/sched.c b/kernel/sched.c
index f3d9a69a3777..2f990b4b24f9 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4430,8 +4430,8 @@ litmus_need_resched_nonpreemptible:
4430 4430
4431#ifdef CONFIG_LITMUS_PAI_SOFTIRQD 4431#ifdef CONFIG_LITMUS_PAI_SOFTIRQD
4432 litmus->run_tasklets(prev); 4432 litmus->run_tasklets(prev);
4433#endif 4433#endif
4434 4434
4435 srp_ceiling_block(); 4435 srp_ceiling_block();
4436} 4436}
4437EXPORT_SYMBOL(schedule); 4437EXPORT_SYMBOL(schedule);
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 1c42e08fdfaa..4d7b1a3e4d01 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -216,7 +216,7 @@ EXPORT_SYMBOL(local_bh_enable_ip);
216 216
217asmlinkage void __do_softirq(void) 217asmlinkage void __do_softirq(void)
218{ 218{
219 struct softirq_action *h; 219 struct softirq_action *h;
220 __u32 pending; 220 __u32 pending;
221 int max_restart = MAX_SOFTIRQ_RESTART; 221 int max_restart = MAX_SOFTIRQ_RESTART;
222 int cpu; 222 int cpu;
@@ -254,10 +254,10 @@ restart:
254 softirq_to_name[vec_nr], h->action, 254 softirq_to_name[vec_nr], h->action,
255 prev_count, preempt_count()); 255 prev_count, preempt_count());
256 preempt_count() = prev_count; 256 preempt_count() = prev_count;
257 } 257 }
258 258
259 rcu_bh_qs(cpu); 259 rcu_bh_qs(cpu);
260 } 260 }
261 h++; 261 h++;
262 pending >>= 1; 262 pending >>= 1;
263 } while (pending); 263 } while (pending);
@@ -412,13 +412,45 @@ struct tasklet_head
412static DEFINE_PER_CPU(struct tasklet_head, tasklet_vec); 412static DEFINE_PER_CPU(struct tasklet_head, tasklet_vec);
413static DEFINE_PER_CPU(struct tasklet_head, tasklet_hi_vec); 413static DEFINE_PER_CPU(struct tasklet_head, tasklet_hi_vec);
414 414
415#ifdef CONFIG_LITMUS_NVIDIA
416static int __do_nv_now(struct tasklet_struct* tasklet)
417{
418 int success = 1;
419
420 if(tasklet_trylock(tasklet)) {
421 if (!atomic_read(&tasklet->count)) {
422 if (!test_and_clear_bit(TASKLET_STATE_SCHED, &tasklet->state)) {
423 BUG();
424 }
425 tasklet->func(tasklet->data);
426 tasklet_unlock(tasklet);
427 }
428 else {
429 success = 0;
430 }
431
432 tasklet_unlock(tasklet);
433 }
434 else {
435 success = 0;
436 }
437
438 return success;
439}
440#endif
441
415 442
416void __tasklet_schedule(struct tasklet_struct *t) 443void __tasklet_schedule(struct tasklet_struct *t)
417{ 444{
418#ifdef CONFIG_LITMUS_NVIDIA 445#ifdef CONFIG_LITMUS_NVIDIA
419 if(is_nvidia_func(t->func)) 446 if(is_nvidia_func(t->func))
420 { 447 {
421 u32 nvidia_device = get_tasklet_nv_device_num(t); 448#if 0
449 // do nvidia tasklets right away and return
450 if(__do_nv_now(t))
451 return;
452#else
453 u32 nvidia_device = get_tasklet_nv_device_num(t);
422 // TRACE("%s: Handling NVIDIA tasklet for device\t%u\tat\t%llu\n", 454 // TRACE("%s: Handling NVIDIA tasklet for device\t%u\tat\t%llu\n",
423 // __FUNCTION__, nvidia_device,litmus_clock()); 455 // __FUNCTION__, nvidia_device,litmus_clock());
424 456
@@ -438,7 +470,7 @@ void __tasklet_schedule(struct tasklet_struct *t)
438 if(is_realtime(device_owner)) 470 if(is_realtime(device_owner))
439 { 471 {
440 TRACE("%s: Handling NVIDIA tasklet for device %u at %llu\n", 472 TRACE("%s: Handling NVIDIA tasklet for device %u at %llu\n",
441 __FUNCTION__, nvidia_device,litmus_clock()); 473 __FUNCTION__, nvidia_device,litmus_clock());
442 TRACE("%s: the owner task %d of NVIDIA Device %u is RT-task\n", 474 TRACE("%s: the owner task %d of NVIDIA Device %u is RT-task\n",
443 __FUNCTION__,device_owner->pid,nvidia_device); 475 __FUNCTION__,device_owner->pid,nvidia_device);
444 476
@@ -461,7 +493,9 @@ void __tasklet_schedule(struct tasklet_struct *t)
461 } 493 }
462 } 494 }
463 unlock_nv_registry(nvidia_device, &flags); 495 unlock_nv_registry(nvidia_device, &flags);
496#endif
464 } 497 }
498
465#endif 499#endif
466 500
467 ___tasklet_schedule(t); 501 ___tasklet_schedule(t);
@@ -487,19 +521,19 @@ void __tasklet_hi_schedule(struct tasklet_struct *t)
487{ 521{
488#ifdef CONFIG_LITMUS_NVIDIA 522#ifdef CONFIG_LITMUS_NVIDIA
489 if(is_nvidia_func(t->func)) 523 if(is_nvidia_func(t->func))
490 { 524 {
491 u32 nvidia_device = get_tasklet_nv_device_num(t); 525 u32 nvidia_device = get_tasklet_nv_device_num(t);
492 // TRACE("%s: Handling NVIDIA tasklet for device\t%u\tat\t%llu\n", 526 // TRACE("%s: Handling NVIDIA tasklet for device\t%u\tat\t%llu\n",
493 // __FUNCTION__, nvidia_device,litmus_clock()); 527 // __FUNCTION__, nvidia_device,litmus_clock());
494 528
495 unsigned long flags; 529 unsigned long flags;
496 struct task_struct* device_owner; 530 struct task_struct* device_owner;
497 531
498 lock_nv_registry(nvidia_device, &flags); 532 lock_nv_registry(nvidia_device, &flags);
499 533
500 device_owner = get_nv_max_device_owner(nvidia_device); 534 device_owner = get_nv_max_device_owner(nvidia_device);
501 535
502 if(device_owner==NULL) 536 if(device_owner==NULL)
503 { 537 {
504 t->owner = NULL; 538 t->owner = NULL;
505 } 539 }
@@ -508,10 +542,10 @@ void __tasklet_hi_schedule(struct tasklet_struct *t)
508 if( is_realtime(device_owner)) 542 if( is_realtime(device_owner))
509 { 543 {
510 TRACE("%s: Handling NVIDIA tasklet for device %u\tat %llu\n", 544 TRACE("%s: Handling NVIDIA tasklet for device %u\tat %llu\n",
511 __FUNCTION__, nvidia_device,litmus_clock()); 545 __FUNCTION__, nvidia_device,litmus_clock());
512 TRACE("%s: the owner task %d of NVIDIA Device %u is RT-task\n", 546 TRACE("%s: the owner task %d of NVIDIA Device %u is RT-task\n",
513 __FUNCTION__,device_owner->pid,nvidia_device); 547 __FUNCTION__,device_owner->pid,nvidia_device);
514 548
515 t->owner = device_owner; 549 t->owner = device_owner;
516 sched_trace_tasklet_release(t->owner); 550 sched_trace_tasklet_release(t->owner);
517 if(likely(_litmus_tasklet_hi_schedule(t,nvidia_device))) 551 if(likely(_litmus_tasklet_hi_schedule(t,nvidia_device)))
@@ -553,15 +587,15 @@ EXPORT_SYMBOL(___tasklet_hi_schedule);
553void __tasklet_hi_schedule_first(struct tasklet_struct *t) 587void __tasklet_hi_schedule_first(struct tasklet_struct *t)
554{ 588{
555 BUG_ON(!irqs_disabled()); 589 BUG_ON(!irqs_disabled());
556#ifdef CONFIG_LITMUS_NVIDIA 590#ifdef CONFIG_LITMUS_NVIDIA
557 if(is_nvidia_func(t->func)) 591 if(is_nvidia_func(t->func))
558 { 592 {
559 u32 nvidia_device = get_tasklet_nv_device_num(t); 593 u32 nvidia_device = get_tasklet_nv_device_num(t);
560 // TRACE("%s: Handling NVIDIA tasklet for device\t%u\tat\t%llu\n", 594 // TRACE("%s: Handling NVIDIA tasklet for device\t%u\tat\t%llu\n",
561 // __FUNCTION__, nvidia_device,litmus_clock()); 595 // __FUNCTION__, nvidia_device,litmus_clock());
562 unsigned long flags; 596 unsigned long flags;
563 struct task_struct* device_owner; 597 struct task_struct* device_owner;
564 598
565 lock_nv_registry(nvidia_device, &flags); 599 lock_nv_registry(nvidia_device, &flags);
566 600
567 device_owner = get_nv_max_device_owner(nvidia_device); 601 device_owner = get_nv_max_device_owner(nvidia_device);
@@ -576,10 +610,10 @@ void __tasklet_hi_schedule_first(struct tasklet_struct *t)
576 { 610 {
577 TRACE("%s: Handling NVIDIA tasklet for device %u at %llu\n", 611 TRACE("%s: Handling NVIDIA tasklet for device %u at %llu\n",
578 __FUNCTION__, nvidia_device,litmus_clock()); 612 __FUNCTION__, nvidia_device,litmus_clock());
579 613
580 TRACE("%s: the owner task %d of NVIDIA Device %u is RT-task\n", 614 TRACE("%s: the owner task %d of NVIDIA Device %u is RT-task\n",
581 __FUNCTION__,device_owner->pid,nvidia_device); 615 __FUNCTION__,device_owner->pid,nvidia_device);
582 616
583 t->owner = device_owner; 617 t->owner = device_owner;
584 sched_trace_tasklet_release(t->owner); 618 sched_trace_tasklet_release(t->owner);
585 if(likely(_litmus_tasklet_hi_schedule_first(t,nvidia_device))) 619 if(likely(_litmus_tasklet_hi_schedule_first(t,nvidia_device)))