aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2014-03-13 16:28:07 -0400
committerGlenn Elliott <gelliott@cs.unc.edu>2014-03-13 16:28:07 -0400
commit1a747de02f4f13b4398940b32470ea0cac45074b (patch)
treee132c00db99c68b5cd275e25f41bebe07f16c46b
parent9f09e173b0414f9c80fce7dd9f5324eec1ecc5f1 (diff)
C-EDF: Use sbinheap to track to top-m prio tasks.
This patch updates C-EDF to use sbinheap instead of binheap to track the m-highest priority released jobs.
-rw-r--r--include/litmus/budget.h5
-rw-r--r--litmus/budget.c3
-rw-r--r--litmus/sched_cedf.c85
3 files changed, 59 insertions, 34 deletions
diff --git a/include/litmus/budget.h b/include/litmus/budget.h
index aff48d9218fa..de38c01444a7 100644
--- a/include/litmus/budget.h
+++ b/include/litmus/budget.h
@@ -5,6 +5,7 @@
5#include <linux/semaphore.h> 5#include <linux/semaphore.h>
6 6
7#include <litmus/binheap.h> 7#include <litmus/binheap.h>
8#include <litmus/sbinheap.h>
8 9
9struct enforcement_timer 10struct enforcement_timer
10{ 11{
@@ -62,7 +63,9 @@ struct budget_tracker
62 const struct budget_tracker_ops* ops; 63 const struct budget_tracker_ops* ops;
63 unsigned long flags; 64 unsigned long flags;
64 65
65 struct binheap_node top_m_node; 66 sbinheap_node_t top_m_node;
67 binheap_node_t not_top_m_node;
68
66 lt_t suspend_timestamp; 69 lt_t suspend_timestamp;
67}; 70};
68 71
diff --git a/litmus/budget.c b/litmus/budget.c
index 410112213cf0..65cc3bc263a8 100644
--- a/litmus/budget.c
+++ b/litmus/budget.c
@@ -456,5 +456,6 @@ void init_budget_tracker(struct budget_tracker* bt,
456 hrtimer_init(&bt->timer.timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); 456 hrtimer_init(&bt->timer.timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
457 bt->timer.timer.function = __on_timeout; 457 bt->timer.timer.function = __on_timeout;
458 bt->ops = ops; 458 bt->ops = ops;
459 INIT_BINHEAP_NODE(&bt->top_m_node); 459 INIT_SBINHEAP_NODE(&bt->top_m_node);
460 INIT_BINHEAP_NODE(&bt->not_top_m_node);
460} 461}
diff --git a/litmus/sched_cedf.c b/litmus/sched_cedf.c
index a6b61926eda1..61fef55f38a5 100644
--- a/litmus/sched_cedf.c
+++ b/litmus/sched_cedf.c
@@ -133,8 +133,7 @@ typedef struct clusterdomain {
133 raw_spinlock_t dgl_lock; 133 raw_spinlock_t dgl_lock;
134#endif 134#endif
135 135
136 int top_m_size; 136 struct sbinheap top_m;
137 struct binheap top_m;
138 struct binheap not_top_m; 137 struct binheap not_top_m;
139 138
140} cedf_domain_t; 139} cedf_domain_t;
@@ -163,7 +162,7 @@ static unsigned int gpu_cluster_size;
163inline static const struct task_struct* binheap_node_to_task(const struct binheap_node *bn) 162inline static const struct task_struct* binheap_node_to_task(const struct binheap_node *bn)
164{ 163{
165 const struct budget_tracker *bt = 164 const struct budget_tracker *bt =
166 binheap_entry(bn, struct budget_tracker, top_m_node); 165 binheap_entry(bn, struct budget_tracker, not_top_m_node);
167 const struct task_struct *t = 166 const struct task_struct *t =
168 container_of( 167 container_of(
169 container_of(bt, struct rt_param, budget), 168 container_of(bt, struct rt_param, budget),
@@ -180,11 +179,23 @@ static int cedf_max_heap_base_priority_order(const struct binheap_node *a,
180 return __edf_higher_prio(t_a, BASE, t_b, BASE); 179 return __edf_higher_prio(t_a, BASE, t_b, BASE);
181} 180}
182 181
183static int cedf_min_heap_base_priority_order(const struct binheap_node *a, 182inline static const struct task_struct* sbinheap_node_to_task(const struct sbinheap_node *bn)
184 const struct binheap_node *b)
185{ 183{
186 const struct task_struct* t_a = binheap_node_to_task(a); 184 const struct budget_tracker *bt =
187 const struct task_struct* t_b = binheap_node_to_task(b); 185 sbinheap_entry(bn, struct budget_tracker, top_m_node);
186 const struct task_struct *t =
187 container_of(
188 container_of(bt, struct rt_param, budget),
189 struct task_struct,
190 rt_param);
191 return t;
192}
193
194static int cedf_min_heap_base_priority_order(const struct sbinheap_node *a,
195 const struct sbinheap_node *b)
196{
197 const struct task_struct* t_a = sbinheap_node_to_task(a);
198 const struct task_struct* t_b = sbinheap_node_to_task(b);
188 return __edf_higher_prio(t_b, BASE, t_a, BASE); 199 return __edf_higher_prio(t_b, BASE, t_a, BASE);
189} 200}
190 201
@@ -195,23 +206,23 @@ static void cedf_track_in_top_m(struct task_struct *t)
195 struct budget_tracker *bt; 206 struct budget_tracker *bt;
196 struct task_struct *mth_highest; 207 struct task_struct *mth_highest;
197 208
198 if (binheap_is_in_heap(&tsk_rt(t)->budget.top_m_node)) 209 if (sbinheap_is_in_heap(&tsk_rt(t)->budget.top_m_node) ||
210 binheap_is_in_heap(&tsk_rt(t)->budget.not_top_m_node))
199 return; 211 return;
200 212
201 /* TODO: do cluster_size-1 if release master is in this cluster */ 213 /* TODO: do cluster_size-1 if release master is in this cluster */
202 if (cluster->top_m_size < cluster_size) { 214 if (cluster->top_m.size < cluster_size) {
203 binheap_add(&tsk_rt(t)->budget.top_m_node, &cluster->top_m, 215 sbinheap_add(&tsk_rt(t)->budget.top_m_node, &cluster->top_m,
204 struct budget_tracker, top_m_node); 216 struct budget_tracker, top_m_node);
205 ++cluster->top_m_size;
206 bt_flag_set(t, BTF_IS_TOP_M); 217 bt_flag_set(t, BTF_IS_TOP_M);
207 budget_state_machine(t,on_enter_top_m); 218 budget_state_machine(t,on_enter_top_m);
208 219
209 return; 220 return;
210 } 221 }
211 222
212 BUG_ON(binheap_empty(&cluster->top_m)); 223 BUG_ON(sbinheap_empty(&cluster->top_m));
213 224
214 bt = binheap_top_entry(&cluster->top_m, struct budget_tracker, top_m_node); 225 bt = sbinheap_top_entry(&cluster->top_m, struct budget_tracker, top_m_node);
215 mth_highest = 226 mth_highest =
216 container_of( 227 container_of(
217 container_of(bt, struct rt_param, budget), 228 container_of(bt, struct rt_param, budget),
@@ -219,23 +230,27 @@ static void cedf_track_in_top_m(struct task_struct *t)
219 rt_param); 230 rt_param);
220 231
221 if (__edf_higher_prio(t, BASE, mth_highest, BASE)) { 232 if (__edf_higher_prio(t, BASE, mth_highest, BASE)) {
222 binheap_delete_root(&cluster->top_m, struct budget_tracker, top_m_node); 233 /* remove m-th task from the top_m heap and add
223 INIT_BINHEAP_NODE(&tsk_rt(mth_highest)->budget.top_m_node); 234 it to the not-top-m heap */
224 binheap_add(&tsk_rt(mth_highest)->budget.top_m_node, 235 sbinheap_delete_root(&cluster->top_m, struct budget_tracker, top_m_node);
236 INIT_SBINHEAP_NODE(&tsk_rt(mth_highest)->budget.top_m_node);
237
238 binheap_add(&tsk_rt(mth_highest)->budget.not_top_m_node,
225 &cluster->not_top_m, 239 &cluster->not_top_m,
226 struct budget_tracker, top_m_node); 240 struct budget_tracker, not_top_m_node);
227 budget_state_machine(mth_highest,on_exit_top_m); 241 budget_state_machine(mth_highest,on_exit_top_m);
228 bt_flag_clear(mth_highest, BTF_IS_TOP_M); 242 bt_flag_clear(mth_highest, BTF_IS_TOP_M);
229 243
230 binheap_add(&tsk_rt(t)->budget.top_m_node, &cluster->top_m, 244 /* add t to the top_m heap */
245 sbinheap_add(&tsk_rt(t)->budget.top_m_node, &cluster->top_m,
231 struct budget_tracker, top_m_node); 246 struct budget_tracker, top_m_node);
232 bt_flag_set(t, BTF_IS_TOP_M); 247 bt_flag_set(t, BTF_IS_TOP_M);
233 budget_state_machine(t,on_enter_top_m); 248 budget_state_machine(t,on_enter_top_m);
234 } 249 }
235 else { 250 else {
236 binheap_add(&tsk_rt(t)->budget.top_m_node, 251 binheap_add(&tsk_rt(t)->budget.not_top_m_node,
237 &cluster->not_top_m, 252 &cluster->not_top_m,
238 struct budget_tracker, top_m_node); 253 struct budget_tracker, not_top_m_node);
239 } 254 }
240} 255}
241 256
@@ -244,12 +259,14 @@ static void cedf_untrack_in_top_m(struct task_struct *t)
244 /* cluster lock must be held */ 259 /* cluster lock must be held */
245 cedf_domain_t *cluster = task_cpu_cluster(t); 260 cedf_domain_t *cluster = task_cpu_cluster(t);
246 261
247 if (!binheap_is_in_heap(&tsk_rt(t)->budget.top_m_node)) 262 if (!sbinheap_is_in_heap(&tsk_rt(t)->budget.top_m_node) &&
263 !binheap_is_in_heap(&tsk_rt(t)->budget.not_top_m_node))
248 return; 264 return;
249 265
250 if (bt_flag_is_set(t, BTF_IS_TOP_M)) { 266 if (bt_flag_is_set(t, BTF_IS_TOP_M)) {
251 /* delete t's entry */ 267 /* delete t's entry */
252 binheap_delete(&tsk_rt(t)->budget.top_m_node, &cluster->top_m); 268 sbinheap_delete(&tsk_rt(t)->budget.top_m_node, &cluster->top_m);
269 INIT_SBINHEAP_NODE(&tsk_rt(t)->budget.top_m_node);
253 budget_state_machine(t,on_exit_top_m); 270 budget_state_machine(t,on_exit_top_m);
254 bt_flag_clear(t, BTF_IS_TOP_M); 271 bt_flag_clear(t, BTF_IS_TOP_M);
255 272
@@ -257,7 +274,7 @@ static void cedf_untrack_in_top_m(struct task_struct *t)
257 if(!binheap_empty(&cluster->not_top_m)) { 274 if(!binheap_empty(&cluster->not_top_m)) {
258 struct budget_tracker *bt = 275 struct budget_tracker *bt =
259 binheap_top_entry(&cluster->not_top_m, struct budget_tracker, 276 binheap_top_entry(&cluster->not_top_m, struct budget_tracker,
260 top_m_node); 277 not_top_m_node);
261 struct task_struct *to_move = 278 struct task_struct *to_move =
262 container_of( 279 container_of(
263 container_of(bt, struct rt_param, budget), 280 container_of(bt, struct rt_param, budget),
@@ -265,21 +282,19 @@ static void cedf_untrack_in_top_m(struct task_struct *t)
265 rt_param); 282 rt_param);
266 283
267 binheap_delete_root(&cluster->not_top_m, struct budget_tracker, 284 binheap_delete_root(&cluster->not_top_m, struct budget_tracker,
268 top_m_node); 285 not_top_m_node);
269 INIT_BINHEAP_NODE(&tsk_rt(to_move)->budget.top_m_node); 286 INIT_BINHEAP_NODE(&tsk_rt(to_move)->budget.not_top_m_node);
270 287
271 binheap_add(&tsk_rt(to_move)->budget.top_m_node, 288 sbinheap_add(&tsk_rt(to_move)->budget.top_m_node,
272 &cluster->top_m, 289 &cluster->top_m,
273 struct budget_tracker, top_m_node); 290 struct budget_tracker, top_m_node);
274 bt_flag_set(to_move, BTF_IS_TOP_M); 291 bt_flag_set(to_move, BTF_IS_TOP_M);
275 budget_state_machine(to_move,on_enter_top_m); 292 budget_state_machine(to_move,on_enter_top_m);
276 } 293 }
277 else {
278 --cluster->top_m_size;
279 }
280 } 294 }
281 else { 295 else {
282 binheap_delete(&tsk_rt(t)->budget.top_m_node, &cluster->not_top_m); 296 binheap_delete(&tsk_rt(t)->budget.not_top_m_node, &cluster->not_top_m);
297 INIT_BINHEAP_NODE(&tsk_rt(t)->budget.not_top_m_node);
283 } 298 }
284} 299}
285 300
@@ -2366,6 +2381,7 @@ static void cleanup_cedf(void)
2366 for (i = 0; i < num_clusters; i++) { 2381 for (i = 0; i < num_clusters; i++) {
2367 kfree(cedf[i].cpus); 2382 kfree(cedf[i].cpus);
2368 kfree(cedf[i].cpu_heap.buf); 2383 kfree(cedf[i].cpu_heap.buf);
2384 kfree(cedf[i].top_m.buf);
2369 free_cpumask_var(cedf[i].cpu_map); 2385 free_cpumask_var(cedf[i].cpu_map);
2370 } 2386 }
2371 2387
@@ -2539,8 +2555,13 @@ static long cedf_activate_plugin(void)
2539 atomic_set(&cedf[i].owner_cpu, NO_CPU); 2555 atomic_set(&cedf[i].owner_cpu, NO_CPU);
2540#endif 2556#endif
2541 2557
2542 cedf[i].top_m_size = 0; 2558 cedf[i].top_m.compare = cedf_min_heap_base_priority_order;
2543 INIT_BINHEAP_HANDLE(&cedf[i].top_m, cedf_min_heap_base_priority_order); 2559 cedf[i].top_m.size = 0;
2560 cedf[i].top_m.max_size = cluster_size;
2561 cedf[i].top_m.buf =
2562 kmalloc(cluster_size * sizeof(struct sbinheap_node), GFP_ATOMIC);
2563 INIT_SBINHEAP(&(cedf[i].top_m));
2564
2544 INIT_BINHEAP_HANDLE(&cedf[i].not_top_m, 2565 INIT_BINHEAP_HANDLE(&cedf[i].not_top_m,
2545 cedf_max_heap_base_priority_order); 2566 cedf_max_heap_base_priority_order);
2546 2567