--- orig/linux-2.4.20/mm/mlock.c 2001-09-17 18:30:23.000000000 -0400 +++ linux/mm/mlock.c 2003-03-19 22:05:01.000000000 -0500 @@ -12,6 +12,10 @@ #include #include + +extern unsigned long enable_user_rt; + + static inline int mlock_fixup_all(struct vm_area_struct * vma, int newflags) { spin_lock(&vma->vm_mm->page_table_lock); @@ -151,7 +155,7 @@ static int do_mlock(unsigned long start, struct vm_area_struct * vma, * next; int error; - if (on && !capable(CAP_IPC_LOCK)) + if (on && !capable(CAP_IPC_LOCK) && !enable_user_rt) return -EPERM; len = PAGE_ALIGN(len); end = start + len; @@ -241,7 +245,7 @@ static int do_mlockall(int flags) unsigned int def_flags; struct vm_area_struct * vma; - if (!capable(CAP_IPC_LOCK)) + if (!capable(CAP_IPC_LOCK) && !enable_user_rt) return -EPERM; def_flags = 0; --- orig/linux-2.4.20/kernel/sched.c 2003-03-17 23:24:02.000000000 -0500 +++ linux/kernel/sched.c 2003-03-19 22:06:05.000000000 -0500 @@ -43,6 +43,14 @@ extern void immediate_bh(void); unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */ +unsigned long rt_period_start = 0; +unsigned long rt_period_end = 0; +unsigned long rt_period_remain = 0; +unsigned long rt_period_length = 50; +unsigned long rt_period_reserved = 45; +unsigned long enable_user_rt = 0; + + extern void mem_use(void); /* @@ -188,7 +196,35 @@ static inline int goodness(struct task_s * runqueue (taking priorities within processes * into account). */ + + + + /* + * check if we are in the right time period + * + * XXX if it burns though it's entire quantum and + * into the next ? + * + */ + if (jiffies >= rt_period_end) { + /* no, start over from now */ + rt_period_start = jiffies; + rt_period_end = rt_period_length + rt_period_start; + rt_period_remain = rt_period_reserved; + } + + /* + * is there any remaining time ? + * + */ + + if (rt_period_remain > 0) { weight = 1000 + p->rt_priority; + } else { + /* redundent, for clarity */ + weight = -1; + } + out: return weight; } @@ -955,7 +991,7 @@ static int setscheduler(pid_t pid, int p retval = -EPERM; if ((policy == SCHED_FIFO || policy == SCHED_RR) && - !capable(CAP_SYS_NICE)) + !capable(CAP_SYS_NICE) && !enable_user_rt) goto out_unlock; if ((current->euid != p->euid) && (current->euid != p->uid) && !capable(CAP_SYS_NICE)) --- orig/linux-2.4.20/kernel/sysctl.c 2003-03-17 23:24:02.000000000 -0500 +++ linux/kernel/sysctl.c 2003-03-19 22:03:03.000000000 -0500 @@ -51,6 +51,12 @@ extern int sysrq_enabled; extern int core_uses_pid; extern int cad_pid; + +extern unsigned long rt_period_length; +extern unsigned long rt_period_reserved; +extern unsigned long enable_user_rt; + + /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ static int maxolduid = 65535; static int minolduid; @@ -260,6 +266,13 @@ static ctl_table kern_table[] = { {KERN_LOWLATENCY, "lowlatency", &enable_lowlatency, sizeof (int), 0644, NULL, &proc_dointvec}, #endif + + {KERN_FIFOSCHED_PERIOD, "rtsched-period", &rt_period_length, + sizeof (int), 0644, NULL, &proc_dointvec}, + {KERN_FIFOSCHED_RESERV, "rtsched-reserve", + &rt_period_reserved, sizeof (int), 0644, NULL, &proc_dointvec}, + {KERN_USERRT_SYSCTL, "userrealtime", + &enable_user_rt, sizeof (int), 0644, NULL, &proc_dointvec}, {0} }; --- orig/linux-2.4.20/include/linux/sysctl.h 2003-03-17 23:24:02.000000000 -0500 +++ linux/include/linux/sysctl.h 2003-03-19 21:40:56.000000000 -0500 @@ -125,6 +125,10 @@ enum KERN_TAINTED=53, /* int: various kernel tainted flags */ KERN_CADPID=54, /* int: PID of the process to notify on CAD */ KERN_LOWLATENCY=55, /* int: enable low latency scheduling */ + KERN_FIFOSCHED_PERIOD=56, /* int: max time rt processes can take up */ + KERN_FIFOSCHED_RESERV=57, /* "" */ + KERN_USERRT_SYSCTL=58, /* int: let users mlock and use rt */ + KERN_USER_MLOCK_MAX=59, /* int: max memory all users can mlock */ }; --- orig/linux-2.4.20/kernel/timer.c 2002-11-28 18:53:15.000000000 -0500 +++ linux/kernel/timer.c 2003-03-18 12:41:05.000000000 -0500 @@ -105,6 +105,16 @@ static struct list_head * run_timer_list #define NOOF_TVECS (sizeof(tvecs) / sizeof(tvecs[0])) +extern unsigned long rt_period_start; +extern unsigned long rt_period_end; +extern unsigned long rt_period_remain; +extern unsigned long rt_period_length; +extern unsigned long rt_period_reserved; + + + + + void init_timervecs (void) { int i; @@ -610,6 +620,15 @@ void update_process_times(int user_tick) p->need_resched = 1; } } + + if (p->policy == SCHED_FIFO) { + if (rt_period_remain == 0) { + p->need_resched = 1; + } else { + rt_period_remain--; + } + } + if (p->nice > 0) kstat.per_cpu_nice[cpu] += user_tick; else