diff options
-rw-r--r-- | include/litmus/rt_param.h | 6 | ||||
-rw-r--r-- | include/litmus/unistd_32.h | 4 | ||||
-rw-r--r-- | include/litmus/unistd_64.h | 4 | ||||
-rw-r--r-- | litmus/litmus.c | 109 |
4 files changed, 98 insertions, 25 deletions
diff --git a/include/litmus/rt_param.h b/include/litmus/rt_param.h index a1f3613ebeed..02b750a9570b 100644 --- a/include/litmus/rt_param.h +++ b/include/litmus/rt_param.h | |||
@@ -284,6 +284,12 @@ struct rt_param { | |||
284 | struct litmus_lock* blocked_lock; | 284 | struct litmus_lock* blocked_lock; |
285 | #endif | 285 | #endif |
286 | 286 | ||
287 | |||
288 | struct task_struct* hp_group; | ||
289 | unsigned int is_slave:1; | ||
290 | unsigned int has_slaves:1; | ||
291 | |||
292 | |||
287 | #ifdef CONFIG_NP_SECTION | 293 | #ifdef CONFIG_NP_SECTION |
288 | /* For the FMLP under PSN-EDF, it is required to make the task | 294 | /* For the FMLP under PSN-EDF, it is required to make the task |
289 | * non-preemptive from kernel space. In order not to interfere with | 295 | * non-preemptive from kernel space. In order not to interfere with |
diff --git a/include/litmus/unistd_32.h b/include/litmus/unistd_32.h index 4fa514c89605..4fd92956d13f 100644 --- a/include/litmus/unistd_32.h +++ b/include/litmus/unistd_32.h | |||
@@ -21,4 +21,6 @@ | |||
21 | #define __NR_litmus_dgl_unlock __LSC(13) | 21 | #define __NR_litmus_dgl_unlock __LSC(13) |
22 | #define __NR_register_nv_device __LSC(14) | 22 | #define __NR_register_nv_device __LSC(14) |
23 | 23 | ||
24 | #define NR_litmus_syscalls 15 | 24 | #define __NR_slave_non_rt_threads _LSC(15) |
25 | |||
26 | #define NR_litmus_syscalls 16 | ||
diff --git a/include/litmus/unistd_64.h b/include/litmus/unistd_64.h index f80dc45dc185..abb45c181e8e 100644 --- a/include/litmus/unistd_64.h +++ b/include/litmus/unistd_64.h | |||
@@ -36,5 +36,7 @@ __SYSCALL(__NR_litmus_dgl_unlock, sys_litmus_dgl_unlock) | |||
36 | #define __NR_register_nv_device __LSC(14) | 36 | #define __NR_register_nv_device __LSC(14) |
37 | __SYSCALL(__NR_register_nv_device, sys_register_nv_device) | 37 | __SYSCALL(__NR_register_nv_device, sys_register_nv_device) |
38 | 38 | ||
39 | #define __NR_slave_non_rt_threads __LSC(15) | ||
40 | __SYSCALL(__NR_slave_non_rt_threads, sys_slave_non_rt_threads) | ||
39 | 41 | ||
40 | #define NR_litmus_syscalls 15 | 42 | #define NR_litmus_syscalls 16 |
diff --git a/litmus/litmus.c b/litmus/litmus.c index 53727d699915..83e8ef3f42af 100644 --- a/litmus/litmus.c +++ b/litmus/litmus.c | |||
@@ -328,6 +328,59 @@ asmlinkage long sys_null_call(cycles_t __user *ts) | |||
328 | } | 328 | } |
329 | 329 | ||
330 | 330 | ||
331 | long __litmus_admit_task(struct task_struct* tsk); | ||
332 | |||
333 | asmlinkage long sys_slave_non_rt_threads(void) | ||
334 | { | ||
335 | long retval = 0; | ||
336 | struct task_struct *leader = current->group_leader; | ||
337 | struct task_struct *t; | ||
338 | struct task_struct *hp = NULL; | ||
339 | |||
340 | read_lock_irq(&tasklist_lock); | ||
341 | |||
342 | t = leader; | ||
343 | do { | ||
344 | TRACE_CUR("threads in %s/%d: %s/%d:\n", leader->comm, leader->pid, t->comm, t->pid); | ||
345 | |||
346 | if (tsk_rt(t)->heap_node == NULL) { | ||
347 | retval = __litmus_admit_task(t); | ||
348 | |||
349 | if (retval != 0) break; | ||
350 | |||
351 | /* hasn't been admitted into rt. make it a slave. */ | ||
352 | tsk_rt(t)->slave = 1; | ||
353 | } | ||
354 | else { | ||
355 | tsk_rt(t)->has_slaves = 1; | ||
356 | |||
357 | if (is_realtime(t) && litmus->compare(t, hp)) { | ||
358 | hp = t; | ||
359 | } | ||
360 | } | ||
361 | |||
362 | t = next_thread(t); | ||
363 | } while(t != leader); | ||
364 | |||
365 | if (hp) { | ||
366 | TRACE_CUR("found hp in group: %s/%d\n", hp->comm, hp->pid); | ||
367 | |||
368 | /* set up inheritance */ | ||
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); | ||
377 | } | ||
378 | |||
379 | read_unlock_irq(&tasklist_lock); | ||
380 | |||
381 | return 0; | ||
382 | } | ||
383 | |||
331 | #if defined(CONFIG_LITMUS_NVIDIA) && defined(CONFIG_LITMUS_AFFINITY_LOCKING) | 384 | #if defined(CONFIG_LITMUS_NVIDIA) && defined(CONFIG_LITMUS_AFFINITY_LOCKING) |
332 | void init_gpu_affinity_state(struct task_struct* p) | 385 | void init_gpu_affinity_state(struct task_struct* p) |
333 | { | 386 | { |
@@ -422,32 +475,11 @@ static void reinit_litmus_state(struct task_struct* p, int restore) | |||
422 | #endif | 475 | #endif |
423 | } | 476 | } |
424 | 477 | ||
425 | long litmus_admit_task(struct task_struct* tsk) | 478 | long __litmus_admit_task(struct task_struct* tsk) |
426 | { | 479 | { |
427 | long retval = 0; | 480 | long retval = 0; |
428 | unsigned long flags; | 481 | unsigned long flags; |
429 | 482 | ||
430 | BUG_ON(is_realtime(tsk)); | ||
431 | |||
432 | if (get_rt_relative_deadline(tsk) == 0 || | ||
433 | get_exec_cost(tsk) > | ||
434 | min(get_rt_relative_deadline(tsk), get_rt_period(tsk)) ) { | ||
435 | TRACE_TASK(tsk, | ||
436 | "litmus admit: invalid task parameters " | ||
437 | "(e = %lu, p = %lu, d = %lu)\n", | ||
438 | get_exec_cost(tsk), get_rt_period(tsk), | ||
439 | get_rt_relative_deadline(tsk)); | ||
440 | retval = -EINVAL; | ||
441 | goto out; | ||
442 | } | ||
443 | |||
444 | if (!cpu_online(get_partition(tsk))) { | ||
445 | TRACE_TASK(tsk, "litmus admit: cpu %d is not online\n", | ||
446 | get_partition(tsk)); | ||
447 | retval = -EINVAL; | ||
448 | goto out; | ||
449 | } | ||
450 | |||
451 | INIT_LIST_HEAD(&tsk_rt(tsk)->list); | 483 | INIT_LIST_HEAD(&tsk_rt(tsk)->list); |
452 | 484 | ||
453 | /* avoid scheduler plugin changing underneath us */ | 485 | /* avoid scheduler plugin changing underneath us */ |
@@ -469,7 +501,6 @@ long litmus_admit_task(struct task_struct* tsk) | |||
469 | bheap_node_init(&tsk_rt(tsk)->heap_node, tsk); | 501 | bheap_node_init(&tsk_rt(tsk)->heap_node, tsk); |
470 | } | 502 | } |
471 | 503 | ||
472 | |||
473 | #ifdef CONFIG_LITMUS_NVIDIA | 504 | #ifdef CONFIG_LITMUS_NVIDIA |
474 | atomic_set(&tsk_rt(tsk)->nv_int_count, 0); | 505 | atomic_set(&tsk_rt(tsk)->nv_int_count, 0); |
475 | #endif | 506 | #endif |
@@ -499,6 +530,38 @@ long litmus_admit_task(struct task_struct* tsk) | |||
499 | 530 | ||
500 | out_unlock: | 531 | out_unlock: |
501 | raw_spin_unlock_irqrestore(&task_transition_lock, flags); | 532 | raw_spin_unlock_irqrestore(&task_transition_lock, flags); |
533 | |||
534 | return retval; | ||
535 | } | ||
536 | |||
537 | long litmus_admit_task(struct task_struct* tsk) | ||
538 | { | ||
539 | long retval = 0; | ||
540 | unsigned long flags; | ||
541 | |||
542 | BUG_ON(is_realtime(tsk)); | ||
543 | |||
544 | if (get_rt_relative_deadline(tsk) == 0 || | ||
545 | get_exec_cost(tsk) > | ||
546 | min(get_rt_relative_deadline(tsk), get_rt_period(tsk)) ) { | ||
547 | TRACE_TASK(tsk, | ||
548 | "litmus admit: invalid task parameters " | ||
549 | "(e = %lu, p = %lu, d = %lu)\n", | ||
550 | get_exec_cost(tsk), get_rt_period(tsk), | ||
551 | get_rt_relative_deadline(tsk)); | ||
552 | retval = -EINVAL; | ||
553 | goto out; | ||
554 | } | ||
555 | |||
556 | if (!cpu_online(get_partition(tsk))) { | ||
557 | TRACE_TASK(tsk, "litmus admit: cpu %d is not online\n", | ||
558 | get_partition(tsk)); | ||
559 | retval = -EINVAL; | ||
560 | goto out; | ||
561 | } | ||
562 | |||
563 | retval = __litmus_admit_task(tsk); | ||
564 | |||
502 | out: | 565 | out: |
503 | return retval; | 566 | return retval; |
504 | } | 567 | } |