Date: Sat, 24 Jul 1999 20:05:55 +0200 (CEST) From: Rik van Riel <riel@nl.linux.org> To: Linux Kernel <linux-kernel@vger.rutgers.edu> Subject: [PATCH] SCHED_IDLE Hi, I believe I have created a rather 'safe' SCHED_IDLE patch now. I haven't run it yet (my machine is slow and busy with something large at the moment), but I have verified that the files in question compile and the patch looks trivial enough ;) I hope you enjoy it -- and don't forget to grab the changed rtnice utility: http://www.nl.linux.org/~riel/patches/rtnice.c have fun, Rik -- Open Source: you deserve to be in control of your data. +-------------------------------------------------------------------+ | Le Reseau netwerksystemen BV: http://www.reseau.nl/ | | Linux Memory Management site: http://www.linux.eu.org/Linux-MM/ | | Nederlandse Linux documentatie: http://www.nl.linux.org/ | +-------------------------------------------------------------------+ --- linux/kernel/sched.c.12 Sat Jul 24 16:41:57 1999 +++ linux/kernel/sched.c Sat Jul 24 19:56:32 1999 @@ -124,6 +124,13 @@ char __pad [SMP_CACHE_BYTES]; } aligned_data [NR_CPUS] __cacheline_aligned = { {{&init_task,0}}}; +/* + * SCHED_IDLE defines. + */ +sched_idle_t sched_idle = { + 0, /* disabled, use sysctl to enable */ +}; + #define cpu_curr(cpu) aligned_data[(cpu)].schedule_data.curr struct kernel_stat kstat = { 0 }; @@ -166,8 +173,7 @@ * into account). */ if (p->policy != SCHED_OTHER) { - weight = 1000 + p->rt_priority; - goto out; + goto rt_or_idle; } /* @@ -181,6 +187,7 @@ if (!weight) goto out; +calculate_bonus: #ifdef __SMP__ /* Give a largish advantage to the same processor... */ /* (this is equivalent to penalizing other processors) */ @@ -195,6 +202,28 @@ out: return weight; + +rt_or_idle: + if (p->policy == SCHED_IDLE) { + weight = p->counter; + /* if it can deadlock the system, we'll avoid deadlock by + * temporarily giving the task a higher priority. + * We don't want SCHED_IDLE tasks to take advantage of this + * situation however, so the task pays a heavy penalty. + * -- Rik + */ + if (p->lock_depth >= 0 || signal_pending(p)) { + p->counter >>= 1; + } else { + /* requirement: weight + bonus < 0 !!! */ + weight -= HZ; + } + goto calculate_bonus; + } else { /* SCHED_FIFO or SCHED_RR */ + weight = 1000 + p->rt_priority; + } + goto out; + } /* @@ -1714,7 +1743,7 @@ else { retval = -EINVAL; if (policy != SCHED_FIFO && policy != SCHED_RR && - policy != SCHED_OTHER) + policy != SCHED_OTHER && policy != SCHED_IDLE) goto out_unlock; } @@ -1725,12 +1754,19 @@ retval = -EINVAL; if (lp.sched_priority < 0 || lp.sched_priority > 99) goto out_unlock; - if ((policy == SCHED_OTHER) != (lp.sched_priority == 0)) + if ((policy == SCHED_OTHER || policy == SCHED_IDLE) && + (lp.sched_priority != 0)) goto out_unlock; retval = -EPERM; if ((policy == SCHED_FIFO || policy == SCHED_RR) && !capable(CAP_SYS_NICE)) + goto out_unlock; + if (policy == SCHED_IDLE && (!sched_idle.enabled || + !capable(CAP_SYS_NICE))) + goto out_unlock; + if (p->policy == SCHED_IDLE && policy != SCHED_IDLE && + !capable(CAP_SYS_NICE)) goto out_unlock; if ((current->euid != p->euid) && (current->euid != p->uid) && !capable(CAP_SYS_NICE)) --- linux/kernel/sysctl.c.12 Sat Jul 24 19:38:16 1999 +++ linux/kernel/sysctl.c Sat Jul 24 19:33:41 1999 @@ -210,6 +210,8 @@ #endif {KERN_MAX_THREADS, "threads-max", &max_threads, sizeof(int), 0644, NULL, &proc_dointvec}, + {KERN_SCHED_IDLE_EN, "sched_idle_enable", &sched_idle.enabled, sizeof(int), + 0644, NULL, &proc_dointvec}, {0} }; --- linux/include/linux/sysctl.h.12 Sat Jul 24 18:55:26 1999 +++ linux/include/linux/sysctl.h Sat Jul 24 19:13:38 1999 @@ -101,7 +101,8 @@ KERN_MSGMAX=35, /* int: Maximum size of a messege */ KERN_MSGMNB=36, /* int: Maximum message queue size */ KERN_MSGPOOL=37, /* int: Maximum system message pool size */ - KERN_MAX_THREADS=38 /* int: Maximum nr of threads in the system */ + KERN_MAX_THREADS=38, /* int: Maximum nr of threads in the system */ + KERN_SCHED_IDLE_EN=39 /* int: SCHED_IDLE enabled for mortals? */ }; --- linux/include/linux/sched.h.12 Sat Jul 24 16:40:55 1999 +++ linux/include/linux/sched.h Sat Jul 24 19:54:14 1999 @@ -88,6 +88,7 @@ #define SCHED_OTHER 0 #define SCHED_FIFO 1 #define SCHED_RR 2 +#define SCHED_IDLE 3 /* * This is an additional bit set when we want to @@ -98,6 +99,16 @@ struct sched_param { int sched_priority; }; + +/* + * SCHED_IDLE control structure. For now it only controls + * whether SCHED_IDLE is enabled for mere mortals... + */ +typedef struct sched_idle_t +{ + int enabled; +} sched_idle_t; +extern sched_idle_t sched_idle; #ifndef NULL #define NULL ((void *) 0) - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/