diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2013-02-06 20:30:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2013-02-06 20:30:13 -0500 |
commit | 9aacc135e0abe206b7d778af937babaaa7f3c199 (patch) | |
tree | eaab1b47ff8b90cc5f733b6a345878fd1ba03f27 /kernel/workqueue.c | |
parent | dd4c9d77928d67e3afa916b6f1a14e20f02ee67f (diff) |
re-enable klmirqd for workqueues, and grace reboot
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r-- | kernel/workqueue.c | 87 |
1 files changed, 34 insertions, 53 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 6b59d59ce3cf..9eb58729e1bb 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -44,10 +44,11 @@ | |||
44 | 44 | ||
45 | #include "workqueue_sched.h" | 45 | #include "workqueue_sched.h" |
46 | 46 | ||
47 | #ifdef CONFIG_LITMUS_NVIDIA | 47 | #if defined(CONFIG_LITMUS_NVIDIA_WORKQ_ON) || defined(CONFIG_LITMUS_NVIDIA_WORKQ_ON_DEDICATED) |
48 | #include <litmus/litmus.h> | 48 | #include <litmus/litmus.h> |
49 | #include <litmus/sched_trace.h> | ||
50 | #include <litmus/nvidia_info.h> | 49 | #include <litmus/nvidia_info.h> |
50 | #include <litmus/sched_trace.h> | ||
51 | #include <litmus/trace.h> | ||
51 | #endif | 52 | #endif |
52 | 53 | ||
53 | 54 | ||
@@ -2679,6 +2680,32 @@ bool cancel_delayed_work_sync(struct delayed_work *dwork) | |||
2679 | } | 2680 | } |
2680 | EXPORT_SYMBOL(cancel_delayed_work_sync); | 2681 | EXPORT_SYMBOL(cancel_delayed_work_sync); |
2681 | 2682 | ||
2683 | |||
2684 | #if defined(CONFIG_LITMUS_NVIDIA_WORKQ_ON) || defined(CONFIG_LITMUS_NVIDIA_WORKQ_ON_DEDICATED) | ||
2685 | static int __klmirqd_nv_work_schedule(struct work_struct *work) | ||
2686 | { | ||
2687 | /* TODO: MOVE THIS TO nvidia_info.c */ | ||
2688 | unsigned long flags; | ||
2689 | u32 nvidia_device = get_work_nv_device_num(work); | ||
2690 | struct task_struct* klmirqd_th = get_and_lock_nvklmworkqd_thread(nvidia_device, &flags); | ||
2691 | |||
2692 | if (likely(klmirqd_th)) { | ||
2693 | TRACE("Handling NVIDIA workq for device %u (klmirqd: %s/%d) at %llu\n", | ||
2694 | nvidia_device, | ||
2695 | klmirqd_th->comm, | ||
2696 | klmirqd_th->pid, | ||
2697 | litmus_clock()); | ||
2698 | |||
2699 | sched_trace_work_release(NULL, nvidia_device); | ||
2700 | if (likely(litmus_schedule_work(work, klmirqd_th))) { | ||
2701 | unlock_nvklmworkqd_thread(nvidia_device, &flags); | ||
2702 | return 1; /* success */ | ||
2703 | } | ||
2704 | } | ||
2705 | return 0; | ||
2706 | } | ||
2707 | #endif | ||
2708 | |||
2682 | /** | 2709 | /** |
2683 | * schedule_work - put work task in global workqueue | 2710 | * schedule_work - put work task in global workqueue |
2684 | * @work: job to be done | 2711 | * @work: job to be done |
@@ -2692,60 +2719,14 @@ EXPORT_SYMBOL(cancel_delayed_work_sync); | |||
2692 | */ | 2719 | */ |
2693 | int schedule_work(struct work_struct *work) | 2720 | int schedule_work(struct work_struct *work) |
2694 | { | 2721 | { |
2695 | #if 0 | 2722 | #if defined(CONFIG_LITMUS_NVIDIA_WORKQ_ON) || defined(CONFIG_LITMUS_NVIDIA_WORKQ_ON_DEDICATED) |
2696 | #if defined(CONFIG_LITMUS_NVIDIA) && defined(CONFIG_LITMUS_SOFTIRQD) | 2723 | if(is_nvidia_func(work->func)) { |
2697 | if(is_nvidia_func(work->func)) | 2724 | if (__klmirqd_nv_work_schedule(work)) { |
2698 | { | 2725 | return 1; |
2699 | u32 nvidiaDevice = get_work_nv_device_num(work); | ||
2700 | |||
2701 | //1) Ask Litmus which task owns GPU <nvidiaDevice>. (API to be defined.) | ||
2702 | unsigned long flags; | ||
2703 | struct task_struct* device_owner; | ||
2704 | |||
2705 | lock_nv_registry(nvidiaDevice, &flags); | ||
2706 | |||
2707 | device_owner = get_nv_max_device_owner(nvidiaDevice); | ||
2708 | |||
2709 | //2) If there is an owner, set work->owner to the owner's task struct. | ||
2710 | if(device_owner==NULL) | ||
2711 | { | ||
2712 | work->owner = NULL; | ||
2713 | //TRACE("%s: the owner task of NVIDIA Device %u is NULL\n",__FUNCTION__,nvidiaDevice); | ||
2714 | } | 2726 | } |
2715 | else | ||
2716 | { | ||
2717 | if( is_realtime(device_owner)) | ||
2718 | { | ||
2719 | TRACE("%s: Handling NVIDIA work for device\t%u\tat\t%llu\n", | ||
2720 | __FUNCTION__, nvidiaDevice,litmus_clock()); | ||
2721 | TRACE("%s: the owner task %d of NVIDIA Device %u is RT-task\n", | ||
2722 | __FUNCTION__, | ||
2723 | device_owner->pid, | ||
2724 | nvidiaDevice); | ||
2725 | |||
2726 | //3) Call litmus_schedule_work() and return (don't execute the rest | ||
2727 | // of schedule_schedule()). | ||
2728 | work->owner = device_owner; | ||
2729 | sched_trace_work_release(work->owner); | ||
2730 | if(likely(litmus_schedule_work(work, nvidiaDevice))) | ||
2731 | { | ||
2732 | unlock_nv_registry(nvidiaDevice, &flags); | ||
2733 | return 1; | ||
2734 | } | ||
2735 | else | ||
2736 | { | ||
2737 | work->owner = NULL; /* fall through to normal work scheduling */ | ||
2738 | } | ||
2739 | } | ||
2740 | else | ||
2741 | { | ||
2742 | work->owner = NULL; | ||
2743 | } | ||
2744 | } | ||
2745 | unlock_nv_registry(nvidiaDevice, &flags); | ||
2746 | } | 2727 | } |
2747 | #endif | 2728 | #endif |
2748 | #endif | 2729 | |
2749 | return(__schedule_work(work)); | 2730 | return(__schedule_work(work)); |
2750 | } | 2731 | } |
2751 | EXPORT_SYMBOL(schedule_work); | 2732 | EXPORT_SYMBOL(schedule_work); |