diff options
| author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-05-15 19:29:03 -0400 |
|---|---|---|
| committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-05-15 19:29:03 -0400 |
| commit | 2ddfb39795ef54769d064aaba6f1ba8c09d61614 (patch) | |
| tree | fd22fa6b67191b86edf3e25078f1bdf927d6917e | |
| parent | 6827bb817faecede51838e2fcc8b6283e54fe872 (diff) | |
experimental changes to support GPUs under SRPwip-gpu-rtss12-srp
Seems to fail due to locking within GPU driver.
| -rw-r--r-- | kernel/softirq.c | 5 | ||||
| -rw-r--r-- | litmus/litmus_pai_softirq.c | 25 | ||||
| -rw-r--r-- | litmus/sched_psn_edf.c | 104 |
3 files changed, 129 insertions, 5 deletions
diff --git a/kernel/softirq.c b/kernel/softirq.c index 5ce271675662..6bb63ac9dbd4 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c | |||
| @@ -445,10 +445,11 @@ void __tasklet_schedule(struct tasklet_struct *t) | |||
| 445 | #ifdef CONFIG_LITMUS_NVIDIA | 445 | #ifdef CONFIG_LITMUS_NVIDIA |
| 446 | if(is_nvidia_func(t->func)) | 446 | if(is_nvidia_func(t->func)) |
| 447 | { | 447 | { |
| 448 | #if 0 | 448 | #if 1 |
| 449 | // do nvidia tasklets right away and return | 449 | // do nvidia tasklets right away and return |
| 450 | if(__do_nv_now(t)) | 450 | if(likely(_litmus_tasklet_schedule(t,0))) { |
| 451 | return; | 451 | return; |
| 452 | } | ||
| 452 | #else | 453 | #else |
| 453 | u32 nvidia_device = get_tasklet_nv_device_num(t); | 454 | u32 nvidia_device = get_tasklet_nv_device_num(t); |
| 454 | // TRACE("%s: Handling NVIDIA tasklet for device\t%u\tat\t%llu\n", | 455 | // TRACE("%s: Handling NVIDIA tasklet for device\t%u\tat\t%llu\n", |
diff --git a/litmus/litmus_pai_softirq.c b/litmus/litmus_pai_softirq.c index 300571a81bbd..1ee5f73a2991 100644 --- a/litmus/litmus_pai_softirq.c +++ b/litmus/litmus_pai_softirq.c | |||
| @@ -17,9 +17,29 @@ | |||
| 17 | #include <litmus/litmus_softirq.h> | 17 | #include <litmus/litmus_softirq.h> |
| 18 | 18 | ||
| 19 | 19 | ||
| 20 | static void __do_lit_tasklet(struct tasklet_struct* tasklet) | ||
| 21 | { | ||
| 22 | if (!atomic_read(&tasklet->count)) { | ||
| 23 | if (!test_and_clear_bit(TASKLET_STATE_SCHED, &tasklet->state)) | ||
| 24 | { | ||
| 25 | BUG(); | ||
| 26 | } | ||
| 27 | TRACE("%s: Invoking tasklet with owner pid = %d (flushed = %d).\n", | ||
| 28 | __FUNCTION__, | ||
| 29 | (tasklet->owner) ? tasklet->owner->pid : -1, | ||
| 30 | (tasklet->owner) ? 0 : 1); | ||
| 31 | tasklet->func(tasklet->data); | ||
| 32 | tasklet_unlock(tasklet); | ||
| 33 | } | ||
| 34 | else { | ||
| 35 | BUG(); | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 20 | 39 | ||
| 21 | int __litmus_tasklet_schedule(struct tasklet_struct *t, unsigned int k_id) | 40 | int __litmus_tasklet_schedule(struct tasklet_struct *t, unsigned int k_id) |
| 22 | { | 41 | { |
| 42 | #if 0 | ||
| 23 | int ret = 0; /* assume failure */ | 43 | int ret = 0; /* assume failure */ |
| 24 | if(unlikely((t->owner == NULL) || !is_realtime(t->owner))) | 44 | if(unlikely((t->owner == NULL) || !is_realtime(t->owner))) |
| 25 | { | 45 | { |
| @@ -28,8 +48,11 @@ int __litmus_tasklet_schedule(struct tasklet_struct *t, unsigned int k_id) | |||
| 28 | } | 48 | } |
| 29 | 49 | ||
| 30 | ret = litmus->enqueue_pai_tasklet(t); | 50 | ret = litmus->enqueue_pai_tasklet(t); |
| 31 | |||
| 32 | return(ret); | 51 | return(ret); |
| 52 | #else | ||
| 53 | __do_lit_tasklet(t); | ||
| 54 | return(1); | ||
| 55 | #endif | ||
| 33 | } | 56 | } |
| 34 | 57 | ||
| 35 | EXPORT_SYMBOL(__litmus_tasklet_schedule); | 58 | EXPORT_SYMBOL(__litmus_tasklet_schedule); |
diff --git a/litmus/sched_psn_edf.c b/litmus/sched_psn_edf.c index 8e4a22dd8d6a..573214d74794 100644 --- a/litmus/sched_psn_edf.c +++ b/litmus/sched_psn_edf.c | |||
| @@ -22,6 +22,22 @@ | |||
| 22 | #include <litmus/sched_trace.h> | 22 | #include <litmus/sched_trace.h> |
| 23 | #include <litmus/trace.h> | 23 | #include <litmus/trace.h> |
| 24 | 24 | ||
| 25 | |||
| 26 | #ifdef CONFIG_LITMUS_SOFTIRQD | ||
| 27 | #include <litmus/litmus_softirq.h> | ||
| 28 | #endif | ||
| 29 | |||
| 30 | #ifdef CONFIG_LITMUS_PAI_SOFTIRQD | ||
| 31 | #include <linux/interrupt.h> | ||
| 32 | #include <litmus/trace.h> | ||
| 33 | #endif | ||
| 34 | |||
| 35 | #ifdef CONFIG_LITMUS_NVIDIA | ||
| 36 | #include <litmus/nvidia_info.h> | ||
| 37 | #endif | ||
| 38 | |||
| 39 | |||
| 40 | |||
| 25 | typedef struct { | 41 | typedef struct { |
| 26 | rt_domain_t domain; | 42 | rt_domain_t domain; |
| 27 | int cpu; | 43 | int cpu; |
| @@ -130,6 +146,73 @@ static void unboost_priority(struct task_struct* t) | |||
| 130 | raw_spin_unlock_irqrestore(&pedf->slock, flags); | 146 | raw_spin_unlock_irqrestore(&pedf->slock, flags); |
| 131 | } | 147 | } |
| 132 | 148 | ||
| 149 | |||
| 150 | |||
| 151 | |||
| 152 | |||
| 153 | |||
| 154 | |||
| 155 | |||
| 156 | #ifdef CONFIG_LITMUS_PAI_SOFTIRQD | ||
| 157 | |||
| 158 | static void __do_lit_tasklet(struct tasklet_struct* tasklet, unsigned long flushed) | ||
| 159 | { | ||
| 160 | if (!atomic_read(&tasklet->count)) { | ||
| 161 | if(tasklet->owner) { | ||
| 162 | sched_trace_tasklet_begin(tasklet->owner); | ||
| 163 | } | ||
| 164 | |||
| 165 | if (!test_and_clear_bit(TASKLET_STATE_SCHED, &tasklet->state)) | ||
| 166 | { | ||
| 167 | BUG(); | ||
| 168 | } | ||
| 169 | TRACE("%s: Invoking tasklet with owner pid = %d (flushed = %d).\n", | ||
| 170 | __FUNCTION__, | ||
| 171 | (tasklet->owner) ? tasklet->owner->pid : -1, | ||
| 172 | (tasklet->owner) ? 0 : 1); | ||
| 173 | tasklet->func(tasklet->data); | ||
| 174 | tasklet_unlock(tasklet); | ||
| 175 | |||
| 176 | if(tasklet->owner) { | ||
| 177 | sched_trace_tasklet_end(tasklet->owner, flushed); | ||
| 178 | } | ||
| 179 | } | ||
| 180 | else { | ||
| 181 | BUG(); | ||
| 182 | } | ||
| 183 | } | ||
| 184 | |||
| 185 | |||
| 186 | |||
| 187 | static void psnedf_run_tasklets(struct task_struct* sched_task) | ||
| 188 | { | ||
| 189 | // stub | ||
| 190 | } | ||
| 191 | |||
| 192 | |||
| 193 | |||
| 194 | static int psnedf_enqueue_pai_tasklet(struct tasklet_struct* tasklet) | ||
| 195 | { | ||
| 196 | // kludge: we run all nvidia tasklets immediatly | ||
| 197 | TRACE("%s: Running tasklet on CPU where it was received.\n", __FUNCTION__); | ||
| 198 | __do_lit_tasklet(tasklet, 0ul); | ||
| 199 | |||
| 200 | return(1); // success | ||
| 201 | } | ||
| 202 | |||
| 203 | static void psnedf_change_prio_pai_tasklet(struct task_struct *old_prio, | ||
| 204 | struct task_struct *new_prio) | ||
| 205 | { | ||
| 206 | // stub | ||
| 207 | } | ||
| 208 | |||
| 209 | #endif // PAI | ||
| 210 | |||
| 211 | |||
| 212 | |||
| 213 | |||
| 214 | |||
| 215 | |||
| 133 | #endif | 216 | #endif |
| 134 | 217 | ||
| 135 | /* This check is trivial in partioned systems as we only have to consider | 218 | /* This check is trivial in partioned systems as we only have to consider |
| @@ -259,10 +342,10 @@ static struct task_struct* psnedf_schedule(struct task_struct * prev) | |||
| 259 | next = prev; | 342 | next = prev; |
| 260 | 343 | ||
| 261 | if (next) { | 344 | if (next) { |
| 262 | TRACE_TASK(next, "scheduled at %llu\n", litmus_clock()); | 345 | // TRACE_TASK(next, "scheduled at %llu\n", litmus_clock()); |
| 263 | set_rt_flags(next, RT_F_RUNNING); | 346 | set_rt_flags(next, RT_F_RUNNING); |
| 264 | } else { | 347 | } else { |
| 265 | TRACE("becoming idle at %llu\n", litmus_clock()); | 348 | // TRACE("becoming idle at %llu\n", litmus_clock()); |
| 266 | } | 349 | } |
| 267 | 350 | ||
| 268 | pedf->scheduled = next; | 351 | pedf->scheduled = next; |
| @@ -590,6 +673,10 @@ static long psnedf_activate_plugin(void) | |||
| 590 | #ifdef CONFIG_LITMUS_LOCKING | 673 | #ifdef CONFIG_LITMUS_LOCKING |
| 591 | get_srp_prio = psnedf_get_srp_prio; | 674 | get_srp_prio = psnedf_get_srp_prio; |
| 592 | #endif | 675 | #endif |
| 676 | |||
| 677 | #ifdef CONFIG_LITMUS_NVIDIA | ||
| 678 | init_nvidia_info(); | ||
| 679 | #endif | ||
| 593 | 680 | ||
| 594 | return 0; | 681 | return 0; |
| 595 | } | 682 | } |
| @@ -622,6 +709,11 @@ static struct sched_plugin psn_edf_plugin __cacheline_aligned_in_smp = { | |||
| 622 | #ifdef CONFIG_LITMUS_LOCKING | 709 | #ifdef CONFIG_LITMUS_LOCKING |
| 623 | .allocate_lock = psnedf_allocate_lock, | 710 | .allocate_lock = psnedf_allocate_lock, |
| 624 | #endif | 711 | #endif |
| 712 | #ifdef CONFIG_LITMUS_PAI_SOFTIRQD | ||
| 713 | .enqueue_pai_tasklet = psnedf_enqueue_pai_tasklet, | ||
| 714 | .change_prio_pai_tasklet = psnedf_change_prio_pai_tasklet, | ||
| 715 | .run_tasklets = psnedf_run_tasklets, | ||
| 716 | #endif | ||
| 625 | }; | 717 | }; |
| 626 | 718 | ||
| 627 | 719 | ||
| @@ -641,5 +733,13 @@ static int __init init_psn_edf(void) | |||
| 641 | return register_sched_plugin(&psn_edf_plugin); | 733 | return register_sched_plugin(&psn_edf_plugin); |
| 642 | } | 734 | } |
| 643 | 735 | ||
| 736 | static void clean_psn_edf(void) | ||
| 737 | { | ||
| 738 | #ifdef CONFIG_LITMUS_NVIDIA | ||
| 739 | shutdown_nvidia_info(); | ||
| 740 | #endif | ||
| 741 | } | ||
| 742 | |||
| 644 | module_init(init_psn_edf); | 743 | module_init(init_psn_edf); |
| 744 | module_exit(clean_psn_edf); | ||
| 645 | 745 | ||
