aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/litmus.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-09-11 22:42:51 -0400
committerGlenn Elliott <gelliott@cs.unc.edu>2012-09-11 22:42:51 -0400
commitc1d1979c99ca397241da4e3d7e0cb77f7ec28240 (patch)
tree2a988aae1ae7c08891543e844171cbcb4281a5bb /litmus/litmus.c
parentfd3aa01f176cf12b1625f4f46ba01f3340bb57ed (diff)
parent55e04c94b925b0790c2ae0a79f16e939e9bb2846 (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.c161
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 */
25atomic_t rt_task_count = ATOMIC_INIT(0); 29atomic_t rt_task_count = ATOMIC_INIT(0);
26static DEFINE_RAW_SPINLOCK(task_transition_lock); 30static DEFINE_RAW_SPINLOCK(task_transition_lock);
@@ -51,6 +55,28 @@ void bheap_node_free(struct bheap_node* hn)
51struct release_heap* release_heap_alloc(int gfp_flags); 55struct release_heap* release_heap_alloc(int gfp_flags);
52void release_heap_free(struct release_heap* rh); 56void 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 */
67asmlinkage 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
73asmlinkage 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
302long __litmus_admit_task(struct task_struct* tsk); 331long __litmus_admit_task(struct task_struct* tsk);
303 332
304asmlinkage long sys_slave_non_rt_threads(void) 333asmlinkage 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)
385void 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. */
348static void reinit_litmus_state(struct task_struct* p, int restore) 411static 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
375long __litmus_admit_task(struct task_struct* tsk) 478long __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 */
476int switch_sched_plugin(struct sched_plugin* plugin) 598int 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;
510out: 639out:
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}