diff options
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))) |
