diff options
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r-- | kernel/workqueue.c | 70 |
1 files changed, 67 insertions, 3 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index f77afd939229..8139208eaee1 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -47,6 +47,13 @@ | |||
47 | 47 | ||
48 | #include "workqueue_sched.h" | 48 | #include "workqueue_sched.h" |
49 | 49 | ||
50 | #ifdef CONFIG_LITMUS_NVIDIA | ||
51 | #include <litmus/litmus.h> | ||
52 | #include <litmus/sched_trace.h> | ||
53 | #include <litmus/nvidia_info.h> | ||
54 | #endif | ||
55 | |||
56 | |||
50 | enum { | 57 | enum { |
51 | /* global_cwq flags */ | 58 | /* global_cwq flags */ |
52 | GCWQ_MANAGE_WORKERS = 1 << 0, /* need to manage workers */ | 59 | GCWQ_MANAGE_WORKERS = 1 << 0, /* need to manage workers */ |
@@ -1010,9 +1017,7 @@ static void __queue_work(unsigned int cpu, struct workqueue_struct *wq, | |||
1010 | work_flags |= WORK_STRUCT_DELAYED; | 1017 | work_flags |= WORK_STRUCT_DELAYED; |
1011 | worklist = &cwq->delayed_works; | 1018 | worklist = &cwq->delayed_works; |
1012 | } | 1019 | } |
1013 | |||
1014 | insert_work(cwq, work, worklist, work_flags); | 1020 | insert_work(cwq, work, worklist, work_flags); |
1015 | |||
1016 | spin_unlock_irqrestore(&gcwq->lock, flags); | 1021 | spin_unlock_irqrestore(&gcwq->lock, flags); |
1017 | } | 1022 | } |
1018 | 1023 | ||
@@ -2526,10 +2531,69 @@ EXPORT_SYMBOL(cancel_delayed_work_sync); | |||
2526 | */ | 2531 | */ |
2527 | int schedule_work(struct work_struct *work) | 2532 | int schedule_work(struct work_struct *work) |
2528 | { | 2533 | { |
2529 | return queue_work(system_wq, work); | 2534 | #ifdef CONFIG_LITMUS_NVIDIA |
2535 | if(is_nvidia_func(work->func)) | ||
2536 | { | ||
2537 | u32 nvidiaDevice = get_work_nv_device_num(work); | ||
2538 | |||
2539 | //1) Ask Litmus which task owns GPU <nvidiaDevice>. (API to be defined.) | ||
2540 | unsigned long flags; | ||
2541 | struct task_struct* device_owner; | ||
2542 | |||
2543 | lock_nv_registry(nvidiaDevice, &flags); | ||
2544 | |||
2545 | device_owner = get_nv_device_owner(nvidiaDevice); | ||
2546 | |||
2547 | //2) If there is an owner, set work->owner to the owner's task struct. | ||
2548 | if(device_owner==NULL) | ||
2549 | { | ||
2550 | work->owner = NULL; | ||
2551 | //TRACE("%s: the owner task of NVIDIA Device %u is NULL\n",__FUNCTION__,nvidiaDevice); | ||
2552 | } | ||
2553 | else | ||
2554 | { | ||
2555 | if( is_realtime(device_owner)) | ||
2556 | { | ||
2557 | TRACE("%s: Handling NVIDIA work for device\t%u\tat\t%llu\n", | ||
2558 | __FUNCTION__, nvidiaDevice,litmus_clock()); | ||
2559 | TRACE("%s: the owner task %d of NVIDIA Device %u is RT-task\n", | ||
2560 | __FUNCTION__, | ||
2561 | device_owner->pid, | ||
2562 | nvidiaDevice); | ||
2563 | |||
2564 | //3) Call litmus_schedule_work() and return (don't execute the rest | ||
2565 | // of schedule_schedule()). | ||
2566 | work->owner = device_owner; | ||
2567 | sched_trace_work_release(work->owner); | ||
2568 | if(likely(litmus_schedule_work(work, nvidiaDevice))) | ||
2569 | { | ||
2570 | unlock_nv_registry(nvidiaDevice, &flags); | ||
2571 | return 1; | ||
2572 | } | ||
2573 | else | ||
2574 | { | ||
2575 | work->owner = NULL; /* fall through to normal work scheduling */ | ||
2576 | } | ||
2577 | } | ||
2578 | else | ||
2579 | { | ||
2580 | work->owner = NULL; | ||
2581 | } | ||
2582 | } | ||
2583 | unlock_nv_registry(nvidiaDevice, &flags); | ||
2584 | } | ||
2585 | #endif | ||
2586 | |||
2587 | return(__schedule_work(work)); | ||
2530 | } | 2588 | } |
2531 | EXPORT_SYMBOL(schedule_work); | 2589 | EXPORT_SYMBOL(schedule_work); |
2532 | 2590 | ||
2591 | int __schedule_work(struct work_struct* work) | ||
2592 | { | ||
2593 | return queue_work(system_wq, work); | ||
2594 | } | ||
2595 | EXPORT_SYMBOL(__schedule_work); | ||
2596 | |||
2533 | /* | 2597 | /* |
2534 | * schedule_work_on - put work task on a specific cpu | 2598 | * schedule_work_on - put work task on a specific cpu |
2535 | * @cpu: cpu to put the work task on | 2599 | * @cpu: cpu to put the work task on |