#ifndef _LINUX_SCHED_MC_H_ #define _LINUX_SCHED_MC_H_ /* criticality levels */ enum crit_level { /* probably don't need to assign these (paranoid) */ CRIT_LEVEL_A = 0, CRIT_LEVEL_B = 1, CRIT_LEVEL_C = 2, NUM_CRIT_LEVELS = 3, }; struct mc_task { enum crit_level crit; int lvl_a_id; int lvl_a_eligible; }; #ifdef __KERNEL__ /* * These are used only in the kernel. Userspace programs like RTSpin won't see * them. */ struct mc_data { struct mc_task mc_task; }; #define tsk_mc_data(t) (tsk_rt(t)->mc_data) #define tsk_mc_crit(t) \ (tsk_mc_data(t) ? tsk_mc_data(t)->mc_task.crit : CRIT_LEVEL_C) #define is_ghost(t) \ (get_rt_job(t) < get_user_job(t) && (tsk_rt(t)->completed)) #define ce_sid(ce) \ (-(num_online_cpus() + (ce)->level * num_online_cpus() + crit_cpu(ce)->cpu + 1)) #define TS "(%s/%d:%d:%d:%s)" #define TA(t) (t) ? is_ghost(t) ? "ghost" : t->comm : "NULL", \ (t) ? t->pid : 1, \ (t) ? get_rt_job(t) : 1, \ (t) ? get_user_job(t) : 1, \ (t && get_task_domain(t)) ? get_task_domain(t)->name : "" #define TRACE_MC_TASK(t, fmt, args...) \ STRACE(TS " " fmt, TA(t), ##args) #define TRACE_CRIT_ENTRY(ce, fmt, args...) \ STRACE("%s P%d, linked=" TS " " fmt, \ (ce)->domain->name, crit_cpu(ce)->cpu, TA((ce)->server.linked), ##args) /* * The MC-CE scheduler uses this as domain data. */ struct ce_dom_data { int cpu; struct task_struct *scheduled, *should_schedule; #ifdef CONFIG_MERGE_TIMERS struct rt_event event; #else struct hrtimer timer; struct hrtimer_start_on_info timer_info; #endif }; /** * struct crit_entry - State of a CPU within each criticality level system. * @level Criticality level of this entry * @linked Logically running task, ghost or regular * @domain Domain from which to draw tasks * @usable False if a higher criticality task is running * @event For ghost task budget enforcement (merge timers) * @timer For ghost task budget enforcement (not merge timers) * @node Used to sort crit_entries by preemptability in global domains */ struct crit_entry { struct server server; enum crit_level level; struct domain* domain; #ifdef CONFIG_MERGE_TIMERS struct rt_event event; #else struct hrtimer timer; #endif struct bheap_node* node; }; /** * struct domain_data - Wrap domains with related CPU state * @domain A domain for a criticality level * @heap The preemptable heap of crit entries (for global domains) * @crit_entry The crit entry for this domain (for partitioned domains) */ struct domain_data { struct domain domain; struct bheap* heap; struct crit_entry* crit_entry; }; /* * Functions that are used with the MC-CE plugin. */ long mc_ce_set_domains(const int, struct domain_data*[]); unsigned int mc_ce_get_expected_job(const int, const int); /* * These functions are (lazily) inserted into the MC plugin code so that it * manipulates the MC-CE state. */ long mc_ce_admit_task_common(struct task_struct*); void mc_ce_task_exit_common(struct task_struct*); lt_t mc_ce_timer_callback_common(domain_t*); void mc_ce_release_at_common(struct task_struct*, lt_t); long mc_ce_activate_plugin_common(void); long mc_ce_deactivate_plugin_common(void); void mc_ce_job_completion(struct domain *dom, struct task_struct *ts); #endif /* __KERNEL__ */ #endif