aboutsummaryrefslogtreecommitdiffstats
path: root/include/litmus
diff options
context:
space:
mode:
Diffstat (limited to 'include/litmus')
-rw-r--r--include/litmus/cache_proc.h5
-rw-r--r--include/litmus/litmus.h7
-rw-r--r--include/litmus/mc2_common.h31
-rw-r--r--include/litmus/polling_reservations.h36
-rw-r--r--include/litmus/reservation.h256
-rw-r--r--include/litmus/rt_param.h51
-rw-r--r--include/litmus/sched_plugin.h8
-rw-r--r--include/litmus/trace.h16
8 files changed, 408 insertions, 2 deletions
diff --git a/include/litmus/cache_proc.h b/include/litmus/cache_proc.h
index 586224118435..962851da34cc 100644
--- a/include/litmus/cache_proc.h
+++ b/include/litmus/cache_proc.h
@@ -4,6 +4,11 @@
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6void litmus_setup_lockdown(void __iomem*, u32); 6void litmus_setup_lockdown(void __iomem*, u32);
7void enter_irq_mode(void);
8void exit_irq_mode(void);
9void flush_cache(int all);
10
11extern struct page *new_alloc_page_color(unsigned long color);
7 12
8#endif 13#endif
9 14
diff --git a/include/litmus/litmus.h b/include/litmus/litmus.h
index a6eb534ee0fa..441210c84ed8 100644
--- a/include/litmus/litmus.h
+++ b/include/litmus/litmus.h
@@ -113,6 +113,13 @@ static inline lt_t litmus_clock(void)
113 ((current)->state == TASK_RUNNING || \ 113 ((current)->state == TASK_RUNNING || \
114 preempt_count() & PREEMPT_ACTIVE) 114 preempt_count() & PREEMPT_ACTIVE)
115 115
116#define is_running(t) \
117 ((t)->state == TASK_RUNNING || \
118 task_thread_info(t)->preempt_count & PREEMPT_ACTIVE)
119
120#define is_blocked(t) \
121 (!is_running(t))
122
116#define is_released(t, now) \ 123#define is_released(t, now) \
117 (lt_before_eq(get_release(t), now)) 124 (lt_before_eq(get_release(t), now))
118#define is_tardy(t, now) \ 125#define is_tardy(t, now) \
diff --git a/include/litmus/mc2_common.h b/include/litmus/mc2_common.h
new file mode 100644
index 000000000000..e3c0af28f1b9
--- /dev/null
+++ b/include/litmus/mc2_common.h
@@ -0,0 +1,31 @@
1/*
2 * MC^2 common data structures
3 */
4
5#ifndef __UNC_MC2_COMMON_H__
6#define __UNC_MC2_COMMON_H__
7
8enum crit_level {
9 CRIT_LEVEL_A = 0,
10 CRIT_LEVEL_B = 1,
11 CRIT_LEVEL_C = 2,
12 NUM_CRIT_LEVELS = 3,
13};
14
15struct mc2_task {
16 enum crit_level crit;
17 unsigned int res_id;
18};
19
20#ifdef __KERNEL__
21
22#include <litmus/reservation.h>
23
24#define tsk_mc2_data(t) (tsk_rt(t)->mc2_data)
25
26long mc2_task_client_init(struct task_client *tc, struct mc2_task *mc2_param, struct task_struct *tsk,
27 struct reservation *res);
28
29#endif /* __KERNEL__ */
30
31#endif \ No newline at end of file
diff --git a/include/litmus/polling_reservations.h b/include/litmus/polling_reservations.h
new file mode 100644
index 000000000000..66c9b1e31f20
--- /dev/null
+++ b/include/litmus/polling_reservations.h
@@ -0,0 +1,36 @@
1#ifndef LITMUS_POLLING_RESERVATIONS_H
2#define LITMUS_POLLING_RESERVATIONS_H
3
4#include <litmus/reservation.h>
5
6struct polling_reservation {
7 /* extend basic reservation */
8 struct reservation res;
9
10 lt_t max_budget;
11 lt_t period;
12 lt_t deadline;
13 lt_t offset;
14};
15
16void polling_reservation_init(struct polling_reservation *pres, int use_edf_prio,
17 int use_periodic_polling, lt_t budget, lt_t period, lt_t deadline, lt_t offset);
18
19struct table_driven_reservation {
20 /* extend basic reservation */
21 struct reservation res;
22
23 lt_t major_cycle;
24 unsigned int next_interval;
25 unsigned int num_intervals;
26 struct lt_interval *intervals;
27
28 /* info about current scheduling slot */
29 struct lt_interval cur_interval;
30 lt_t major_cycle_start;
31};
32
33void table_driven_reservation_init(struct table_driven_reservation *tdres,
34 lt_t major_cycle, struct lt_interval *intervals, unsigned int num_intervals);
35
36#endif
diff --git a/include/litmus/reservation.h b/include/litmus/reservation.h
new file mode 100644
index 000000000000..7e022b34470f
--- /dev/null
+++ b/include/litmus/reservation.h
@@ -0,0 +1,256 @@
1#ifndef LITMUS_RESERVATION_H
2#define LITMUS_RESERVATION_H
3
4#include <linux/list.h>
5#include <linux/hrtimer.h>
6
7struct reservation_client;
8struct reservation_environment;
9struct reservation;
10
11typedef enum {
12 /* reservation has no clients, is not consuming budget */
13 RESERVATION_INACTIVE = 0,
14
15 /* reservation has clients, consumes budget when scheduled */
16 RESERVATION_ACTIVE,
17
18 /* reservation has no clients, but may be consuming budget */
19 RESERVATION_ACTIVE_IDLE,
20
21 /* Reservation has no budget and waits for
22 * replenishment. May or may not have clients. */
23 RESERVATION_DEPLETED,
24} reservation_state_t;
25
26
27/* ************************************************************************** */
28
29/* Select which task to dispatch. If NULL is returned, it means there is nothing
30 * to schedule right now and background work can be scheduled. */
31typedef struct task_struct * (*dispatch_t) (
32 struct reservation_client *client
33);
34
35/* Something that can be managed in a reservation and that can yield
36 * a process for dispatching. Contains a pointer to the reservation
37 * to which it "belongs". */
38struct reservation_client {
39 struct list_head list;
40 struct reservation* reservation;
41 dispatch_t dispatch;
42};
43
44
45/* ************************************************************************** */
46
47/* Called by reservations to request state change. */
48typedef void (*reservation_change_state_t) (
49 struct reservation_environment* env,
50 struct reservation *res,
51 reservation_state_t new_state
52);
53
54/* The framework within wich reservations operate. */
55struct reservation_environment {
56 lt_t time_zero;
57 lt_t current_time;
58
59 /* services invoked by reservations */
60 reservation_change_state_t change_state;
61};
62
63
64/* ************************************************************************** */
65
66/* A new client is added or an existing client resumes. */
67typedef void (*client_arrives_t) (
68 struct reservation *reservation,
69 struct reservation_client *client
70);
71
72/* A client suspends or terminates. */
73typedef void (*client_departs_t) (
74 struct reservation *reservation,
75 struct reservation_client *client,
76 int did_signal_job_completion
77);
78
79/* A previously requested replenishment has occurred. */
80typedef void (*on_replenishment_timer_t) (
81 struct reservation *reservation
82);
83
84/* Update the reservation's budget to reflect execution or idling. */
85typedef void (*drain_budget_t) (
86 struct reservation *reservation,
87 lt_t how_much
88);
89
90/* Select a ready task from one of the clients for scheduling. */
91typedef struct task_struct* (*dispatch_client_t) (
92 struct reservation *reservation,
93 lt_t *time_slice /* May be used to force rescheduling after
94 some amount of time. 0 => no limit */
95);
96
97
98struct reservation_ops {
99 dispatch_client_t dispatch_client;
100
101 client_arrives_t client_arrives;
102 client_departs_t client_departs;
103
104 on_replenishment_timer_t replenish;
105 drain_budget_t drain_budget;
106};
107
108struct reservation {
109 /* used to queue in environment */
110 struct list_head list;
111
112 reservation_state_t state;
113 unsigned int id;
114
115 /* exact meaning defined by impl. */
116 lt_t priority;
117 lt_t cur_budget;
118 lt_t next_replenishment;
119
120 /* budget stats */
121 lt_t budget_consumed; /* how much budget consumed in this allocation cycle? */
122 lt_t budget_consumed_total;
123
124 /* interaction with framework */
125 struct reservation_environment *env;
126 struct reservation_ops *ops;
127
128 struct list_head clients;
129
130 /* for global env. */
131 int scheduled_on;
132 int event_added;
133 /* for blocked by ghost. Do not charge budget when ACTIVE */
134 int blocked_by_ghost;
135 /* ghost_job. If it is clear, do not charge budget when ACTIVE_IDLE */
136 int is_ghost;
137};
138
139void reservation_init(struct reservation *res);
140
141/* Default implementations */
142
143/* simply select the first client in the list, set *for_at_most to zero */
144struct task_struct* default_dispatch_client(
145 struct reservation *res,
146 lt_t *for_at_most
147);
148
149/* "connector" reservation client to hook up tasks with reservations */
150struct task_client {
151 struct reservation_client client;
152 struct task_struct *task;
153};
154
155void task_client_init(struct task_client *tc, struct task_struct *task,
156 struct reservation *reservation);
157
158#define SUP_RESCHEDULE_NOW (0)
159#define SUP_NO_SCHEDULER_UPDATE (ULLONG_MAX)
160
161/* A simple uniprocessor (SUP) flat (i.e., non-hierarchical) reservation
162 * environment.
163 */
164struct sup_reservation_environment {
165 struct reservation_environment env;
166
167 /* ordered by priority */
168 struct list_head active_reservations;
169
170 /* ordered by next_replenishment */
171 struct list_head depleted_reservations;
172
173 /* unordered */
174 struct list_head inactive_reservations;
175
176 /* - SUP_RESCHEDULE_NOW means call sup_dispatch() now
177 * - SUP_NO_SCHEDULER_UPDATE means nothing to do
178 * any other value means program a timer for the given time
179 */
180 lt_t next_scheduler_update;
181 /* set to true if a call to sup_dispatch() is imminent */
182 bool will_schedule;
183};
184
185/* Contract:
186 * - before calling into sup_ code, or any reservation methods,
187 * update the time with sup_update_time(); and
188 * - after calling into sup_ code, or any reservation methods,
189 * check next_scheduler_update and program timer or trigger
190 * scheduler invocation accordingly.
191 */
192
193void sup_init(struct sup_reservation_environment* sup_env);
194void sup_add_new_reservation(struct sup_reservation_environment* sup_env,
195 struct reservation* new_res);
196void sup_scheduler_update_after(struct sup_reservation_environment* sup_env,
197 lt_t timeout);
198void sup_update_time(struct sup_reservation_environment* sup_env, lt_t now);
199struct task_struct* sup_dispatch(struct sup_reservation_environment* sup_env);
200
201struct reservation* sup_find_by_id(struct sup_reservation_environment* sup_env,
202 unsigned int id);
203
204/* A global multiprocessor reservation environment. */
205
206typedef enum {
207 EVENT_REPLENISH = 0,
208 EVENT_DRAIN,
209 EVENT_OTHERS,
210} event_type_t;
211
212
213struct next_timer_event {
214 lt_t next_update;
215 int timer_armed_on;
216 unsigned int id;
217 event_type_t type;
218 struct list_head list;
219};
220
221struct gmp_reservation_environment {
222 raw_spinlock_t lock;
223 struct reservation_environment env;
224
225 /* ordered by priority */
226 struct list_head active_reservations;
227
228 /* ordered by next_replenishment */
229 struct list_head depleted_reservations;
230
231 /* unordered */
232 struct list_head inactive_reservations;
233
234 /* timer event ordered by next_update */
235 struct list_head next_events;
236
237 /* (schedule_now == true) means call gmp_dispatch() now */
238 int schedule_now;
239 /* set to true if a call to gmp_dispatch() is imminent */
240 bool will_schedule;
241};
242
243void gmp_init(struct gmp_reservation_environment* gmp_env);
244void gmp_add_new_reservation(struct gmp_reservation_environment* gmp_env,
245 struct reservation* new_res);
246void gmp_add_event_after(struct gmp_reservation_environment* gmp_env,
247 lt_t timeout, unsigned int id, event_type_t type);
248void gmp_print_events(struct gmp_reservation_environment* gmp_env, lt_t now);
249int gmp_update_time(struct gmp_reservation_environment* gmp_env, lt_t now);
250struct task_struct* gmp_dispatch(struct gmp_reservation_environment* gmp_env);
251struct next_timer_event* gmp_find_event_by_id(struct gmp_reservation_environment* gmp_env, unsigned int id);
252struct next_timer_event* gmp_find_event_by_time(struct gmp_reservation_environment* gmp_env, lt_t when);
253struct reservation* gmp_find_by_id(struct gmp_reservation_environment* gmp_env,
254 unsigned int id);
255
256#endif
diff --git a/include/litmus/rt_param.h b/include/litmus/rt_param.h
index 7b9a90965c25..998762051a6b 100644
--- a/include/litmus/rt_param.h
+++ b/include/litmus/rt_param.h
@@ -62,6 +62,7 @@ typedef enum {
62#define LITMUS_MAX_PRIORITY 512 62#define LITMUS_MAX_PRIORITY 512
63#define LITMUS_HIGHEST_PRIORITY 1 63#define LITMUS_HIGHEST_PRIORITY 1
64#define LITMUS_LOWEST_PRIORITY (LITMUS_MAX_PRIORITY - 1) 64#define LITMUS_LOWEST_PRIORITY (LITMUS_MAX_PRIORITY - 1)
65#define LITMUS_NO_PRIORITY UINT_MAX
65 66
66/* Provide generic comparison macros for userspace, 67/* Provide generic comparison macros for userspace,
67 * in case that we change this later. */ 68 * in case that we change this later. */
@@ -71,6 +72,46 @@ typedef enum {
71 ((p) >= LITMUS_HIGHEST_PRIORITY && \ 72 ((p) >= LITMUS_HIGHEST_PRIORITY && \
72 (p) <= LITMUS_LOWEST_PRIORITY) 73 (p) <= LITMUS_LOWEST_PRIORITY)
73 74
75/* reservation support */
76
77typedef enum {
78 PERIODIC_POLLING,
79 SPORADIC_POLLING,
80 TABLE_DRIVEN,
81} reservation_type_t;
82
83struct lt_interval {
84 lt_t start;
85 lt_t end;
86};
87
88#ifndef __KERNEL__
89#define __user
90#endif
91
92struct reservation_config {
93 unsigned int id;
94 lt_t priority;
95 int cpu;
96
97 union {
98 struct {
99 lt_t period;
100 lt_t budget;
101 lt_t relative_deadline;
102 lt_t offset;
103 } polling_params;
104
105 struct {
106 lt_t major_cycle_length;
107 unsigned int num_intervals;
108 struct lt_interval __user *intervals;
109 } table_driven_params;
110 };
111};
112
113/* regular sporadic task support */
114
74struct rt_task { 115struct rt_task {
75 lt_t exec_cost; 116 lt_t exec_cost;
76 lt_t period; 117 lt_t period;
@@ -165,6 +206,7 @@ struct rt_job {
165}; 206};
166 207
167struct pfair_param; 208struct pfair_param;
209struct mc2_task;
168 210
169/* RT task parameters for scheduling extensions 211/* RT task parameters for scheduling extensions
170 * These parameters are inherited during clone and therefore must 212 * These parameters are inherited during clone and therefore must
@@ -246,7 +288,10 @@ struct rt_param {
246 volatile int linked_on; 288 volatile int linked_on;
247 289
248 /* PFAIR/PD^2 state. Allocated on demand. */ 290 /* PFAIR/PD^2 state. Allocated on demand. */
249 struct pfair_param* pfair; 291 union {
292 void *plugin_state;
293 struct pfair_param *pfair;
294 };
250 295
251 /* Fields saved before BE->RT transition. 296 /* Fields saved before BE->RT transition.
252 */ 297 */
@@ -275,6 +320,10 @@ struct rt_param {
275 320
276 /* Pointer to the page shared between userspace and kernel. */ 321 /* Pointer to the page shared between userspace and kernel. */
277 struct control_page * ctrl_page; 322 struct control_page * ctrl_page;
323
324 /* Mixed-criticality specific data */
325 struct mc2_task* mc2_data;
326 unsigned long addr_ctrl_page;
278}; 327};
279 328
280#endif 329#endif
diff --git a/include/litmus/sched_plugin.h b/include/litmus/sched_plugin.h
index f36bb3875f58..4c8aaa6b6674 100644
--- a/include/litmus/sched_plugin.h
+++ b/include/litmus/sched_plugin.h
@@ -83,6 +83,10 @@ typedef void (*synchronous_release_at_t)(lt_t time_zero);
83 * reservation-specific values. */ 83 * reservation-specific values. */
84typedef void (*current_budget_t)(lt_t *used_so_far, lt_t *remaining); 84typedef void (*current_budget_t)(lt_t *used_so_far, lt_t *remaining);
85 85
86/* Reservation creation/removal backends. Meaning of reservation_type and
87 * reservation_id are entirely plugin-specific. */
88typedef long (*reservation_create_t)(int reservation_type, void* __user config);
89typedef long (*reservation_destroy_t)(unsigned int reservation_id, int cpu);
86 90
87/************************ misc routines ***********************/ 91/************************ misc routines ***********************/
88 92
@@ -118,6 +122,10 @@ struct sched_plugin {
118 122
119 current_budget_t current_budget; 123 current_budget_t current_budget;
120 124
125 /* Reservation support */
126 reservation_create_t reservation_create;
127 reservation_destroy_t reservation_destroy;
128
121#ifdef CONFIG_LITMUS_LOCKING 129#ifdef CONFIG_LITMUS_LOCKING
122 /* locking protocols */ 130 /* locking protocols */
123 allocate_lock_t allocate_lock; 131 allocate_lock_t allocate_lock;
diff --git a/include/litmus/trace.h b/include/litmus/trace.h
index 601787214037..24ca412e1184 100644
--- a/include/litmus/trace.h
+++ b/include/litmus/trace.h
@@ -118,6 +118,9 @@ feather_callback void save_cpu_task_latency(unsigned long event, unsigned long w
118#define TS_TICK_START(t) CPU_TTIMESTAMP(110, t) 118#define TS_TICK_START(t) CPU_TTIMESTAMP(110, t)
119#define TS_TICK_END(t) CPU_TTIMESTAMP(111, t) 119#define TS_TICK_END(t) CPU_TTIMESTAMP(111, t)
120 120
121#define TS_RELEASE_C_START CPU_DTIMESTAMP(108, TSK_RT)
122#define TS_RELEASE_C_END CPU_DTIMESTAMP(109, TSK_RT)
123
121#define TS_QUANTUM_BOUNDARY_START CPU_TIMESTAMP_CUR(112) 124#define TS_QUANTUM_BOUNDARY_START CPU_TIMESTAMP_CUR(112)
122#define TS_QUANTUM_BOUNDARY_END CPU_TIMESTAMP_CUR(113) 125#define TS_QUANTUM_BOUNDARY_END CPU_TIMESTAMP_CUR(113)
123 126
@@ -137,6 +140,17 @@ feather_callback void save_cpu_task_latency(unsigned long event, unsigned long w
137#define TS_SEND_RESCHED_START(c) MSG_TIMESTAMP_SENT(190, c) 140#define TS_SEND_RESCHED_START(c) MSG_TIMESTAMP_SENT(190, c)
138#define TS_SEND_RESCHED_END MSG_TIMESTAMP_RECEIVED(191) 141#define TS_SEND_RESCHED_END MSG_TIMESTAMP_RECEIVED(191)
139 142
140#define TS_RELEASE_LATENCY(when) CPU_LTIMESTAMP(208, &(when)) 143#define TS_ISR_START CPU_TIMESTAMP_CUR(192)
144#define TS_ISR_END CPU_TIMESTAMP_CUR(193)
145
146#define TS_RELEASE_LATENCY(when) CPU_LTIMESTAMP(208, &(when))
147#define TS_RELEASE_LATENCY_A(when) CPU_LTIMESTAMP(209, &(when))
148#define TS_RELEASE_LATENCY_B(when) CPU_LTIMESTAMP(210, &(when))
149#define TS_RELEASE_LATENCY_C(when) CPU_LTIMESTAMP(211, &(when))
150
151#define TS_SCHED_A_START CPU_DTIMESTAMP(212, TSK_UNKNOWN)
152#define TS_SCHED_A_END(t) CPU_TTIMESTAMP(213, t)
153#define TS_SCHED_C_START CPU_DTIMESTAMP(214, TSK_UNKNOWN)
154#define TS_SCHED_C_END(t) CPU_TTIMESTAMP(215, t)
141 155
142#endif /* !_SYS_TRACE_H_ */ 156#endif /* !_SYS_TRACE_H_ */