aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/workqueue.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r--kernel/workqueue.c70
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
50enum { 57enum {
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 */
2527int schedule_work(struct work_struct *work) 2532int 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}
2531EXPORT_SYMBOL(schedule_work); 2589EXPORT_SYMBOL(schedule_work);
2532 2590
2591int __schedule_work(struct work_struct* work)
2592{
2593 return queue_work(system_wq, work);
2594}
2595EXPORT_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