1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
#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;
};
struct mc_job {
int is_ghost:1;
lt_t ghost_budget;
};
#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;
struct mc_job mc_job;
};
#define tsk_mc_data(t) (tsk_rt(t)->mc_data)
#define tsk_mc_crit(t) (tsk_mc_data(t)->mc_task.crit)
#define is_ghost(t) (tsk_mc_data(t)->mc_job.is_ghost)
#define TS "(%s/%d:%d:%s)"
#define TA(t) (t) ? (is_ghost(t)) ? "ghost" : t->comm : "NULL", \
(t) ? t->pid : 1, \
(t) ? t->rt_param.job_params.job_no : 1, \
(t && get_task_domain(t)) ? get_task_domain(t)->name : ""
#define STRACE(fmt, args...) \
sched_trace_log_message("%d P%d [%s@%s:%d]: " fmt, \
TRACE_ARGS, ## args)
#define TRACE_MC_TASK(t, fmt, args...) \
STRACE(TS " " fmt "\n", TA(t), ##args)
/*
* The MC-CE scheduler uses this as domain data.
*/
struct ce_dom_data {
int cpu;
struct task_struct *scheduled, *should_schedule;
/*
* Each CPU needs a mapping of level A ID (integer) to struct pid so
* that we can get its task struct.
*/
struct hrtimer_start_on_info timer_info;
struct hrtimer timer;
};
/**
* 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
* @timer For ghost task budget enforcement
* @node Used to sort crit_entries by preemptability in global domains
*/
struct crit_entry {
enum crit_level level;
struct task_struct* linked;
struct domain* domain;
int usable;
#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*);
void mc_ce_timer_callback_common(domain_t*, struct hrtimer*);
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);
#endif /* __KERNEL__ */
#endif
|