diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-09-11 22:42:51 -0400 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-09-11 22:42:51 -0400 |
commit | c1d1979c99ca397241da4e3d7e0cb77f7ec28240 (patch) | |
tree | 2a988aae1ae7c08891543e844171cbcb4281a5bb /litmus/litmus.c | |
parent | fd3aa01f176cf12b1625f4f46ba01f3340bb57ed (diff) | |
parent | 55e04c94b925b0790c2ae0a79f16e939e9bb2846 (diff) |
Merge branch 'wip-gpu-rtas12' into wip-slave-threads
Conflicts:
include/litmus/unistd_32.h
include/litmus/unistd_64.h
litmus/litmus.c
Diffstat (limited to 'litmus/litmus.c')
-rw-r--r-- | litmus/litmus.c | 161 |
1 files changed, 145 insertions, 16 deletions
diff --git a/litmus/litmus.c b/litmus/litmus.c index 2300281b6b30..83e8ef3f42af 100644 --- a/litmus/litmus.c +++ b/litmus/litmus.c | |||
@@ -21,6 +21,10 @@ | |||
21 | #include <litmus/affinity.h> | 21 | #include <litmus/affinity.h> |
22 | #endif | 22 | #endif |
23 | 23 | ||
24 | #ifdef CONFIG_LITMUS_NVIDIA | ||
25 | #include <litmus/nvidia_info.h> | ||
26 | #endif | ||
27 | |||
24 | /* Number of RT tasks that exist in the system */ | 28 | /* Number of RT tasks that exist in the system */ |
25 | atomic_t rt_task_count = ATOMIC_INIT(0); | 29 | atomic_t rt_task_count = ATOMIC_INIT(0); |
26 | static DEFINE_RAW_SPINLOCK(task_transition_lock); | 30 | static DEFINE_RAW_SPINLOCK(task_transition_lock); |
@@ -51,6 +55,28 @@ void bheap_node_free(struct bheap_node* hn) | |||
51 | struct release_heap* release_heap_alloc(int gfp_flags); | 55 | struct release_heap* release_heap_alloc(int gfp_flags); |
52 | void release_heap_free(struct release_heap* rh); | 56 | void release_heap_free(struct release_heap* rh); |
53 | 57 | ||
58 | #ifdef CONFIG_LITMUS_NVIDIA | ||
59 | /* | ||
60 | * sys_register_nv_device | ||
61 | * @nv_device_id: The Nvidia device id that the task want to register | ||
62 | * @reg_action: set to '1' to register the specified device. zero otherwise. | ||
63 | * Syscall for register task's designated nvidia device into NV_DEVICE_REG array | ||
64 | * Returns EFAULT if nv_device_id is out of range. | ||
65 | * 0 if success | ||
66 | */ | ||
67 | asmlinkage long sys_register_nv_device(int nv_device_id, int reg_action) | ||
68 | { | ||
69 | /* register the device to caller (aka 'current') */ | ||
70 | return(reg_nv_device(nv_device_id, reg_action, current)); | ||
71 | } | ||
72 | #else | ||
73 | asmlinkage long sys_register_nv_device(int nv_device_id, int reg_action) | ||
74 | { | ||
75 | return(-EINVAL); | ||
76 | } | ||
77 | #endif | ||
78 | |||
79 | |||
54 | /* | 80 | /* |
55 | * sys_set_task_rt_param | 81 | * sys_set_task_rt_param |
56 | * @pid: Pid of the task which scheduling parameters must be changed | 82 | * @pid: Pid of the task which scheduling parameters must be changed |
@@ -136,6 +162,16 @@ asmlinkage long sys_set_rt_task_param(pid_t pid, struct rt_task __user * param) | |||
136 | pid, tp.budget_policy); | 162 | pid, tp.budget_policy); |
137 | goto out_unlock; | 163 | goto out_unlock; |
138 | } | 164 | } |
165 | if (tp.budget_signal_policy != NO_SIGNALS && | ||
166 | tp.budget_signal_policy != QUANTUM_SIGNALS && | ||
167 | tp.budget_signal_policy != PRECISE_SIGNALS) | ||
168 | { | ||
169 | printk(KERN_INFO "litmus: real-time task %d rejected " | ||
170 | "because unsupported budget signalling policy " | ||
171 | "specified (%d)\n", | ||
172 | pid, tp.budget_signal_policy); | ||
173 | goto out_unlock; | ||
174 | } | ||
139 | 175 | ||
140 | target->rt_param.task_params = tp; | 176 | target->rt_param.task_params = tp; |
141 | 177 | ||
@@ -273,6 +309,7 @@ asmlinkage long sys_query_job_no(unsigned int __user *job) | |||
273 | return retval; | 309 | return retval; |
274 | } | 310 | } |
275 | 311 | ||
312 | |||
276 | /* sys_null_call() is only used for determining raw system call | 313 | /* sys_null_call() is only used for determining raw system call |
277 | * overheads (kernel entry, kernel exit). It has no useful side effects. | 314 | * overheads (kernel entry, kernel exit). It has no useful side effects. |
278 | * If ts is non-NULL, then the current Feather-Trace time is recorded. | 315 | * If ts is non-NULL, then the current Feather-Trace time is recorded. |
@@ -291,14 +328,6 @@ asmlinkage long sys_null_call(cycles_t __user *ts) | |||
291 | } | 328 | } |
292 | 329 | ||
293 | 330 | ||
294 | |||
295 | |||
296 | |||
297 | |||
298 | |||
299 | |||
300 | |||
301 | |||
302 | long __litmus_admit_task(struct task_struct* tsk); | 331 | long __litmus_admit_task(struct task_struct* tsk); |
303 | 332 | ||
304 | asmlinkage long sys_slave_non_rt_threads(void) | 333 | asmlinkage long sys_slave_non_rt_threads(void) |
@@ -310,8 +339,6 @@ asmlinkage long sys_slave_non_rt_threads(void) | |||
310 | 339 | ||
311 | read_lock_irq(&tasklist_lock); | 340 | read_lock_irq(&tasklist_lock); |
312 | 341 | ||
313 | is_realtime(target) | ||
314 | |||
315 | t = leader; | 342 | t = leader; |
316 | do { | 343 | do { |
317 | TRACE_CUR("threads in %s/%d: %s/%d:\n", leader->comm, leader->pid, t->comm, t->pid); | 344 | TRACE_CUR("threads in %s/%d: %s/%d:\n", leader->comm, leader->pid, t->comm, t->pid); |
@@ -324,8 +351,10 @@ asmlinkage long sys_slave_non_rt_threads(void) | |||
324 | /* hasn't been admitted into rt. make it a slave. */ | 351 | /* hasn't been admitted into rt. make it a slave. */ |
325 | tsk_rt(t)->slave = 1; | 352 | tsk_rt(t)->slave = 1; |
326 | } | 353 | } |
327 | else if (is_realtime(t)) | 354 | else { |
328 | if (litmus->compare(t, hp)) { | 355 | tsk_rt(t)->has_slaves = 1; |
356 | |||
357 | if (is_realtime(t) && litmus->compare(t, hp)) { | ||
329 | hp = t; | 358 | hp = t; |
330 | } | 359 | } |
331 | } | 360 | } |
@@ -334,8 +363,17 @@ asmlinkage long sys_slave_non_rt_threads(void) | |||
334 | } while(t != leader); | 363 | } while(t != leader); |
335 | 364 | ||
336 | if (hp) { | 365 | if (hp) { |
366 | TRACE_CUR("found hp in group: %s/%d\n", hp->comm, hp->pid); | ||
367 | |||
337 | /* set up inheritance */ | 368 | /* set up inheritance */ |
338 | 369 | leader->hp_group = hp; | |
370 | |||
371 | t = leader; | ||
372 | do { | ||
373 | if (tsk_rt(t)->slave) { | ||
374 | litmus->increase_prio(t); | ||
375 | } | ||
376 | } while(t != leader); | ||
339 | } | 377 | } |
340 | 378 | ||
341 | read_unlock_irq(&tasklist_lock); | 379 | read_unlock_irq(&tasklist_lock); |
@@ -343,6 +381,31 @@ asmlinkage long sys_slave_non_rt_threads(void) | |||
343 | return 0; | 381 | return 0; |
344 | } | 382 | } |
345 | 383 | ||
384 | #if defined(CONFIG_LITMUS_NVIDIA) && defined(CONFIG_LITMUS_AFFINITY_LOCKING) | ||
385 | void init_gpu_affinity_state(struct task_struct* p) | ||
386 | { | ||
387 | // under-damped | ||
388 | //p->rt_param.gpu_fb_param_a = _frac(14008, 10000); | ||
389 | //p->rt_param.gpu_fb_param_b = _frac(16024, 10000); | ||
390 | |||
391 | #if 0 | ||
392 | // emperical; | ||
393 | p->rt_param.gpu_fb_param_a[0] = _frac(7550, 10000); | ||
394 | p->rt_param.gpu_fb_param_b[0] = _frac(45800, 10000); | ||
395 | |||
396 | p->rt_param.gpu_fb_param_a[1] = _frac(8600, 10000); | ||
397 | p->rt_param.gpu_fb_param_b[1] = _frac(40000, 10000); | ||
398 | |||
399 | p->rt_param.gpu_fb_param_a[2] = _frac(6890, 10000); | ||
400 | p->rt_param.gpu_fb_param_b[2] = _frac(40000, 10000); | ||
401 | |||
402 | p->rt_param.gpu_fb_param_a[3] = _frac(7580, 10000); | ||
403 | p->rt_param.gpu_fb_param_b[3] = _frac(34590, 10000); | ||
404 | #endif | ||
405 | p->rt_param.gpu_migration = MIG_NONE; | ||
406 | p->rt_param.last_gpu = -1; | ||
407 | } | ||
408 | #endif | ||
346 | 409 | ||
347 | /* p is a real-time task. Re-init its state as a best-effort task. */ | 410 | /* p is a real-time task. Re-init its state as a best-effort task. */ |
348 | static void reinit_litmus_state(struct task_struct* p, int restore) | 411 | static void reinit_litmus_state(struct task_struct* p, int restore) |
@@ -350,6 +413,10 @@ static void reinit_litmus_state(struct task_struct* p, int restore) | |||
350 | struct rt_task user_config = {}; | 413 | struct rt_task user_config = {}; |
351 | void* ctrl_page = NULL; | 414 | void* ctrl_page = NULL; |
352 | 415 | ||
416 | #ifdef CONFIG_LITMUS_NESTED_LOCKING | ||
417 | binheap_order_t prio_order = NULL; | ||
418 | #endif | ||
419 | |||
353 | if (restore) { | 420 | if (restore) { |
354 | /* Safe user-space provided configuration data. | 421 | /* Safe user-space provided configuration data. |
355 | * and allocated page. */ | 422 | * and allocated page. */ |
@@ -357,11 +424,38 @@ static void reinit_litmus_state(struct task_struct* p, int restore) | |||
357 | ctrl_page = p->rt_param.ctrl_page; | 424 | ctrl_page = p->rt_param.ctrl_page; |
358 | } | 425 | } |
359 | 426 | ||
427 | #ifdef CONFIG_LITMUS_NESTED_LOCKING | ||
428 | prio_order = p->rt_param.hp_blocked_tasks.compare; | ||
429 | #endif | ||
430 | |||
360 | /* We probably should not be inheriting any task's priority | 431 | /* We probably should not be inheriting any task's priority |
361 | * at this point in time. | 432 | * at this point in time. |
362 | */ | 433 | */ |
363 | WARN_ON(p->rt_param.inh_task); | 434 | WARN_ON(p->rt_param.inh_task); |
364 | 435 | ||
436 | #ifdef CONFIG_LITMUS_NESTED_LOCKING | ||
437 | WARN_ON(p->rt_param.blocked_lock); | ||
438 | WARN_ON(!binheap_empty(&p->rt_param.hp_blocked_tasks)); | ||
439 | #endif | ||
440 | |||
441 | #ifdef CONFIG_LITMUS_SOFTIRQD | ||
442 | /* We probably should not have any tasklets executing for | ||
443 | * us at this time. | ||
444 | */ | ||
445 | WARN_ON(p->rt_param.cur_klitirqd); | ||
446 | WARN_ON(atomic_read(&p->rt_param.klitirqd_sem_stat) == HELD); | ||
447 | |||
448 | if(p->rt_param.cur_klitirqd) | ||
449 | flush_pending(p->rt_param.cur_klitirqd, p); | ||
450 | |||
451 | if(atomic_read(&p->rt_param.klitirqd_sem_stat) == HELD) | ||
452 | up_and_set_stat(p, NOT_HELD, &p->rt_param.klitirqd_sem); | ||
453 | #endif | ||
454 | |||
455 | #ifdef CONFIG_LITMUS_NVIDIA | ||
456 | WARN_ON(p->rt_param.held_gpus != 0); | ||
457 | #endif | ||
458 | |||
365 | /* Cleanup everything else. */ | 459 | /* Cleanup everything else. */ |
366 | memset(&p->rt_param, 0, sizeof(p->rt_param)); | 460 | memset(&p->rt_param, 0, sizeof(p->rt_param)); |
367 | 461 | ||
@@ -370,6 +464,15 @@ static void reinit_litmus_state(struct task_struct* p, int restore) | |||
370 | p->rt_param.task_params = user_config; | 464 | p->rt_param.task_params = user_config; |
371 | p->rt_param.ctrl_page = ctrl_page; | 465 | p->rt_param.ctrl_page = ctrl_page; |
372 | } | 466 | } |
467 | |||
468 | #if defined(CONFIG_LITMUS_NVIDIA) && defined(CONFIG_LITMUS_AFFINITY_LOCKING) | ||
469 | init_gpu_affinity_state(p); | ||
470 | #endif | ||
471 | |||
472 | #ifdef CONFIG_LITMUS_NESTED_LOCKING | ||
473 | INIT_BINHEAP_HANDLE(&p->rt_param.hp_blocked_tasks, prio_order); | ||
474 | raw_spin_lock_init(&p->rt_param.hp_blocked_tasks_lock); | ||
475 | #endif | ||
373 | } | 476 | } |
374 | 477 | ||
375 | long __litmus_admit_task(struct task_struct* tsk) | 478 | long __litmus_admit_task(struct task_struct* tsk) |
@@ -398,6 +501,25 @@ long __litmus_admit_task(struct task_struct* tsk) | |||
398 | bheap_node_init(&tsk_rt(tsk)->heap_node, tsk); | 501 | bheap_node_init(&tsk_rt(tsk)->heap_node, tsk); |
399 | } | 502 | } |
400 | 503 | ||
504 | #ifdef CONFIG_LITMUS_NVIDIA | ||
505 | atomic_set(&tsk_rt(tsk)->nv_int_count, 0); | ||
506 | #endif | ||
507 | #if defined(CONFIG_LITMUS_NVIDIA) && defined(CONFIG_LITMUS_AFFINITY_LOCKING) | ||
508 | init_gpu_affinity_state(tsk); | ||
509 | #endif | ||
510 | #ifdef CONFIG_LITMUS_NESTED_LOCKING | ||
511 | tsk_rt(tsk)->blocked_lock = NULL; | ||
512 | raw_spin_lock_init(&tsk_rt(tsk)->hp_blocked_tasks_lock); | ||
513 | //INIT_BINHEAP_HANDLE(&tsk_rt(tsk)->hp_blocked_tasks, prio_order); // done by scheduler | ||
514 | #endif | ||
515 | #ifdef CONFIG_LITMUS_SOFTIRQD | ||
516 | /* proxy thread off by default */ | ||
517 | tsk_rt(tsk)is_proxy_thread = 0; | ||
518 | tsk_rt(tsk)cur_klitirqd = NULL; | ||
519 | mutex_init(&tsk_rt(tsk)->klitirqd_sem); | ||
520 | atomic_set(&tsk_rt(tsk)->klitirqd_sem_stat, NOT_HELD); | ||
521 | #endif | ||
522 | |||
401 | retval = litmus->admit_task(tsk); | 523 | retval = litmus->admit_task(tsk); |
402 | 524 | ||
403 | if (!retval) { | 525 | if (!retval) { |
@@ -475,7 +597,7 @@ static void synch_on_plugin_switch(void* info) | |||
475 | */ | 597 | */ |
476 | int switch_sched_plugin(struct sched_plugin* plugin) | 598 | int switch_sched_plugin(struct sched_plugin* plugin) |
477 | { | 599 | { |
478 | unsigned long flags; | 600 | //unsigned long flags; |
479 | int ret = 0; | 601 | int ret = 0; |
480 | 602 | ||
481 | BUG_ON(!plugin); | 603 | BUG_ON(!plugin); |
@@ -489,8 +611,15 @@ int switch_sched_plugin(struct sched_plugin* plugin) | |||
489 | while (atomic_read(&cannot_use_plugin) < num_online_cpus()) | 611 | while (atomic_read(&cannot_use_plugin) < num_online_cpus()) |
490 | cpu_relax(); | 612 | cpu_relax(); |
491 | 613 | ||
614 | #ifdef CONFIG_LITMUS_SOFTIRQD | ||
615 | if(!klitirqd_is_dead()) | ||
616 | { | ||
617 | kill_klitirqd(); | ||
618 | } | ||
619 | #endif | ||
620 | |||
492 | /* stop task transitions */ | 621 | /* stop task transitions */ |
493 | raw_spin_lock_irqsave(&task_transition_lock, flags); | 622 | //raw_spin_lock_irqsave(&task_transition_lock, flags); |
494 | 623 | ||
495 | /* don't switch if there are active real-time tasks */ | 624 | /* don't switch if there are active real-time tasks */ |
496 | if (atomic_read(&rt_task_count) == 0) { | 625 | if (atomic_read(&rt_task_count) == 0) { |
@@ -508,7 +637,7 @@ int switch_sched_plugin(struct sched_plugin* plugin) | |||
508 | } else | 637 | } else |
509 | ret = -EBUSY; | 638 | ret = -EBUSY; |
510 | out: | 639 | out: |
511 | raw_spin_unlock_irqrestore(&task_transition_lock, flags); | 640 | //raw_spin_unlock_irqrestore(&task_transition_lock, flags); |
512 | atomic_set(&cannot_use_plugin, 0); | 641 | atomic_set(&cannot_use_plugin, 0); |
513 | return ret; | 642 | return ret; |
514 | } | 643 | } |