aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/rt_param.h8
-rw-r--r--kernel/litmus.c90
2 files changed, 62 insertions, 36 deletions
diff --git a/include/linux/rt_param.h b/include/linux/rt_param.h
index 8936d2c22f..426a929187 100644
--- a/include/linux/rt_param.h
+++ b/include/linux/rt_param.h
@@ -101,14 +101,6 @@ typedef struct task_rt_param {
101 */ 101 */
102 unsigned int subject_to_srp:1; 102 unsigned int subject_to_srp:1;
103 103
104 /* Ready to receive scheduler signals? */
105 unsigned int signal_ready:1;
106
107 /* scheduler signal list head */
108 unsigned int in_sig_list:1;
109 unsigned int signal:8;
110 struct list_head sig_list;
111
112 /* user controlled parameters */ 104 /* user controlled parameters */
113 rt_param_t basic_params; 105 rt_param_t basic_params;
114 106
diff --git a/kernel/litmus.c b/kernel/litmus.c
index 438b2e7942..ee1e09a627 100644
--- a/kernel/litmus.c
+++ b/kernel/litmus.c
@@ -499,62 +499,96 @@ asmlinkage int sys_scheduler_setup(int cmd, void __user *parameter)
499{ 499{
500 int ret = -EINVAL; 500 int ret = -EINVAL;
501 501
502 switch (cmd) { 502 ret = curr_sched_plugin->scheduler_setup(cmd, parameter);
503 case ENABLE_WEIGHT_CHANGE_SIGNAL:
504 current->rt_param.signal_ready = 1;
505 ret = 0;
506 break;
507 default:
508 ret = curr_sched_plugin->scheduler_setup(cmd, parameter);
509 };
510 503
511 return ret; 504 return ret;
512} 505}
513 506
514/* only call with interrupts disabled! */ 507struct sched_sig {
515void scheduler_signal(struct task_struct *t, unsigned int signo) 508 struct list_head list;
509 struct task_struct* task;
510 unsigned int signal:31;
511 int force:1;
512};
513
514static void __scheduler_signal(struct task_struct *t, unsigned int signo,
515 int force)
516{ 516{
517 struct sched_sig* sig;
518
519 sig = kmalloc(GFP_ATOMIC, sizeof(struct sched_sig));
520 if (!sig) {
521 TRACE_TASK(t, "dropping signal: %u\n", t);
522 return;
523 }
524
517 spin_lock(&sched_sig_list_lock); 525 spin_lock(&sched_sig_list_lock);
518 526
519 if (!t->rt_param.in_sig_list) { 527 sig->signal = signo;
520 get_task_struct(t); 528 sig->force = force;
521 t->rt_param.signal = signo; 529 sig->task = t;
522 t->rt_param.in_sig_list = 1; 530 get_task_struct(t);
523 list_add(&t->rt_param.sig_list, &sched_sig_list); 531 list_add(&sig->list, &sched_sig_list);
524 } else
525 TRACE_TASK(t, "dropping signal: %u\n", t);
526 532
527 spin_unlock(&sched_sig_list_lock); 533 spin_unlock(&sched_sig_list_lock);
528} 534}
529 535
536void scheduler_signal(struct task_struct *t, unsigned int signo)
537{
538 __scheduler_signal(t, signo, 0);
539}
540
541void force_scheduler_signal(struct task_struct *t, unsigned int signo)
542{
543 __scheduler_signal(t, signo, 1);
544}
545
530void send_scheduler_signals(void) 546void send_scheduler_signals(void)
531{ 547{
532 unsigned long flags; 548 unsigned long flags;
533 struct list_head *p, *extra; 549 struct list_head *p, *extra;
534 struct siginfo info; 550 struct siginfo info;
551 struct sched_sig* sig;
535 struct task_struct* t; 552 struct task_struct* t;
536/* 553 struct list_head claimed;
554
537 if (spin_trylock_irqsave(&sched_sig_list_lock, flags)) { 555 if (spin_trylock_irqsave(&sched_sig_list_lock, flags)) {
556 if (list_empty(&sched_sig_list))
557 p = NULL;
558 else {
559 p = sched_sig_list.next;
560 list_del(&sched_sig_list);
561 INIT_LIST_HEAD(&sched_sig_list);
562 }
563 spin_unlock_irqrestore(&sched_sig_list_lock, flags);
564
565 /* abort if there are no signals */
566 if (!p)
567 return;
538 568
539 list_for_each_safe(p, extra, &sched_sig_list) { 569 /* take signal list we just obtained */
570 list_add(&claimed, p);
571
572 list_for_each_safe(p, extra, &claimed) {
540 list_del(p); 573 list_del(p);
541 t = list_entry(p, struct task_struct, 574 sig = list_entry(p, struct sched_sig, list);
542 rt_param.sig_list); 575 t = sig->task;
543 t->rt_param.in_sig_list = 0; 576 info.si_signo = sig->signal;
544 info.si_signo = t->rt_param.signal;
545 info.si_errno = 0; 577 info.si_errno = 0;
546 info.si_code = SI_KERNEL; 578 info.si_code = SI_KERNEL;
547 info.si_pid = 1; 579 info.si_pid = 1;
548 info.si_uid = 0; 580 info.si_uid = 0;
549 TRACE("sending signal %d to %d\n", info.si_signo, 581 TRACE("sending signal %d to %d\n", info.si_signo,
550 t->pid); 582 t->pid);
551 force_sig_info(t->rt_param.signal, &info, t); 583 if (sig->force)
584 force_sig_info(sig->signal, &info, t);
585 else
586 send_sig_info(sig->signal, &info, t);
552 put_task_struct(t); 587 put_task_struct(t);
588 kfree(sig);
553 } 589 }
554
555 spin_unlock_irqrestore(&sched_sig_list_lock, flags);
556 } 590 }
557*/ 591
558} 592}
559 593
560static inline void np_mem_error(struct task_struct* t, const char* reason) 594static inline void np_mem_error(struct task_struct* t, const char* reason)
@@ -562,7 +596,7 @@ static inline void np_mem_error(struct task_struct* t, const char* reason)
562 if (t->state != TASK_DEAD && !(t->flags & PF_EXITING)) { 596 if (t->state != TASK_DEAD && !(t->flags & PF_EXITING)) {
563 TRACE("np section: %s => %s/%d killed\n", 597 TRACE("np section: %s => %s/%d killed\n",
564 reason, t->comm, t->pid); 598 reason, t->comm, t->pid);
565 scheduler_signal(t, SIGKILL); 599 force_scheduler_signal(t, SIGKILL);
566 } 600 }
567} 601}
568 602