diff options
| author | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2007-10-08 20:24:20 -0400 |
|---|---|---|
| committer | Bjoern B. Brandenburg <bbb@cs.unc.edu> | 2007-10-08 20:24:20 -0400 |
| commit | 729c2d3b077bf90d1c4e32dcb047e25cf5d9f684 (patch) | |
| tree | 496c57a3b51e287cf29d7381aced70a43ddc5a90 /kernel | |
| parent | 0b57fb8bf75f9ab8e8378238b71f3c983afc5fa5 (diff) | |
adaptive: debugging
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/litmus.c | 44 | ||||
| -rw-r--r-- | kernel/sched_adaptive.c | 52 |
2 files changed, 69 insertions, 27 deletions
diff --git a/kernel/litmus.c b/kernel/litmus.c index 131fc5039e..e837850998 100644 --- a/kernel/litmus.c +++ b/kernel/litmus.c | |||
| @@ -218,12 +218,6 @@ asmlinkage long sys_set_service_levels(pid_t pid, | |||
| 218 | target->rt_param.service_level = NULL; | 218 | target->rt_param.service_level = NULL; |
| 219 | target->rt_param.no_service_levels = 0; | 219 | target->rt_param.no_service_levels = 0; |
| 220 | 220 | ||
| 221 | /* count == 0 means tear down service levels*/ | ||
| 222 | if (count == 0) { | ||
| 223 | retval = 0; | ||
| 224 | goto out; | ||
| 225 | } | ||
| 226 | |||
| 227 | if (wt_y && wt_slope) { | 221 | if (wt_y && wt_slope) { |
| 228 | if (copy_from_user(&target->rt_param.wt_y, wt_y, | 222 | if (copy_from_user(&target->rt_param.wt_y, wt_y, |
| 229 | sizeof(fp_t))) { | 223 | sizeof(fp_t))) { |
| @@ -238,7 +232,7 @@ asmlinkage long sys_set_service_levels(pid_t pid, | |||
| 238 | target->rt_param.wt_slope = FP(1); | 232 | target->rt_param.wt_slope = FP(1); |
| 239 | goto out; | 233 | goto out; |
| 240 | } | 234 | } |
| 241 | if (_leq(target->rt_param.wt_y, FP(0)) || | 235 | if (_lt(target->rt_param.wt_y, FP(0)) || |
| 242 | _leq(target->rt_param.wt_slope, FP(0))) { | 236 | _leq(target->rt_param.wt_slope, FP(0))) { |
| 243 | retval = -EINVAL; | 237 | retval = -EINVAL; |
| 244 | target->rt_param.wt_y = FP(0); | 238 | target->rt_param.wt_y = FP(0); |
| @@ -250,6 +244,15 @@ asmlinkage long sys_set_service_levels(pid_t pid, | |||
| 250 | target->rt_param.wt_slope = FP(1); | 244 | target->rt_param.wt_slope = FP(1); |
| 251 | } | 245 | } |
| 252 | 246 | ||
| 247 | TRACE_TASK(target, "set slope=" _FP_ ", y=" _FP_ "\n", | ||
| 248 | target->rt_param.wt_slope, target->rt_param.wt_y); | ||
| 249 | |||
| 250 | /* count == 0 means tear down service levels*/ | ||
| 251 | if (count == 0) { | ||
| 252 | retval = 0; | ||
| 253 | goto out; | ||
| 254 | } | ||
| 255 | |||
| 253 | klevels = kmalloc(sizeof(service_level_t) * count, GFP_KERNEL); | 256 | klevels = kmalloc(sizeof(service_level_t) * count, GFP_KERNEL); |
| 254 | if (!klevels) { | 257 | if (!klevels) { |
| 255 | retval = -ENOMEM; | 258 | retval = -ENOMEM; |
| @@ -262,12 +265,18 @@ asmlinkage long sys_set_service_levels(pid_t pid, | |||
| 262 | kfree(klevels); | 265 | kfree(klevels); |
| 263 | goto out; | 266 | goto out; |
| 264 | } | 267 | } |
| 265 | if (level.period <= 0) | 268 | if (level.period <= 0) { |
| 269 | TRACE("service level %d period <= 0\n", i); | ||
| 266 | goto out; | 270 | goto out; |
| 267 | if (_leq(level.weight, last_weight)) | 271 | } |
| 272 | if (_leq(level.weight, last_weight)) { | ||
| 273 | TRACE("service level %d weight non-increase\n", i); | ||
| 268 | goto out; | 274 | goto out; |
| 269 | if (_leq(level.value, last_value)) | 275 | } |
| 276 | if (_leq(level.value, last_value)) { | ||
| 277 | TRACE("service level %d value non-increase\n", i); | ||
| 270 | goto out; | 278 | goto out; |
| 279 | } | ||
| 271 | last_value = level.value; | 280 | last_value = level.value; |
| 272 | last_weight = level.weight; | 281 | last_weight = level.weight; |
| 273 | klevels[i] = level; | 282 | klevels[i] = level; |
| @@ -679,6 +688,7 @@ void exit_litmus(struct task_struct *dead_tsk) | |||
| 679 | curr_sched_plugin->tear_down(dead_tsk); | 688 | curr_sched_plugin->tear_down(dead_tsk); |
| 680 | } | 689 | } |
| 681 | 690 | ||
| 691 | |||
| 682 | void list_qsort(struct list_head* list, list_cmp_t less_than) | 692 | void list_qsort(struct list_head* list, list_cmp_t less_than) |
| 683 | { | 693 | { |
| 684 | struct list_head lt; | 694 | struct list_head lt; |
| @@ -694,6 +704,7 @@ void list_qsort(struct list_head* list, list_cmp_t less_than) | |||
| 694 | INIT_LIST_HEAD(&geq); | 704 | INIT_LIST_HEAD(&geq); |
| 695 | 705 | ||
| 696 | pivot = list->next; | 706 | pivot = list->next; |
| 707 | list_del(pivot); | ||
| 697 | list_for_each_safe(pos, extra, list) { | 708 | list_for_each_safe(pos, extra, list) { |
| 698 | list_del(pos); | 709 | list_del(pos); |
| 699 | if (less_than(pos, pivot)) { | 710 | if (less_than(pos, pivot)) { |
| @@ -705,17 +716,14 @@ void list_qsort(struct list_head* list, list_cmp_t less_than) | |||
| 705 | } | 716 | } |
| 706 | } | 717 | } |
| 707 | if (n_lt < n_geq) { | 718 | if (n_lt < n_geq) { |
| 708 | if (n_lt > 1) | 719 | list_qsort(<, less_than); |
| 709 | list_qsort(<, less_than); | 720 | list_qsort(&geq, less_than); |
| 710 | if (n_geq > 1) | ||
| 711 | list_qsort(&geq, less_than); | ||
| 712 | } else { | 721 | } else { |
| 713 | if (n_geq > 1) | 722 | list_qsort(&geq, less_than); |
| 714 | list_qsort(&geq, less_than); | 723 | list_qsort(<, less_than); |
| 715 | if (n_lt > 1) | ||
| 716 | list_qsort(<, less_than); | ||
| 717 | } | 724 | } |
| 718 | list_splice(&geq, list); | 725 | list_splice(&geq, list); |
| 726 | list_add(pivot, list); | ||
| 719 | list_splice(<, list); | 727 | list_splice(<, list); |
| 720 | } | 728 | } |
| 721 | 729 | ||
diff --git a/kernel/sched_adaptive.c b/kernel/sched_adaptive.c index a91e607105..24095e02d8 100644 --- a/kernel/sched_adaptive.c +++ b/kernel/sched_adaptive.c | |||
| @@ -93,6 +93,11 @@ | |||
| 93 | * __take_ready). | 93 | * __take_ready). |
| 94 | */ | 94 | */ |
| 95 | 95 | ||
| 96 | /* TODO: | ||
| 97 | * - export weight error on task completion | ||
| 98 | * - | ||
| 99 | */ | ||
| 100 | |||
| 96 | 101 | ||
| 97 | /* cpu_entry_t - maintain the linked and scheduled state | 102 | /* cpu_entry_t - maintain the linked and scheduled state |
| 98 | */ | 103 | */ |
| @@ -208,12 +213,12 @@ void adaptive_optimize(void) | |||
| 208 | struct list_head *p, *extra; | 213 | struct list_head *p, *extra; |
| 209 | cpu_entry_t *cpu; | 214 | cpu_entry_t *cpu; |
| 210 | struct task_struct* t; | 215 | struct task_struct* t; |
| 211 | fp_t M = FP(0), w0, wl, new_M, estU = FP(0), _M; | 216 | fp_t M = FP(0), w0, wl, tmp, estU = FP(0), _M; |
| 212 | int i; | 217 | int i; |
| 213 | unsigned int l; | 218 | unsigned int l; |
| 214 | jiffie_t enactment_time; | 219 | jiffie_t enactment_time; |
| 215 | 220 | ||
| 216 | TRACE("running adaptive optimizer\n"); | 221 | TRACE(":::::: running adaptive optimizer\n"); |
| 217 | opt_time = jiffies; | 222 | opt_time = jiffies; |
| 218 | 223 | ||
| 219 | INIT_LIST_HEAD(&list); | 224 | INIT_LIST_HEAD(&list); |
| @@ -233,6 +238,7 @@ void adaptive_optimize(void) | |||
| 233 | for_each_online_cpu(i) | 238 | for_each_online_cpu(i) |
| 234 | M = _add(M, FP(1)); | 239 | M = _add(M, FP(1)); |
| 235 | _M = M; | 240 | _M = M; |
| 241 | TRACE("opt: system capacity: " _FP_ "\n", fp2str(M)); | ||
| 236 | 242 | ||
| 237 | /* 3) Compute L value for all tasks, | 243 | /* 3) Compute L value for all tasks, |
| 238 | * and set tasks to service level 0, | 244 | * and set tasks to service level 0, |
| @@ -241,11 +247,17 @@ void adaptive_optimize(void) | |||
| 241 | */ | 247 | */ |
| 242 | list_for_each(p, &list) { | 248 | list_for_each(p, &list) { |
| 243 | t = list_entry(p, struct task_struct, rt_param.opt_list); | 249 | t = list_entry(p, struct task_struct, rt_param.opt_list); |
| 244 | t->rt_param.opt_order = linear_metric(t); | 250 | t->rt_param.opt_order = linear_metric(t); |
| 251 | TRACE_TASK(t, "est_w = " _FP_ " L = " _FP_ "\n", | ||
| 252 | get_est_weight(t), | ||
| 253 | fp2str(t->rt_param.opt_order)); | ||
| 245 | t->rt_param.opt_level = 0; | 254 | t->rt_param.opt_level = 0; |
| 246 | M = _sub(M, est_weight_at(t, 0)); | 255 | M = _sub(M, est_weight_at(t, 0)); |
| 247 | estU = _add(estU, get_est_weight(t)); | 256 | estU = _add(estU, get_est_weight(t)); |
| 248 | } | 257 | } |
| 258 | TRACE("opt: estimated utilization: " _FP_ "\n", fp2str(estU)); | ||
| 259 | TRACE("opt: estimated capacity at all sl=0: " _FP_ "\n", fp2str(M)); | ||
| 260 | |||
| 249 | 261 | ||
| 250 | /* 4) sort list by decreasing linear metric */ | 262 | /* 4) sort list by decreasing linear metric */ |
| 251 | list_qsort(&list, by_linear_metric); | 263 | list_qsort(&list, by_linear_metric); |
| @@ -258,13 +270,18 @@ void adaptive_optimize(void) | |||
| 258 | while (l > 1) { | 270 | while (l > 1) { |
| 259 | l--; | 271 | l--; |
| 260 | wl = est_weight_at(t, l); | 272 | wl = est_weight_at(t, l); |
| 261 | new_M = _sub(M, _sub(wl, w0)); | 273 | tmp = _sub(M, _sub(wl, w0)); |
| 262 | if (_leq(FP(0), new_M)) { | 274 | if (_leq(FP(0), tmp)) { |
| 263 | /* this level fits in */ | 275 | /* this level fits in */ |
| 264 | M = new_M; | 276 | M = tmp; |
| 265 | t->rt_param.opt_level = l; | 277 | t->rt_param.opt_level = l; |
| 266 | t->rt_param.opt_dw = _sub(get_est_weight(t), wl); | 278 | t->rt_param.opt_dw = _sub(wl, |
| 279 | get_est_weight(t)); | ||
| 267 | t->rt_param.opt_nw = wl; | 280 | t->rt_param.opt_nw = wl; |
| 281 | TRACE_TASK(t, " will run at sl=%u, " | ||
| 282 | "prior=%ud dw=" _FP_ "\n", | ||
| 283 | l, get_cur_sl(t), | ||
| 284 | fp2str(t->rt_param.opt_dw)); | ||
| 268 | break; /* proceed to next task */ | 285 | break; /* proceed to next task */ |
| 269 | } | 286 | } |
| 270 | } | 287 | } |
| @@ -301,6 +318,7 @@ void adaptive_optimize(void) | |||
| 301 | /* Very ugly jump, but we need to force enactment_time = 0 | 318 | /* Very ugly jump, but we need to force enactment_time = 0 |
| 302 | * during the first iteration. | 319 | * during the first iteration. |
| 303 | */ | 320 | */ |
| 321 | M = _M; | ||
| 304 | enactment_time = 0; | 322 | enactment_time = 0; |
| 305 | goto first_iteration; | 323 | goto first_iteration; |
| 306 | 324 | ||
| @@ -321,6 +339,10 @@ void adaptive_optimize(void) | |||
| 321 | /* opt_dw is negative */ | 339 | /* opt_dw is negative */ |
| 322 | estU = _add(estU, t->rt_param.opt_dw); | 340 | estU = _add(estU, t->rt_param.opt_dw); |
| 323 | list_add(p, &list); | 341 | list_add(p, &list); |
| 342 | TRACE_TASK(t, " weight decrease at %ld => estU=" | ||
| 343 | _FP_ "\n", enactment_time, | ||
| 344 | fp2str(estU)); | ||
| 345 | |||
| 324 | } else | 346 | } else |
| 325 | /* stop decrease loop */ | 347 | /* stop decrease loop */ |
| 326 | break; | 348 | break; |
| @@ -331,12 +353,16 @@ void adaptive_optimize(void) | |||
| 331 | p = inc.next; | 353 | p = inc.next; |
| 332 | t = list_entry(p, struct task_struct, | 354 | t = list_entry(p, struct task_struct, |
| 333 | rt_param.opt_list); | 355 | rt_param.opt_list); |
| 334 | if (_leq(_add(estU, t->rt_param.opt_dw), M)) { | 356 | tmp = _add(estU, t->rt_param.opt_dw) |
| 357 | if (_leq(tmp, M)) { | ||
| 335 | /* it fits */ | 358 | /* it fits */ |
| 336 | estU = _add(estU, t->rt_param.opt_dw); | 359 | estU = tmp; |
| 337 | t->rt_param.opt_change = enactment_time; | 360 | t->rt_param.opt_change = enactment_time; |
| 338 | list_del(p); | 361 | list_del(p); |
| 339 | list_add(p, &list); | 362 | list_add(p, &list); |
| 363 | TRACE_TASK(t, " weight increase at %ld => estU=" | ||
| 364 | _FP_ "\n", enactment_time, | ||
| 365 | fp2str(estU)); | ||
| 340 | } else | 366 | } else |
| 341 | /* stop increase loop */ | 367 | /* stop increase loop */ |
| 342 | break; | 368 | break; |
| @@ -369,6 +395,7 @@ void adaptive_optimize(void) | |||
| 369 | } | 395 | } |
| 370 | 396 | ||
| 371 | last_optimizer_run = jiffies; | 397 | last_optimizer_run = jiffies; |
| 398 | |||
| 372 | } | 399 | } |
| 373 | 400 | ||
| 374 | /* update_cpu_position - Move the cpu entry to the correct place to maintain | 401 | /* update_cpu_position - Move the cpu entry to the correct place to maintain |
| @@ -800,6 +827,13 @@ static long adaptive_prepare_task(struct task_struct * t) | |||
| 800 | 827 | ||
| 801 | t->rt_param.scheduled_on = NO_CPU; | 828 | t->rt_param.scheduled_on = NO_CPU; |
| 802 | t->rt_param.linked_on = NO_CPU; | 829 | t->rt_param.linked_on = NO_CPU; |
| 830 | if (t->rt_param.no_service_levels) { | ||
| 831 | t->rt_param.predictor_state.estimate = | ||
| 832 | get_sl(t, 0).weight; | ||
| 833 | } else | ||
| 834 | t->rt_param.predictor_state.estimate = | ||
| 835 | _frac(get_exec_cost(t), get_rt_period(t)); | ||
| 836 | |||
| 803 | if (get_rt_mode() == MODE_RT_RUN) | 837 | if (get_rt_mode() == MODE_RT_RUN) |
| 804 | /* The action is already on. | 838 | /* The action is already on. |
| 805 | * Prepare immediate release | 839 | * Prepare immediate release |
