diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-05-14 16:51:05 -0400 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2013-05-19 22:46:49 -0400 |
commit | 44326648c2ea81b9a32619644fe9c665ed0d9e0b (patch) | |
tree | ff1e00cf3cbc0e06f511a90c4f28aa8f7b40b12e /kernel | |
parent | af6eeb156c7da47ff5df03a3da04432c8ac4460c (diff) |
Final GPUSync implementation.gpusync-rtss12
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/mutex.c | 48 | ||||
-rw-r--r-- | kernel/sched.c | 4 | ||||
-rw-r--r-- | kernel/softirq.c | 66 |
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 | ||
566 | done: | 566 | done: |
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 | } |
625 | EXPORT_SYMBOL(mutex_unlock_sfx); | 625 | EXPORT_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 | } |
4437 | EXPORT_SYMBOL(schedule); | 4437 | EXPORT_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 | ||
217 | asmlinkage void __do_softirq(void) | 217 | asmlinkage 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 | |||
412 | static DEFINE_PER_CPU(struct tasklet_head, tasklet_vec); | 412 | static DEFINE_PER_CPU(struct tasklet_head, tasklet_vec); |
413 | static DEFINE_PER_CPU(struct tasklet_head, tasklet_hi_vec); | 413 | static DEFINE_PER_CPU(struct tasklet_head, tasklet_hi_vec); |
414 | 414 | ||
415 | #ifdef CONFIG_LITMUS_NVIDIA | ||
416 | static 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 | ||
416 | void __tasklet_schedule(struct tasklet_struct *t) | 443 | void __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); | |||
553 | void __tasklet_hi_schedule_first(struct tasklet_struct *t) | 587 | void __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))) |