aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/sched_mc_ce.c
diff options
context:
space:
mode:
Diffstat (limited to 'litmus/sched_mc_ce.c')
-rw-r--r--litmus/sched_mc_ce.c49
1 files changed, 43 insertions, 6 deletions
diff --git a/litmus/sched_mc_ce.c b/litmus/sched_mc_ce.c
index 63b0470e1f52..c5066918f282 100644
--- a/litmus/sched_mc_ce.c
+++ b/litmus/sched_mc_ce.c
@@ -52,6 +52,10 @@ struct ce_pid_entry {
52 unsigned int expected_job; 52 unsigned int expected_job;
53}; 53};
54 54
55/*
56 * Each CPU needs a mapping of level A ID (integer) to struct pid so that we
57 * can get its task struct.
58 */
55struct ce_pid_table { 59struct ce_pid_table {
56 struct ce_pid_entry entries[CONFIG_PLUGIN_MC_LEVEL_A_MAX_TASKS]; 60 struct ce_pid_entry entries[CONFIG_PLUGIN_MC_LEVEL_A_MAX_TASKS];
57 int num_pid_entries; 61 int num_pid_entries;
@@ -434,7 +438,10 @@ void mc_ce_task_exit_common(struct task_struct *ts)
434 * Timer stuff 438 * Timer stuff
435 **********************************************************/ 439 **********************************************************/
436 440
437void mc_ce_timer_callback_common(struct domain *dom, struct hrtimer *timer) 441/*
442 * Returns the next absolute time that the timer should fire.
443 */
444lt_t mc_ce_timer_callback_common(struct domain *dom)
438{ 445{
439 /* relative and absolute times for cycles */ 446 /* relative and absolute times for cycles */
440 lt_t now, offset_rel, cycle_start_abs, next_timer_abs; 447 lt_t now, offset_rel, cycle_start_abs, next_timer_abs;
@@ -455,9 +462,7 @@ void mc_ce_timer_callback_common(struct domain *dom, struct hrtimer *timer)
455 cycle_start_abs = now - offset_rel; 462 cycle_start_abs = now - offset_rel;
456 idx = mc_ce_schedule_at(dom, offset_rel); 463 idx = mc_ce_schedule_at(dom, offset_rel);
457 pid_entry = get_pid_entry(ce_data->cpu, idx); 464 pid_entry = get_pid_entry(ce_data->cpu, idx);
458 /* set the timer to fire at the next cycle start */
459 next_timer_abs = cycle_start_abs + pid_entry->acc_time; 465 next_timer_abs = cycle_start_abs + pid_entry->acc_time;
460 hrtimer_set_expires(timer, ns_to_ktime(next_timer_abs));
461 466
462 STRACE("timer: now: %llu offset_rel: %llu cycle_start_abs: %llu " 467 STRACE("timer: now: %llu offset_rel: %llu cycle_start_abs: %llu "
463 "next_timer_abs: %llu\n", now, offset_rel, 468 "next_timer_abs: %llu\n", now, offset_rel,
@@ -495,32 +500,52 @@ void mc_ce_timer_callback_common(struct domain *dom, struct hrtimer *timer)
495 sched_trace_task_release(should_schedule); 500 sched_trace_task_release(should_schedule);
496 set_rt_flags(ce_data->should_schedule, RT_F_RUNNING); 501 set_rt_flags(ce_data->should_schedule, RT_F_RUNNING);
497 } 502 }
503 return next_timer_abs;
498} 504}
499 505
500/* 506/*
501 * What to do when a timer fires. The timer should only be armed if the number 507 * What to do when a timer fires. The timer should only be armed if the number
502 * of PID entries is positive. 508 * of PID entries is positive.
503 */ 509 */
510#ifdef CONFIG_MERGE_TIMERS
511static void mc_ce_timer_callback(struct rt_event *e)
512#else
504static enum hrtimer_restart mc_ce_timer_callback(struct hrtimer *timer) 513static enum hrtimer_restart mc_ce_timer_callback(struct hrtimer *timer)
514#endif
505{ 515{
506 struct ce_dom_data *ce_data; 516 struct ce_dom_data *ce_data;
507 unsigned long flags; 517 unsigned long flags;
508 struct domain *dom; 518 struct domain *dom;
509 519 lt_t next_timer_abs;
520#ifdef CONFIG_MERGE_TIMERS
521 struct event_group *event_group;
522 ce_data = container_of(e, struct ce_dom_data, event);
523 event_group = get_event_group_for(ce_data->cpu);
524#else
510 ce_data = container_of(timer, struct ce_dom_data, timer); 525 ce_data = container_of(timer, struct ce_dom_data, timer);
526#endif
511 dom = get_domain_for(ce_data->cpu); 527 dom = get_domain_for(ce_data->cpu);
512 528
513 TRACE("timer callback on CPU %d (before lock)\n", ce_data->cpu); 529 TRACE("timer callback on CPU %d (before lock)\n", ce_data->cpu);
514 530
515 raw_spin_lock_irqsave(dom->lock, flags); 531 raw_spin_lock_irqsave(dom->lock, flags);
516 mc_ce_timer_callback_common(dom, timer); 532 next_timer_abs = mc_ce_timer_callback_common(dom);
533
534 /* setup an event or timer for the next release in the CE schedule */
535#ifdef CONFIG_MERGE_TIMERS
536 add_event(event_group, e, next_timer_abs);
537#else
538 hrtimer_set_expires(timer, ns_to_ktime(next_timer_abs));
539#endif
517 540
518 if (ce_data->scheduled != ce_data->should_schedule) 541 if (ce_data->scheduled != ce_data->should_schedule)
519 preempt_if_preemptable(ce_data->scheduled, ce_data->cpu); 542 preempt_if_preemptable(ce_data->scheduled, ce_data->cpu);
520 543
521 raw_spin_unlock_irqrestore(dom->lock, flags); 544 raw_spin_unlock_irqrestore(dom->lock, flags);
522 545
546#ifndef CONFIG_MERGE_TIMERS
523 return HRTIMER_RESTART; 547 return HRTIMER_RESTART;
548#endif
524} 549}
525 550
526/* 551/*
@@ -530,7 +555,10 @@ static int cancel_all_timers(void)
530{ 555{
531 struct ce_dom_data *ce_data; 556 struct ce_dom_data *ce_data;
532 struct domain *dom; 557 struct domain *dom;
533 int cpu, cancel_res, ret = 0; 558 int cpu, ret = 0;
559#ifndef CONFIG_MERGE_TIMERS
560 int cancel_res;
561#endif
534 562
535 TRACE("cancel all timers\n"); 563 TRACE("cancel all timers\n");
536 564
@@ -538,10 +566,14 @@ static int cancel_all_timers(void)
538 dom = get_domain_for(cpu); 566 dom = get_domain_for(cpu);
539 ce_data = dom->data; 567 ce_data = dom->data;
540 ce_data->should_schedule = NULL; 568 ce_data->should_schedule = NULL;
569#ifdef CONFIG_MERGE_TIMERS
570 cancel_event(&ce_data->event);
571#else
541 cancel_res = hrtimer_cancel(&ce_data->timer); 572 cancel_res = hrtimer_cancel(&ce_data->timer);
542 atomic_set(&ce_data->timer_info.state, 573 atomic_set(&ce_data->timer_info.state,
543 HRTIMER_START_ON_INACTIVE); 574 HRTIMER_START_ON_INACTIVE);
544 ret = ret || cancel_res; 575 ret = ret || cancel_res;
576#endif
545 } 577 }
546 return ret; 578 return ret;
547} 579}
@@ -570,9 +602,14 @@ static void arm_all_timers(void)
570 for (idx = 0; idx < pid_table->num_pid_entries; idx++) { 602 for (idx = 0; idx < pid_table->num_pid_entries; idx++) {
571 pid_table->entries[idx].expected_job = 0; 603 pid_table->entries[idx].expected_job = 0;
572 } 604 }
605#ifdef CONFIG_MERGE_TIMERS
606 TRACE("adding event for CPU %d\n", cpu);
607 add_event(get_event_group_for(cpu), &ce_data->event, start);
608#else
573 TRACE("arming timer for CPU %d\n", cpu); 609 TRACE("arming timer for CPU %d\n", cpu);
574 hrtimer_start_on(cpu, &ce_data->timer_info, &ce_data->timer, 610 hrtimer_start_on(cpu, &ce_data->timer_info, &ce_data->timer,
575 ns_to_ktime(start), HRTIMER_MODE_ABS_PINNED); 611 ns_to_ktime(start), HRTIMER_MODE_ABS_PINNED);
612#endif
576 } 613 }
577} 614}
578 615