diff options
| author | Namhoon Kim <namhoonk@cs.unc.edu> | 2016-04-30 19:46:44 -0400 |
|---|---|---|
| committer | Namhoon Kim <namhoonk@cs.unc.edu> | 2016-04-30 19:46:44 -0400 |
| commit | fc35ca6c9592d43b067a45c49f98cf4b5b361b87 (patch) | |
| tree | 9a7d7d6eec9ea24bea317de137cc0431ff54cb8b | |
| parent | f0e07f0e5cba027377c57e1aa25101023640c62b (diff) | |
PGM supportwip-mc2-new
| -rw-r--r-- | include/litmus/pgm.h | 12 | ||||
| -rw-r--r-- | include/litmus/rt_param.h | 15 | ||||
| -rw-r--r-- | include/litmus/sched_trace.h | 39 | ||||
| -rw-r--r-- | include/trace/events/litmus.h | 53 | ||||
| -rw-r--r-- | litmus/Makefile | 1 | ||||
| -rw-r--r-- | litmus/litmus.c | 22 | ||||
| -rw-r--r-- | litmus/pgm.c | 61 | ||||
| -rw-r--r-- | litmus/sched_mc2.c | 76 | ||||
| -rw-r--r-- | litmus/sched_task_trace.c | 23 |
9 files changed, 296 insertions, 6 deletions
diff --git a/include/litmus/pgm.h b/include/litmus/pgm.h new file mode 100644 index 000000000000..5682a76b3acb --- /dev/null +++ b/include/litmus/pgm.h | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | #ifndef _LITMUS_PGM_H_ | ||
| 2 | #define _LITMUS_PGM_H_ | ||
| 3 | |||
| 4 | #include <litmus/litmus.h> | ||
| 5 | |||
| 6 | #define is_pgm_waiting(t) (tsk_rt(t)->ctrl_page && tsk_rt(t)->ctrl_page->pgm_waiting) | ||
| 7 | #define is_pgm_sending(t) (tsk_rt(t)->ctrl_page && tsk_rt(t)->ctrl_page->pgm_sending) | ||
| 8 | #define is_pgm_satisfied(t) (tsk_rt(t)->ctrl_page && tsk_rt(t)->ctrl_page->pgm_satisfied) | ||
| 9 | |||
| 10 | int setup_pgm_release(struct task_struct* t); | ||
| 11 | |||
| 12 | #endif | ||
diff --git a/include/litmus/rt_param.h b/include/litmus/rt_param.h index a3dde39753bd..fa0f5f4647bd 100644 --- a/include/litmus/rt_param.h +++ b/include/litmus/rt_param.h | |||
| @@ -51,6 +51,14 @@ typedef enum { | |||
| 51 | TASK_EARLY | 51 | TASK_EARLY |
| 52 | } release_policy_t; | 52 | } release_policy_t; |
| 53 | 53 | ||
| 54 | typedef enum { | ||
| 55 | PGM_NOT_A_NODE, | ||
| 56 | PGM_SRC, | ||
| 57 | PGM_SINK, | ||
| 58 | PGM_SRC_SINK, | ||
| 59 | PGM_INTERNAL | ||
| 60 | } pgm_node_type_t; | ||
| 61 | |||
| 54 | /* We use the common priority interpretation "lower index == higher priority", | 62 | /* We use the common priority interpretation "lower index == higher priority", |
| 55 | * which is commonly used in fixed-priority schedulability analysis papers. | 63 | * which is commonly used in fixed-priority schedulability analysis papers. |
| 56 | * So, a numerically lower priority value implies higher scheduling priority, | 64 | * So, a numerically lower priority value implies higher scheduling priority, |
| @@ -122,6 +130,8 @@ struct rt_task { | |||
| 122 | task_class_t cls; | 130 | task_class_t cls; |
| 123 | budget_policy_t budget_policy; /* ignored by pfair */ | 131 | budget_policy_t budget_policy; /* ignored by pfair */ |
| 124 | release_policy_t release_policy; | 132 | release_policy_t release_policy; |
| 133 | pgm_node_type_t pgm_type; | ||
| 134 | lt_t pgm_expected_etoe; | ||
| 125 | }; | 135 | }; |
| 126 | 136 | ||
| 127 | union np_flag { | 137 | union np_flag { |
| @@ -162,6 +172,11 @@ struct control_page { | |||
| 162 | uint64_t irq_syscall_start; /* Snapshot of irq_count when the syscall | 172 | uint64_t irq_syscall_start; /* Snapshot of irq_count when the syscall |
| 163 | * started. */ | 173 | * started. */ |
| 164 | 174 | ||
| 175 | /* Flags from userspace signifying PGM wait states. */ | ||
| 176 | volatile uint32_t pgm_waiting; /* waiting for tokens */ | ||
| 177 | volatile uint32_t pgm_sending; /* sending tokens */ | ||
| 178 | volatile uint32_t pgm_satisfied; /* done waiting/sending */ | ||
| 179 | |||
| 165 | /* to be extended */ | 180 | /* to be extended */ |
| 166 | }; | 181 | }; |
| 167 | 182 | ||
diff --git a/include/litmus/sched_trace.h b/include/litmus/sched_trace.h index 82bde8241298..d3f78a812ef3 100644 --- a/include/litmus/sched_trace.h +++ b/include/litmus/sched_trace.h | |||
| @@ -80,6 +80,19 @@ struct st_sys_release_data { | |||
| 80 | u64 release; | 80 | u64 release; |
| 81 | }; | 81 | }; |
| 82 | 82 | ||
| 83 | struct st_pgm_param_data { | ||
| 84 | u32 node_type; | ||
| 85 | u16 graph_pid; | ||
| 86 | u16 unused; | ||
| 87 | u64 expected_graph_etoe; | ||
| 88 | }; | ||
| 89 | |||
| 90 | struct st_pgm_release_data { | ||
| 91 | u64 release; /* PGM-adjusted release time */ | ||
| 92 | u64 deadline; /* PGM-adjusted deadline */ | ||
| 93 | }; | ||
| 94 | |||
| 95 | |||
| 83 | #define DATA(x) struct st_ ## x ## _data x; | 96 | #define DATA(x) struct st_ ## x ## _data x; |
| 84 | 97 | ||
| 85 | typedef enum { | 98 | typedef enum { |
| @@ -94,7 +107,9 @@ typedef enum { | |||
| 94 | ST_BLOCK, | 107 | ST_BLOCK, |
| 95 | ST_RESUME, | 108 | ST_RESUME, |
| 96 | ST_ACTION, | 109 | ST_ACTION, |
| 97 | ST_SYS_RELEASE | 110 | ST_SYS_RELEASE, |
| 111 | ST_PGM_PARAM, | ||
| 112 | ST_PGM_RELEASE | ||
| 98 | } st_event_record_type_t; | 113 | } st_event_record_type_t; |
| 99 | 114 | ||
| 100 | struct st_event_record { | 115 | struct st_event_record { |
| @@ -113,6 +128,8 @@ struct st_event_record { | |||
| 113 | DATA(resume); | 128 | DATA(resume); |
| 114 | DATA(action); | 129 | DATA(action); |
| 115 | DATA(sys_release); | 130 | DATA(sys_release); |
| 131 | DATA(pgm_param); | ||
| 132 | DATA(pgm_release); | ||
| 116 | } data; | 133 | } data; |
| 117 | }; | 134 | }; |
| 118 | 135 | ||
| @@ -154,6 +171,10 @@ feather_callback void do_sched_trace_action(unsigned long id, | |||
| 154 | unsigned long action); | 171 | unsigned long action); |
| 155 | feather_callback void do_sched_trace_sys_release(unsigned long id, | 172 | feather_callback void do_sched_trace_sys_release(unsigned long id, |
| 156 | lt_t* start); | 173 | lt_t* start); |
| 174 | feather_callback void do_sched_trace_pgm_param(unsigned long id, | ||
| 175 | struct task_struct* task); | ||
| 176 | feather_callback void do_sched_trace_pgm_release(unsigned long id, | ||
| 177 | struct task_struct* task); | ||
| 157 | 178 | ||
| 158 | #endif | 179 | #endif |
| 159 | 180 | ||
| @@ -179,6 +200,8 @@ feather_callback void do_sched_trace_sys_release(unsigned long id, | |||
| 179 | #define trace_litmus_task_block(t) | 200 | #define trace_litmus_task_block(t) |
| 180 | #define trace_litmus_task_resume(t) | 201 | #define trace_litmus_task_resume(t) |
| 181 | #define trace_litmus_sys_release(start) | 202 | #define trace_litmus_sys_release(start) |
| 203 | #define trace_litmus_pgm_param(t) | ||
| 204 | #define trace_litmus_pgm_release(t) | ||
| 182 | 205 | ||
| 183 | #endif | 206 | #endif |
| 184 | 207 | ||
| @@ -252,6 +275,20 @@ feather_callback void do_sched_trace_sys_release(unsigned long id, | |||
| 252 | trace_litmus_sys_release(when); \ | 275 | trace_litmus_sys_release(when); \ |
| 253 | } while (0) | 276 | } while (0) |
| 254 | 277 | ||
| 278 | #define sched_trace_pgm_param(t) \ | ||
| 279 | do { \ | ||
| 280 | SCHED_TRACE(SCHED_TRACE_BASE_ID + 11, \ | ||
| 281 | do_sched_trace_pgm_param, t); \ | ||
| 282 | trace_litmus_pgm_param(t); \ | ||
| 283 | } while (0) | ||
| 284 | |||
| 285 | #define sched_trace_pgm_release(t) \ | ||
| 286 | do { \ | ||
| 287 | SCHED_TRACE(SCHED_TRACE_BASE_ID + 12, \ | ||
| 288 | do_sched_trace_pgm_release, t); \ | ||
| 289 | trace_litmus_pgm_release(t); \ | ||
| 290 | } while (0) | ||
| 291 | |||
| 255 | #define sched_trace_quantum_boundary() /* NOT IMPLEMENTED */ | 292 | #define sched_trace_quantum_boundary() /* NOT IMPLEMENTED */ |
| 256 | 293 | ||
| 257 | #endif /* __KERNEL__ */ | 294 | #endif /* __KERNEL__ */ |
diff --git a/include/trace/events/litmus.h b/include/trace/events/litmus.h index 0fffcee02be0..02b4b54f718c 100644 --- a/include/trace/events/litmus.h +++ b/include/trace/events/litmus.h | |||
| @@ -39,7 +39,7 @@ TRACE_EVENT(litmus_task_param, | |||
| 39 | __entry->partition = get_partition(t); | 39 | __entry->partition = get_partition(t); |
| 40 | ), | 40 | ), |
| 41 | 41 | ||
| 42 | TP_printk("period(%d, %Lu).\nwcet(%d, %Lu).\n", | 42 | TP_printk("period(%u, %Lu).\nwcet(%d, %Lu).\n", |
| 43 | __entry->pid, __entry->period, | 43 | __entry->pid, __entry->period, |
| 44 | __entry->pid, __entry->wcet) | 44 | __entry->pid, __entry->wcet) |
| 45 | ); | 45 | ); |
| @@ -225,6 +225,57 @@ TRACE_EVENT(litmus_sys_release, | |||
| 225 | TP_printk("SynRelease(%Lu) at %Lu\n", __entry->rel, __entry->when) | 225 | TP_printk("SynRelease(%Lu) at %Lu\n", __entry->rel, __entry->when) |
| 226 | ); | 226 | ); |
| 227 | 227 | ||
| 228 | /* Tracing PGM node parameters */ | ||
| 229 | TRACE_EVENT(litmus_pgm_param, | ||
| 230 | |||
| 231 | TP_PROTO(struct task_struct *t), | ||
| 232 | |||
| 233 | TP_ARGS(t), | ||
| 234 | |||
| 235 | TP_STRUCT__entry( | ||
| 236 | __field( pid_t, pid ) | ||
| 237 | __field( pgm_node_type_t, node_type ) | ||
| 238 | __field( pid_t, graph_pid ) | ||
| 239 | ), | ||
| 240 | |||
| 241 | TP_fast_assign( | ||
| 242 | __entry->pid = t ? t->pid : 0; | ||
| 243 | __entry->node_type = t ? t->rt_param.task_params.pgm_type : PGM_NOT_A_NODE; | ||
| 244 | __entry->graph_pid = t ? t->tgid : 0; | ||
| 245 | ), | ||
| 246 | |||
| 247 | TP_printk("pgm node (%u, node type = %d) in graph (%u)\n", | ||
| 248 | __entry->pid, __entry->node_type, __entry->graph_pid) | ||
| 249 | ); | ||
| 250 | |||
| 251 | /* | ||
| 252 | * Tracing PGM-adjusted job release | ||
| 253 | */ | ||
| 254 | TRACE_EVENT(litmus_pgm_release, | ||
| 255 | |||
| 256 | TP_PROTO(struct task_struct *t), | ||
| 257 | |||
| 258 | TP_ARGS(t), | ||
| 259 | |||
| 260 | TP_STRUCT__entry( | ||
| 261 | __field( pid_t, pid ) | ||
| 262 | __field( unsigned int, job ) | ||
| 263 | __field( lt_t, release ) | ||
| 264 | __field( lt_t, deadline ) | ||
| 265 | ), | ||
| 266 | |||
| 267 | TP_fast_assign( | ||
| 268 | __entry->pid = t ? t->pid : 0; | ||
| 269 | __entry->job = t ? t->rt_param.job_params.job_no : 0; | ||
| 270 | __entry->release = get_release(t); | ||
| 271 | __entry->deadline = get_deadline(t); | ||
| 272 | ), | ||
| 273 | |||
| 274 | TP_printk("release(job(%u, %u)): %Lu\ndeadline(job(%u, %u)): %Lu\n", | ||
| 275 | __entry->pid, __entry->job, __entry->release, | ||
| 276 | __entry->pid, __entry->job, __entry->deadline) | ||
| 277 | ); | ||
| 278 | |||
| 228 | #endif /* _SCHED_TASK_TRACEPOINT_H */ | 279 | #endif /* _SCHED_TASK_TRACEPOINT_H */ |
| 229 | 280 | ||
| 230 | /* Must stay outside the protection */ | 281 | /* Must stay outside the protection */ |
diff --git a/litmus/Makefile b/litmus/Makefile index 3d0de72284f8..c19b6015b02e 100644 --- a/litmus/Makefile +++ b/litmus/Makefile | |||
| @@ -40,3 +40,4 @@ obj-y += reservation.o polling_reservations.o | |||
| 40 | 40 | ||
| 41 | obj-y += sched_pres.o | 41 | obj-y += sched_pres.o |
| 42 | obj-y += mc2_common.o sched_mc2.o | 42 | obj-y += mc2_common.o sched_mc2.o |
| 43 | obj-y += pgm.o | ||
diff --git a/litmus/litmus.c b/litmus/litmus.c index d72039067689..d2815f52876e 100644 --- a/litmus/litmus.c +++ b/litmus/litmus.c | |||
| @@ -140,10 +140,16 @@ asmlinkage long sys_set_rt_task_param(pid_t pid, struct rt_task __user * param) | |||
| 140 | if (tp.relative_deadline == 0) | 140 | if (tp.relative_deadline == 0) |
| 141 | tp.relative_deadline = tp.period; | 141 | tp.relative_deadline = tp.period; |
| 142 | 142 | ||
| 143 | if (tp.exec_cost <= 0) | 143 | if (tp.exec_cost <= 0) { |
| 144 | printk(KERN_INFO "litmus: real-time task %d rejected " | ||
| 145 | "because declared job execution time <= 0.", pid); | ||
| 144 | goto out_unlock; | 146 | goto out_unlock; |
| 145 | if (tp.period <= 0) | 147 | } |
| 148 | if (tp.period <= 0) { | ||
| 149 | printk(KERN_INFO "litmus: real-time task %d rejected " | ||
| 150 | "because declared job period <= 0.", pid); | ||
| 146 | goto out_unlock; | 151 | goto out_unlock; |
| 152 | } | ||
| 147 | if (min(tp.relative_deadline, tp.period) < tp.exec_cost) /*density check*/ | 153 | if (min(tp.relative_deadline, tp.period) < tp.exec_cost) /*density check*/ |
| 148 | { | 154 | { |
| 149 | printk(KERN_INFO "litmus: real-time task %d rejected " | 155 | printk(KERN_INFO "litmus: real-time task %d rejected " |
| @@ -169,6 +175,13 @@ asmlinkage long sys_set_rt_task_param(pid_t pid, struct rt_task __user * param) | |||
| 169 | goto out_unlock; | 175 | goto out_unlock; |
| 170 | } | 176 | } |
| 171 | 177 | ||
| 178 | if (tp.pgm_type < PGM_NOT_A_NODE || tp.pgm_type > PGM_INTERNAL) { | ||
| 179 | printk(KERN_INFO "litmus: real-time task %d rejected " | ||
| 180 | "because of unknown PGM node type specified (%d)\n", | ||
| 181 | pid, tp.pgm_type); | ||
| 182 | goto out_unlock; | ||
| 183 | } | ||
| 184 | |||
| 172 | target->rt_param.task_params = tp; | 185 | target->rt_param.task_params = tp; |
| 173 | 186 | ||
| 174 | retval = 0; | 187 | retval = 0; |
| @@ -549,6 +562,10 @@ long litmus_admit_task(struct task_struct* tsk) | |||
| 549 | if (get_rt_relative_deadline(tsk) == 0 || | 562 | if (get_rt_relative_deadline(tsk) == 0 || |
| 550 | get_exec_cost(tsk) > | 563 | get_exec_cost(tsk) > |
| 551 | min(get_rt_relative_deadline(tsk), get_rt_period(tsk)) ) { | 564 | min(get_rt_relative_deadline(tsk), get_rt_period(tsk)) ) { |
| 565 | printk(KERN_INFO "litmus: invalid task parameters " | ||
| 566 | "(e = %lu, p = %lu, d = %lu)\n", | ||
| 567 | get_exec_cost(tsk), get_rt_period(tsk), | ||
| 568 | get_rt_relative_deadline(tsk)); | ||
| 552 | TRACE_TASK(tsk, | 569 | TRACE_TASK(tsk, |
| 553 | "litmus admit: invalid task parameters " | 570 | "litmus admit: invalid task parameters " |
| 554 | "(e = %lu, p = %lu, d = %lu)\n", | 571 | "(e = %lu, p = %lu, d = %lu)\n", |
| @@ -580,6 +597,7 @@ long litmus_admit_task(struct task_struct* tsk) | |||
| 580 | if (!retval) { | 597 | if (!retval) { |
| 581 | sched_trace_task_name(tsk); | 598 | sched_trace_task_name(tsk); |
| 582 | sched_trace_task_param(tsk); | 599 | sched_trace_task_param(tsk); |
| 600 | sched_trace_pgm_param(tsk); | ||
| 583 | atomic_inc(&rt_task_count); | 601 | atomic_inc(&rt_task_count); |
| 584 | } | 602 | } |
| 585 | 603 | ||
diff --git a/litmus/pgm.c b/litmus/pgm.c new file mode 100644 index 000000000000..db3378ff803d --- /dev/null +++ b/litmus/pgm.c | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | /* litmus/pgm.c - common pgm control code | ||
| 2 | */ | ||
| 3 | |||
| 4 | #include <linux/sched.h> | ||
| 5 | #include <litmus/litmus.h> | ||
| 6 | #include <litmus/pgm.h> | ||
| 7 | #include <litmus/sched_trace.h> | ||
| 8 | |||
| 9 | /* Only readjust release/deadline if difference is over a given threshold. | ||
| 10 | It's a weak method for accounting overheads. Ideally, we'd know the last | ||
| 11 | time t was woken up by its last predecessor, rather than having to look | ||
| 12 | at 'now'. Adjustment threshold currently set to 200us. */ | ||
| 13 | #define ADJUSTMENT_THRESH_NS (200*1000LL) | ||
| 14 | |||
| 15 | int setup_pgm_release(struct task_struct* t) | ||
| 16 | { | ||
| 17 | int shifted_release = 0; | ||
| 18 | |||
| 19 | /* approximate time last predecessor gave us tokens */ | ||
| 20 | lt_t now = litmus_clock(); | ||
| 21 | |||
| 22 | TRACE_TASK(t, "is starting a new PGM job: waiting:%d\n", | ||
| 23 | tsk_rt(t)->ctrl_page->pgm_waiting); | ||
| 24 | |||
| 25 | BUG_ON(!tsk_rt(t)->ctrl_page->pgm_waiting); | ||
| 26 | |||
| 27 | /* Adjust release time if we got the last tokens after release of this job. | ||
| 28 | This is possible since PGM jobs are early-released. Don't shift our | ||
| 29 | deadline if we got the tokens earlier than expected. */ | ||
| 30 | if (now > tsk_rt(t)->job_params.release) { | ||
| 31 | long long diff_ns = now - tsk_rt(t)->job_params.release; | ||
| 32 | if (diff_ns > ADJUSTMENT_THRESH_NS) { | ||
| 33 | lt_t adj_deadline = now + get_rt_relative_deadline(t); | ||
| 34 | |||
| 35 | TRACE_TASK(t, "adjusting PGM release time from (r = %llu, d = %llu) " | ||
| 36 | "to (r = %llu, d = %llu)\n", | ||
| 37 | tsk_rt(t)->job_params.release, tsk_rt(t)->job_params.deadline, | ||
| 38 | now, adj_deadline); | ||
| 39 | |||
| 40 | tsk_rt(t)->job_params.release = now; | ||
| 41 | tsk_rt(t)->job_params.deadline = adj_deadline; | ||
| 42 | shifted_release = 1; | ||
| 43 | } | ||
| 44 | else { | ||
| 45 | TRACE_TASK(t, "adjustment falls below threshold. %lld < %lld\n", | ||
| 46 | diff_ns, ADJUSTMENT_THRESH_NS); | ||
| 47 | } | ||
| 48 | } | ||
| 49 | else { | ||
| 50 | TRACE_TASK(t, "got tokens early--no need to adjust release. " | ||
| 51 | "cur time = %llu, release time = %llu\n", | ||
| 52 | now, tsk_rt(t)->job_params.release); | ||
| 53 | } | ||
| 54 | |||
| 55 | /* possible that there can be multiple instances of pgm_release logged. | ||
| 56 | analysis tools should filter out all but the last pgm_release for | ||
| 57 | a given job release */ | ||
| 58 | sched_trace_pgm_release(t); | ||
| 59 | |||
| 60 | return shifted_release; | ||
| 61 | } | ||
diff --git a/litmus/sched_mc2.c b/litmus/sched_mc2.c index a310723dce24..9ed92d355d7a 100644 --- a/litmus/sched_mc2.c +++ b/litmus/sched_mc2.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <litmus/mc2_common.h> | 25 | #include <litmus/mc2_common.h> |
| 26 | #include <litmus/reservation.h> | 26 | #include <litmus/reservation.h> |
| 27 | #include <litmus/polling_reservations.h> | 27 | #include <litmus/polling_reservations.h> |
| 28 | #include <litmus/pgm.h> | ||
| 28 | 29 | ||
| 29 | #define BUDGET_ENFORCEMENT_AT_C 0 | 30 | #define BUDGET_ENFORCEMENT_AT_C 0 |
| 30 | 31 | ||
| @@ -614,14 +615,82 @@ static struct task_struct* mc2_schedule(struct task_struct * prev) | |||
| 614 | /* next == NULL means "schedule background work". */ | 615 | /* next == NULL means "schedule background work". */ |
| 615 | lt_t now; | 616 | lt_t now; |
| 616 | struct mc2_cpu_state *state = local_cpu_state(); | 617 | struct mc2_cpu_state *state = local_cpu_state(); |
| 618 | int sleep, preempt, np, exists, blocks; | ||
| 617 | 619 | ||
| 618 | pre_schedule(prev, state->cpu); | 620 | pre_schedule(prev, state->cpu); |
| 619 | 621 | ||
| 620 | raw_spin_lock(&_global_env.lock); | 622 | raw_spin_lock(&_global_env.lock); |
| 621 | raw_spin_lock(&state->lock); | 623 | raw_spin_lock(&state->lock); |
| 622 | 624 | ||
| 623 | //BUG_ON(state->scheduled && state->scheduled != prev); | 625 | /* sanity check */ |
| 624 | //BUG_ON(state->scheduled && !is_realtime(prev)); | 626 | BUG_ON(state->scheduled && state->scheduled != prev); |
| 627 | BUG_ON(state->scheduled && !is_realtime(prev)); | ||
| 628 | BUG_ON(is_realtime(prev) && !state->scheduled); | ||
| 629 | |||
| 630 | /* (0) Determine state */ | ||
| 631 | exists = state->scheduled != NULL; | ||
| 632 | blocks = exists && !is_running(state->scheduled); | ||
| 633 | sleep = exists && is_completed(state->scheduled); | ||
| 634 | np = exists && is_np(state->scheduled); | ||
| 635 | preempt = _lowest_prio_cpu.cpu_entries[state->cpu].will_schedule; | ||
| 636 | |||
| 637 | if (exists) { | ||
| 638 | if (is_pgm_sending(state->scheduled)) { | ||
| 639 | if (!is_pgm_satisfied(state->scheduled)) { | ||
| 640 | if (!is_priority_boosted(state->scheduled)) { | ||
| 641 | TRACE_TASK(state->scheduled, "is sending PGM tokens and needs boosting.\n"); | ||
| 642 | BUG_ON(is_pgm_satisfied(state->scheduled)); | ||
| 643 | |||
| 644 | /* We are either sending tokens or waiting for tokes. | ||
| 645 | If waiting: Boost priority so we'll be scheduled | ||
| 646 | immediately when needed tokens arrive. | ||
| 647 | If sending: Boost priority so no one (specifically, our | ||
| 648 | consumers) will preempt us while signalling the token | ||
| 649 | transmission. | ||
| 650 | */ | ||
| 651 | tsk_rt(state->scheduled)->priority_boosted = 1; | ||
| 652 | tsk_rt(state->scheduled)->boost_start_time = litmus_clock(); | ||
| 653 | |||
| 654 | if (likely(!blocks)) { | ||
| 655 | task_departs(state->scheduled, is_completed(prev)); | ||
| 656 | task_arrives(state, state->scheduled); | ||
| 657 | /* we may regain the processor */ | ||
| 658 | if (preempt) { | ||
| 659 | //preempt = resched_cpu[state->cpu]; | ||
| 660 | litmus_reschedule_local(); | ||
| 661 | if (!preempt) { | ||
| 662 | TRACE_TASK(state->scheduled, "blocked preemption by lazy boosting.\n"); | ||
| 663 | } | ||
| 664 | } | ||
| 665 | } | ||
| 666 | } | ||
| 667 | } | ||
| 668 | else { /* sending is satisfied */ | ||
| 669 | tsk_rt(state->scheduled)->ctrl_page->pgm_sending = 0; | ||
| 670 | tsk_rt(state->scheduled)->ctrl_page->pgm_satisfied = 0; | ||
| 671 | |||
| 672 | if (is_priority_boosted(state->scheduled)) { | ||
| 673 | TRACE_TASK(state->scheduled, | ||
| 674 | "is done sending PGM tokens must relinquish boosting.\n"); | ||
| 675 | /* clear boosting */ | ||
| 676 | tsk_rt(state->scheduled)->priority_boosted = 0; | ||
| 677 | if(likely(!blocks)) { | ||
| 678 | /* recheck priority */ | ||
| 679 | task_departs(state->scheduled, is_completed(prev)); | ||
| 680 | task_arrives(state, state->scheduled); | ||
| 681 | /* we may lose the processor */ | ||
| 682 | if (!preempt) { | ||
| 683 | //preempt = resched_cpu[state->cpu]; | ||
| 684 | litmus_reschedule_local(); | ||
| 685 | if (preempt) { | ||
| 686 | TRACE_TASK(state->scheduled, "preempted by lazy unboosting.\n"); | ||
| 687 | } | ||
| 688 | } | ||
| 689 | } | ||
| 690 | } | ||
| 691 | } | ||
| 692 | } | ||
| 693 | } | ||
| 625 | 694 | ||
| 626 | /* update time */ | 695 | /* update time */ |
| 627 | state->sup_env.will_schedule = true; | 696 | state->sup_env.will_schedule = true; |
| @@ -701,6 +770,9 @@ static void resume_legacy_task_model_updates(struct task_struct *tsk) | |||
| 701 | sched_trace_task_release(tsk); | 770 | sched_trace_task_release(tsk); |
| 702 | } | 771 | } |
| 703 | } | 772 | } |
| 773 | //if (is_pgm_waiting(tsk)) { | ||
| 774 | // setup_pgm_release(tsk); | ||
| 775 | //} | ||
| 704 | } | 776 | } |
| 705 | 777 | ||
| 706 | /* mc2_task_resume - Called when the state of tsk changes back to | 778 | /* mc2_task_resume - Called when the state of tsk changes back to |
diff --git a/litmus/sched_task_trace.c b/litmus/sched_task_trace.c index 3a6756deb32f..784b18ecfd8b 100644 --- a/litmus/sched_task_trace.c +++ b/litmus/sched_task_trace.c | |||
| @@ -238,3 +238,26 @@ feather_callback void do_sched_trace_action(unsigned long id, | |||
| 238 | put_record(rec); | 238 | put_record(rec); |
| 239 | } | 239 | } |
| 240 | } | 240 | } |
| 241 | |||
| 242 | feather_callback void do_sched_trace_pgm_param(unsigned long id, unsigned long _task) | ||
| 243 | { | ||
| 244 | struct task_struct *t = (struct task_struct*) _task; | ||
| 245 | struct st_event_record* rec = get_record(ST_PGM_PARAM, t); | ||
| 246 | if (rec) { | ||
| 247 | rec->data.pgm_param.node_type = tsk_rt(t)->task_params.pgm_type; | ||
| 248 | rec->data.pgm_param.graph_pid = t->tgid; | ||
| 249 | rec->data.pgm_param.expected_graph_etoe = tsk_rt(t)->task_params.pgm_expected_etoe; | ||
| 250 | put_record(rec); | ||
| 251 | } | ||
| 252 | } | ||
| 253 | |||
| 254 | feather_callback void do_sched_trace_pgm_release(unsigned long id, unsigned long _task) | ||
| 255 | { | ||
| 256 | struct task_struct *t = (struct task_struct*) _task; | ||
| 257 | struct st_event_record* rec = get_record(ST_PGM_RELEASE, t); | ||
| 258 | if (rec) { | ||
| 259 | rec->data.pgm_release.release = get_release(t); | ||
| 260 | rec->data.pgm_release.deadline = get_deadline(t); | ||
| 261 | put_record(rec); | ||
| 262 | } | ||
| 263 | } | ||
