2005-01-09 17:16:27

by utz lehmann

[permalink] [raw]
Subject: [PATCH] scheduling priorities with rlimit

Hi

I really like the idea of controlling the maximum settable scheduling
priorities via rlimit. See the Realtime LSM thread. I want to give users
the right to raise the priority of previously niced jobs.

I have modified Chris Wright's patch (against 2.6.10):
(http://marc.theaimsgroup.com/?l=linux-kernel&m=110513793228776&w=2)

- allow always to increase nice levels (lower priority).
- set the default for RLIMIT_PRIO to 0.
- add the other architectures.

With this the default is compatible with the old behavior.

With RLIMIT_PRIO > 0 a user is able to raise the priority up to the
value. 0-39 for nice levels 19 .. -20, 40-139 for realtime priorities
(0 .. 99).

It can be simply set in /etc/security/limits.conf with a patched PAM.

I have tested it on x86 incl. jack + audio apps.


Is this approach suitable for mainline?
Is the patch ok?

You can find PAM patches and rpms for FC 3 at
http://www.s2y4n2c.de/linux/rlimit_prio/


utz

Signed off by: utz lehmann <[email protected]>

diff -Nrup linux-2.6.10/include/linux/sched.h linux-2.6.10-prio/include/linux/sched.h
--- linux-2.6.10/include/linux/sched.h 2004-12-24 22:33:59.000000000 +0100
+++ linux-2.6.10-prio/include/linux/sched.h 2005-01-09 02:42:27.459948519 +0100
@@ -738,6 +738,7 @@ extern void sched_idle_next(void);
extern void set_user_nice(task_t *p, long nice);
extern int task_prio(const task_t *p);
extern int task_nice(const task_t *p);
+extern int nice_to_prio(const int nice);
extern int task_curr(const task_t *p);
extern int idle_cpu(int cpu);

diff -Nrup linux-2.6.10/kernel/sched.c linux-2.6.10-prio/kernel/sched.c
--- linux-2.6.10/kernel/sched.c 2004-12-24 22:35:24.000000000 +0100
+++ linux-2.6.10-prio/kernel/sched.c 2005-01-09 02:50:42.146306514 +0100
@@ -3008,12 +3008,8 @@ asmlinkage long sys_nice(int increment)
* We don't have to worry. Conceptually one call occurs first
* and we have a single winner.
*/
- if (increment < 0) {
- if (!capable(CAP_SYS_NICE))
- return -EPERM;
- if (increment < -40)
- increment = -40;
- }
+ if (increment < -40)
+ increment = -40;
if (increment > 40)
increment = 40;

@@ -3023,6 +3019,12 @@ asmlinkage long sys_nice(int increment)
if (nice > 19)
nice = 19;

+ if (increment < 0 &&
+ (MAX_PRIO-1) - NICE_TO_PRIO(nice) >
+ current->signal->rlim[RLIMIT_PRIO].rlim_cur &&
+ !capable(CAP_SYS_NICE))
+ return -EPERM;
+
retval = security_task_setnice(current, nice);
if (retval)
return retval;
@@ -3056,6 +3058,15 @@ int task_nice(const task_t *p)
}

/**
+ * nice_to_prio - return priority of give nice value
+ * @nice: nice value
+ */
+int nice_to_prio(const int nice)
+{
+ return NICE_TO_PRIO(nice);
+}
+
+/**
* idle_cpu - is a given cpu idle currently?
* @cpu: the processor in question.
*/
@@ -3139,6 +3150,7 @@ recheck:

retval = -EPERM;
if ((policy == SCHED_FIFO || policy == SCHED_RR) &&
+ lp.sched_priority+40 > p->signal->rlim[RLIMIT_PRIO].rlim_cur &&
!capable(CAP_SYS_NICE))
goto out_unlock;
if ((current->euid != p->euid) && (current->euid != p->uid) &&
diff -Nrup linux-2.6.10/kernel/sys.c linux-2.6.10-prio/kernel/sys.c
--- linux-2.6.10/kernel/sys.c 2004-12-24 22:33:59.000000000 +0100
+++ linux-2.6.10-prio/kernel/sys.c 2005-01-09 03:34:54.618507222 +0100
@@ -224,7 +224,10 @@ static int set_one_prio(struct task_stru
error = -EPERM;
goto out;
}
- if (niceval < task_nice(p) && !capable(CAP_SYS_NICE)) {
+ if (niceval < task_nice(p) &&
+ (MAX_PRIO-1) - nice_to_prio(niceval) >
+ p->signal->rlim[RLIMIT_PRIO].rlim_cur &&
+ !capable(CAP_SYS_NICE)) {
error = -EACCES;
goto out;
}
diff -Nrup linux-2.6.10/include/asm-alpha/resource.h linux-2.6.10-prio/include/asm-alpha/resource.h
--- linux-2.6.10/include/asm-alpha/resource.h 2004-12-24 22:33:51.000000000 +0100
+++ linux-2.6.10-prio/include/asm-alpha/resource.h 2005-01-09 04:19:22.581658112 +0100
@@ -18,8 +18,9 @@
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_PRIO 13 /* maximum scheduling priority */

-#define RLIM_NLIMITS 13
+#define RLIM_NLIMITS 14

/*
* SuS says limits have to be unsigned. Fine, it's unsigned, but
@@ -45,6 +46,7 @@
{LONG_MAX, LONG_MAX}, /* RLIMIT_LOCKS */ \
{MAX_SIGPENDING, MAX_SIGPENDING}, /* RLIMIT_SIGPENDING */ \
{MQ_BYTES_MAX, MQ_BYTES_MAX}, /* RLIMIT_MSGQUEUE */ \
+ { 0, 0}, /* RLIMIT_PRIO */ \
}

#endif /* __KERNEL__ */
diff -Nrup linux-2.6.10/include/asm-arm/resource.h linux-2.6.10-prio/include/asm-arm/resource.h
--- linux-2.6.10/include/asm-arm/resource.h 2004-12-24 22:35:25.000000000 +0100
+++ linux-2.6.10-prio/include/asm-arm/resource.h 2005-01-09 04:19:47.831161464 +0100
@@ -18,8 +18,9 @@
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_PRIO 13 /* maximum scheduling priority */

-#define RLIM_NLIMITS 13
+#define RLIM_NLIMITS 14

#ifdef __KERNEL__

@@ -44,6 +45,7 @@
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ MAX_SIGPENDING, MAX_SIGPENDING}, \
{ MQ_BYTES_MAX, MQ_BYTES_MAX}, \
+ { 0, 0 }, \
}

#endif /* __KERNEL__ */
diff -Nrup linux-2.6.10/include/asm-arm26/resource.h linux-2.6.10-prio/include/asm-arm26/resource.h
--- linux-2.6.10/include/asm-arm26/resource.h 2004-12-24 22:33:49.000000000 +0100
+++ linux-2.6.10-prio/include/asm-arm26/resource.h 2005-01-09 04:20:16.152359541 +0100
@@ -18,8 +18,9 @@
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_PRIO 13 /* maximum scheduling priority */

-#define RLIM_NLIMITS 13
+#define RLIM_NLIMITS 14

#ifdef __KERNEL__

@@ -44,6 +45,7 @@
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ MAX_SIGPENDING, MAX_SIGPENDING}, \
{ MQ_BYTES_MAX, MQ_BYTES_MAX}, \
+ { 0, 0 }, \
}

#endif /* __KERNEL__ */
diff -Nrup linux-2.6.10/include/asm-cris/resource.h linux-2.6.10-prio/include/asm-cris/resource.h
--- linux-2.6.10/include/asm-cris/resource.h 2004-12-24 22:35:01.000000000 +0100
+++ linux-2.6.10-prio/include/asm-cris/resource.h 2005-01-09 04:20:25.483436038 +0100
@@ -18,8 +18,9 @@
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_PRIO 13 /* maximum scheduling priority */

-#define RLIM_NLIMITS 13
+#define RLIM_NLIMITS 14

/*
* SuS says limits have to be unsigned.
@@ -44,6 +45,7 @@
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ MAX_SIGPENDING, MAX_SIGPENDING }, \
{ MQ_BYTES_MAX, MQ_BYTES_MAX }, \
+ { 0, 0 }, \
}

#endif /* __KERNEL__ */
diff -Nrup linux-2.6.10/include/asm-h8300/resource.h linux-2.6.10-prio/include/asm-h8300/resource.h
--- linux-2.6.10/include/asm-h8300/resource.h 2004-12-24 22:33:50.000000000 +0100
+++ linux-2.6.10-prio/include/asm-h8300/resource.h 2005-01-09 04:20:55.316482343 +0100
@@ -18,8 +18,9 @@
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_PRIO 13 /* maximum scheduling priority */

-#define RLIM_NLIMITS 13
+#define RLIM_NLIMITS 14

/*
* SuS says limits have to be unsigned.
@@ -44,6 +45,7 @@
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ MAX_SIGPENDING, MAX_SIGPENDING }, \
{ MQ_BYTES_MAX, MQ_BYTES_MAX }, \
+ { 0, 0 }, \
}

#endif /* __KERNEL__ */
diff -Nrup linux-2.6.10/include/asm-i386/resource.h linux-2.6.10-prio/include/asm-i386/resource.h
--- linux-2.6.10/include/asm-i386/resource.h 2004-12-24 22:35:50.000000000 +0100
+++ linux-2.6.10-prio/include/asm-i386/resource.h 2005-01-09 02:51:38.550652444 +0100
@@ -18,8 +18,9 @@
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_PRIO 13 /* maximum scheduling priority */

-#define RLIM_NLIMITS 13
+#define RLIM_NLIMITS 14


/*
@@ -45,6 +46,7 @@
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ MAX_SIGPENDING, MAX_SIGPENDING }, \
{ MQ_BYTES_MAX, MQ_BYTES_MAX }, \
+ { 0, 0 }, \
}

#endif /* __KERNEL__ */
diff -Nrup linux-2.6.10/include/asm-ia64/resource.h linux-2.6.10-prio/include/asm-ia64/resource.h
--- linux-2.6.10/include/asm-ia64/resource.h 2004-12-24 22:35:23.000000000 +0100
+++ linux-2.6.10-prio/include/asm-ia64/resource.h 2005-01-09 04:21:40.555000376 +0100
@@ -25,8 +25,9 @@
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_PRIO 13 /* maximum scheduling priority */

-#define RLIM_NLIMITS 13
+#define RLIM_NLIMITS 14

/*
* SuS says limits have to be unsigned.
@@ -51,6 +52,7 @@
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ MAX_SIGPENDING, MAX_SIGPENDING }, \
{ MQ_BYTES_MAX, MQ_BYTES_MAX }, \
+ { 0, 0 }, \
}

# endif /* __KERNEL__ */
diff -Nrup linux-2.6.10/include/asm-m32r/resource.h linux-2.6.10-prio/include/asm-m32r/resource.h
--- linux-2.6.10/include/asm-m32r/resource.h 2004-12-24 22:34:29.000000000 +0100
+++ linux-2.6.10-prio/include/asm-m32r/resource.h 2005-01-09 04:23:12.890842150 +0100
@@ -22,8 +22,9 @@
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_PRIO 13 /* maximum scheduling priority */

-#define RLIM_NLIMITS 13
+#define RLIM_NLIMITS 14

/*
* SuS says limits have to be unsigned.
@@ -48,6 +49,7 @@
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ MAX_SIGPENDING, MAX_SIGPENDING }, \
{ MQ_BYTES_MAX, MQ_BYTES_MAX }, \
+ { 0, 0 }, \
}

#endif /* __KERNEL__ */
diff -Nrup linux-2.6.10/include/asm-m68k/resource.h linux-2.6.10-prio/include/asm-m68k/resource.h
--- linux-2.6.10/include/asm-m68k/resource.h 2004-12-24 22:33:49.000000000 +0100
+++ linux-2.6.10-prio/include/asm-m68k/resource.h 2005-01-09 04:23:23.319806990 +0100
@@ -18,8 +18,9 @@
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_PRIO 13 /* maximum scheduling priority */

-#define RLIM_NLIMITS 13
+#define RLIM_NLIMITS 14

/*
* SuS says limits have to be unsigned.
@@ -44,6 +45,7 @@
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ MAX_SIGPENDING, MAX_SIGPENDING }, \
{ MQ_BYTES_MAX, MQ_BYTES_MAX }, \
+ { 0, 0 }, \
}

#endif /* __KERNEL__ */
diff -Nrup linux-2.6.10/include/asm-mips/resource.h linux-2.6.10-prio/include/asm-mips/resource.h
--- linux-2.6.10/include/asm-mips/resource.h 2004-12-24 22:35:25.000000000 +0100
+++ linux-2.6.10-prio/include/asm-mips/resource.h 2005-01-09 04:24:59.745229422 +0100
@@ -25,8 +25,9 @@
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_PRIO 13 /* maximum scheduling priority */

-#define RLIM_NLIMITS 13 /* Number of limit flavors. */
+#define RLIM_NLIMITS 14 /* Number of limit flavors. */

#ifdef __KERNEL__

@@ -58,6 +59,7 @@
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ MAX_SIGPENDING, MAX_SIGPENDING }, \
{ MQ_BYTES_MAX, MQ_BYTES_MAX }, \
+ { 0, 0 }, \
}

#endif /* __KERNEL__ */
diff -Nrup linux-2.6.10/include/asm-parisc/resource.h linux-2.6.10-prio/include/asm-parisc/resource.h
--- linux-2.6.10/include/asm-parisc/resource.h 2004-12-24 22:35:23.000000000 +0100
+++ linux-2.6.10-prio/include/asm-parisc/resource.h 2005-01-09 04:25:24.322786492 +0100
@@ -18,8 +18,9 @@
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_PRIO 13 /* maximum scheduling priority */

-#define RLIM_NLIMITS 13
+#define RLIM_NLIMITS 14

/*
* SuS says limits have to be unsigned.
@@ -44,6 +45,7 @@
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ MAX_SIGPENDING, MAX_SIGPENDING }, \
{ MQ_BYTES_MAX, MQ_BYTES_MAX }, \
+ { 0, 0 }, \
}

#endif /* __KERNEL__ */
diff -Nrup linux-2.6.10/include/asm-ppc/resource.h linux-2.6.10-prio/include/asm-ppc/resource.h
--- linux-2.6.10/include/asm-ppc/resource.h 2004-12-24 22:34:32.000000000 +0100
+++ linux-2.6.10-prio/include/asm-ppc/resource.h 2005-01-09 04:25:39.139313466 +0100
@@ -14,8 +14,9 @@
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_PRIO 13 /* maximum scheduling priority */

-#define RLIM_NLIMITS 13
+#define RLIM_NLIMITS 14

#ifdef __KERNEL__

@@ -41,6 +42,7 @@
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ MAX_SIGPENDING, MAX_SIGPENDING }, \
{ MQ_BYTES_MAX, MQ_BYTES_MAX }, \
+ { 0, 0 }, \
}

#endif /* __KERNEL__ */
diff -Nrup linux-2.6.10/include/asm-ppc64/resource.h linux-2.6.10-prio/include/asm-ppc64/resource.h
--- linux-2.6.10/include/asm-ppc64/resource.h 2004-12-24 22:35:23.000000000 +0100
+++ linux-2.6.10-prio/include/asm-ppc64/resource.h 2005-01-09 04:25:55.064729944 +0100
@@ -23,8 +23,9 @@
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_PRIO 13 /* maximum scheduling priority */

-#define RLIM_NLIMITS 13
+#define RLIM_NLIMITS 14

#ifdef __KERNEL__

@@ -50,6 +51,7 @@
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ MAX_SIGPENDING, MAX_SIGPENDING }, \
{ MQ_BYTES_MAX, MQ_BYTES_MAX }, \
+ { 0, 0 }, \
}

#endif /* __KERNEL__ */
diff -Nrup linux-2.6.10/include/asm-s390/resource.h linux-2.6.10-prio/include/asm-s390/resource.h
--- linux-2.6.10/include/asm-s390/resource.h 2004-12-24 22:34:30.000000000 +0100
+++ linux-2.6.10-prio/include/asm-s390/resource.h 2005-01-09 04:26:16.528595316 +0100
@@ -26,8 +26,9 @@
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_PRIO 13 /* maximum scheduling priority */

-#define RLIM_NLIMITS 13
+#define RLIM_NLIMITS 14

/*
* SuS says limits have to be unsigned.
@@ -52,6 +53,7 @@
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ MAX_SIGPENDING, MAX_SIGPENDING }, \
{ MQ_BYTES_MAX, MQ_BYTES_MAX }, \
+ { 0, 0 }, \
}

#endif /* __KERNEL__ */
diff -Nrup linux-2.6.10/include/asm-sh/resource.h linux-2.6.10-prio/include/asm-sh/resource.h
--- linux-2.6.10/include/asm-sh/resource.h 2004-12-24 22:35:01.000000000 +0100
+++ linux-2.6.10-prio/include/asm-sh/resource.h 2005-01-09 04:26:36.105647948 +0100
@@ -18,8 +18,9 @@
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_PRIO 13 /* maximum scheduling priority */

-#define RLIM_NLIMITS 13
+#define RLIM_NLIMITS 14

#ifdef __KERNEL__

@@ -44,6 +45,7 @@
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ MAX_SIGPENDING, MAX_SIGPENDING }, \
{ MQ_BYTES_MAX, MQ_BYTES_MAX }, \
+ { 0, 0 }, \
}

#endif /* __KERNEL__ */
diff -Nrup linux-2.6.10/include/asm-sparc/resource.h linux-2.6.10-prio/include/asm-sparc/resource.h
--- linux-2.6.10/include/asm-sparc/resource.h 2004-12-24 22:33:59.000000000 +0100
+++ linux-2.6.10-prio/include/asm-sparc/resource.h 2005-01-09 04:28:51.647156378 +0100
@@ -24,8 +24,9 @@
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_PRIO 13 /* maximum scheduling priority */

-#define RLIM_NLIMITS 13
+#define RLIM_NLIMITS 14

/*
* SuS says limits have to be unsigned.
@@ -49,6 +50,7 @@
{RLIM_INFINITY, RLIM_INFINITY}, \
{MAX_SIGPENDING, MAX_SIGPENDING}, \
{MQ_BYTES_MAX, MQ_BYTES_MAX}, \
+ { 0, 0 }, \
}

#endif /* __KERNEL__ */
diff -Nrup linux-2.6.10/include/asm-sparc64/resource.h linux-2.6.10-prio/include/asm-sparc64/resource.h
--- linux-2.6.10/include/asm-sparc64/resource.h 2004-12-24 22:33:50.000000000 +0100
+++ linux-2.6.10-prio/include/asm-sparc64/resource.h 2005-01-09 04:29:19.272404892 +0100
@@ -24,8 +24,9 @@
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_PRIO 13 /* maximum scheduling priority */

-#define RLIM_NLIMITS 13
+#define RLIM_NLIMITS 14

/*
* SuS says limits have to be unsigned.
@@ -48,6 +49,7 @@
{RLIM_INFINITY, RLIM_INFINITY}, \
{MAX_SIGPENDING, MAX_SIGPENDING}, \
{MQ_BYTES_MAX, MQ_BYTES_MAX}, \
+ { 0, 0 }, \
}

#endif /* __KERNEL__ */
diff -Nrup linux-2.6.10/include/asm-v850/resource.h linux-2.6.10-prio/include/asm-v850/resource.h
--- linux-2.6.10/include/asm-v850/resource.h 2004-12-24 22:33:50.000000000 +0100
+++ linux-2.6.10-prio/include/asm-v850/resource.h 2005-01-09 04:29:53.196025392 +0100
@@ -18,8 +18,9 @@
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_PRIO 13 /* maximum scheduling priority */

-#define RLIM_NLIMITS 13
+#define RLIM_NLIMITS 14

/*
* SuS says limits have to be unsigned.
@@ -44,6 +45,7 @@
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ MAX_SIGPENDING, MAX_SIGPENDING }, \
{ MQ_BYTES_MAX, MQ_BYTES_MAX }, \
+ { 0, 0 }, \
}

#endif /* __KERNEL__ */
diff -Nrup linux-2.6.10/include/asm-x86_64/resource.h linux-2.6.10-prio/include/asm-x86_64/resource.h
--- linux-2.6.10/include/asm-x86_64/resource.h 2004-12-24 22:35:23.000000000 +0100
+++ linux-2.6.10-prio/include/asm-x86_64/resource.h 2005-01-09 04:30:05.892760345 +0100
@@ -18,8 +18,9 @@
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_PRIO 13 /* maximum scheduling priority */

-#define RLIM_NLIMITS 13
+#define RLIM_NLIMITS 14

/*
* SuS says limits have to be unsigned.
@@ -44,6 +45,7 @@
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ MAX_SIGPENDING, MAX_SIGPENDING }, \
{ MQ_BYTES_MAX, MQ_BYTES_MAX }, \
+ { 0, 0 }, \
}

#endif /* __KERNEL__ */



2005-01-09 19:06:48

by Arjan van de Ven

[permalink] [raw]
Subject: Re: [PATCH] scheduling priorities with rlimit

On Sun, 2005-01-09 at 18:15 +0100, utz lehmann wrote:
> Hi
>
> I really like the idea of controlling the maximum settable scheduling
> priorities via rlimit. See the Realtime LSM thread. I want to give users
> the right to raise the priority of previously niced jobs.
>
> I have modified Chris Wright's patch (against 2.6.10):
> (http://marc.theaimsgroup.com/?l=linux-kernel&m=110513793228776&w=2)
>
> - allow always to increase nice levels (lower priority).
> - set the default for RLIMIT_PRIO to 0.
> - add the other architectures.
>
> With this the default is compatible with the old behavior.
>
> With RLIMIT_PRIO > 0 a user is able to raise the priority up to the
> value. 0-39 for nice levels 19 .. -20, 40-139 for realtime priorities
> (0 .. 99).

this is a bit of an awkward interface don't you think?
I much rather have the rlimit match the exact nice values we communicate
to userspace elsewhere, both to be consistent and to not expose
scheduler internals to userpsace.


Also I like the idea of allowing sysadmins to make certain users/groups
nice levels 5 and higher (think a university machine that makes all
students nice 5 and higher only, while giving staff 0 and higher, and
the sysadmin -5 and higher ;)

2005-01-09 19:25:10

by utz lehmann

[permalink] [raw]
Subject: Re: [PATCH] scheduling priorities with rlimit

On Sun, 2005-01-09 at 20:06 +0100, Arjan van de Ven wrote:
> On Sun, 2005-01-09 at 18:15 +0100, utz lehmann wrote:
> > Hi
> >
> > I really like the idea of controlling the maximum settable scheduling
> > priorities via rlimit. See the Realtime LSM thread. I want to give users
> > the right to raise the priority of previously niced jobs.
> >
> > I have modified Chris Wright's patch (against 2.6.10):
> > (http://marc.theaimsgroup.com/?l=linux-kernel&m=110513793228776&w=2)
> >
> > - allow always to increase nice levels (lower priority).
> > - set the default for RLIMIT_PRIO to 0.
> > - add the other architectures.
> >
> > With this the default is compatible with the old behavior.
> >
> > With RLIMIT_PRIO > 0 a user is able to raise the priority up to the
> > value. 0-39 for nice levels 19 .. -20, 40-139 for realtime priorities
> > (0 .. 99).
>
> this is a bit of an awkward interface don't you think?
> I much rather have the rlimit match the exact nice values we communicate
> to userspace elsewhere, both to be consistent and to not expose
> scheduler internals to userpsace.

Yes it is. But rlimits are unsigned .-( (asm/resource.h says this).
I prefer rlimit match nice value too, but how to do this with unsigned.
And what do with the RT prio, different rlimit?
Btw: I saw this on a solaris command too, 0-39 for nice, 40-139 for RT
(dont rememer which).

>
> Also I like the idea of allowing sysadmins to make certain users/groups
> nice levels 5 and higher (think a university machine that makes all
> students nice 5 and higher only, while giving staff 0 and higher, and
> the sysadmin -5 and higher ;)

You can do this already. "priority" item in /etc/security/limits.conf.
But they can only lower the priority.
This patch is for allowing to raise it.


2005-01-09 20:35:15

by Chris Wright

[permalink] [raw]
Subject: Re: [PATCH] scheduling priorities with rlimit

* Arjan van de Ven ([email protected]) wrote:
> On Sun, 2005-01-09 at 18:15 +0100, utz lehmann wrote:
> > Hi
> >
> > I really like the idea of controlling the maximum settable scheduling
> > priorities via rlimit. See the Realtime LSM thread. I want to give users
> > the right to raise the priority of previously niced jobs.
> >
> > I have modified Chris Wright's patch (against 2.6.10):
> > (http://marc.theaimsgroup.com/?l=linux-kernel&m=110513793228776&w=2)
> >
> > - allow always to increase nice levels (lower priority).
> > - set the default for RLIMIT_PRIO to 0.
> > - add the other architectures.
> >
> > With this the default is compatible with the old behavior.
> >
> > With RLIMIT_PRIO > 0 a user is able to raise the priority up to the
> > value. 0-39 for nice levels 19 .. -20, 40-139 for realtime priorities
> > (0 .. 99).
>
> this is a bit of an awkward interface don't you think?

Yes it is. But I didn't think of a better one.

> I much rather have the rlimit match the exact nice values we communicate
> to userspace elsewhere, both to be consistent and to not expose
> scheduler internals to userpsace.

The problem is the numbers are inconsistent between user interfaces already.
RT priorities are [0, 99], nice vaules are [-20, 19]. Perhaps it'd be
simpler to break it down to just three values for the rlimit.

0: Same as now, raise nice value only.
1: Can lower nice value.
2: Can set RT policy (this includes any priority [1, 99], or optionally
max out at something lower than 99, reserving full CAP_SYS_NICE to 99).

Each level inherits the permissions of the lower level, and none of them
allow the CAP_SYS_NICE ability to affect processes other than your own.

> Also I like the idea of allowing sysadmins to make certain users/groups
> nice levels 5 and higher (think a university machine that makes all
> students nice 5 and higher only, while giving staff 0 and higher, and
> the sysadmin -5 and higher ;)

This is a separate issue. It's about setting the default during login
which can be done with setpriority (still could be done via pam).

thanks,
-chris
--
Linux Security Modules http://lsm.immunix.org http://lsm.bkbits.net

2005-01-10 15:16:51

by Horst H. von Brand

[permalink] [raw]
Subject: Re: [PATCH] scheduling priorities with rlimit

Arjan van de Ven <[email protected]> said:

[...]

> Also I like the idea of allowing sysadmins to make certain users/groups
> nice levels 5 and higher (think a university machine that makes all
> students nice 5 and higher only, while giving staff 0 and higher, and
> the sysadmin -5 and higher ;)

AFAIU, this can be done via PAM. No kernel involvment required.
--
Dr. Horst H. von Brand User #22616 counter.li.org
Departamento de Informatica Fono: +56 32 654431
Universidad Tecnica Federico Santa Maria +56 32 654239
Casilla 110-V, Valparaiso, Chile Fax: +56 32 797513

2005-01-10 18:05:14

by utz lehmann

[permalink] [raw]
Subject: Re: [PATCH] scheduling priorities with rlimit

On Sun, 2005-01-09 at 12:34 -0800, Chris Wright wrote:
> * Arjan van de Ven ([email protected]) wrote:

> > I much rather have the rlimit match the exact nice values we communicate
> > to userspace elsewhere, both to be consistent and to not expose
> > scheduler internals to userpsace.
>
> The problem is the numbers are inconsistent between user interfaces already.
> RT priorities are [0, 99], nice vaules are [-20, 19]. Perhaps it'd be
> simpler to break it down to just three values for the rlimit.
>
> 0: Same as now, raise nice value only.
> 1: Can lower nice value.
> 2: Can set RT policy (this includes any priority [1, 99], or optionally
> max out at something lower than 99, reserving full CAP_SYS_NICE to 99).
>
> Each level inherits the permissions of the lower level, and none of them
> allow the CAP_SYS_NICE ability to affect processes other than your own.

I dont like this. I dont what to give user the ability to renice there
jobs to -20. I need numeric limits.

But i think it's mainly a problem of userspace to present userfriendly
values. There are already conversions of rlimit values in pam_limits and
ulimit.

What about this. Separate the rlimit in RLIMIT_NICE and LIMIT_RT.
Putting both into one value is not a good idea, confusing and error
prone. Setting (by fault) RLIMIT_NICE to unlimited is not so risky as
doing it for the old RLIMIT_PRIO.

RLIMIT_RT has the same values like RT priorities 0-99
For RLIMIT_NICE is not possible because the negative nice levels.
Using 0-39 for the nice levels 19 .. -20. It has the advantage that has
the same meaning like the other rlimits, greater value means more
resources.

With a patched PAM you can simply do this in /etc/security/limits.conf

@student hard nice 5
@stuff hard nice 0
@stuff soft nice 5
@admin hard nice -10
@admin soft nice -10

@admin hard realtime 10
@admin soft realtime 10

The nice values are converted by pam_limits to 0-39.


diff -Nrup linux-2.6.10/include/linux/sched.h linux-2.6.10-prio4/include/linux/sched.h
--- linux-2.6.10/include/linux/sched.h 2004-12-24 22:33:59.000000000 +0100
+++ linux-2.6.10-prio4/include/linux/sched.h 2005-01-10 17:28:51.699861886 +0100
@@ -738,6 +738,7 @@ extern void sched_idle_next(void);
extern void set_user_nice(task_t *p, long nice);
extern int task_prio(const task_t *p);
extern int task_nice(const task_t *p);
+extern unsigned long nice_to_rlimit_nice(const int nice);
extern int task_curr(const task_t *p);
extern int idle_cpu(int cpu);

diff -Nrup linux-2.6.10/kernel/sched.c linux-2.6.10-prio4/kernel/sched.c
--- linux-2.6.10/kernel/sched.c 2004-12-24 22:35:24.000000000 +0100
+++ linux-2.6.10-prio4/kernel/sched.c 2005-01-10 17:25:28.079188450 +0100
@@ -73,6 +73,12 @@
#define MAX_USER_PRIO (USER_PRIO(MAX_PRIO))

/*
+ * convert nice to RLIMIT_NICE values ([ 19 ... -20 ] to [ 0 ... 39 ])
+ */
+
+#define NICE_TO_RLIMIT_NICE(nice) (19 - nice)
+
+/*
* Some helpers for converting nanosecond timing to jiffy resolution
*/
#define NS_TO_JIFFIES(TIME) ((TIME) / (1000000000 / HZ))
@@ -3008,12 +3014,8 @@ asmlinkage long sys_nice(int increment)
* We don't have to worry. Conceptually one call occurs first
* and we have a single winner.
*/
- if (increment < 0) {
- if (!capable(CAP_SYS_NICE))
- return -EPERM;
- if (increment < -40)
- increment = -40;
- }
+ if (increment < -40)
+ increment = -40;
if (increment > 40)
increment = 40;

@@ -3023,6 +3025,12 @@ asmlinkage long sys_nice(int increment)
if (nice > 19)
nice = 19;

+ if (increment < 0 &&
+ NICE_TO_RLIMIT_NICE(nice) >
+ current->signal->rlim[RLIMIT_NICE].rlim_cur &&
+ !capable(CAP_SYS_NICE))
+ return -EPERM;
+
retval = security_task_setnice(current, nice);
if (retval)
return retval;
@@ -3056,6 +3064,15 @@ int task_nice(const task_t *p)
}

/**
+ * nice_to_rlimit_nice - return rlimit_nice priority of give nice value
+ * @nice: nice value
+ */
+unsigned long nice_to_rlimit_nice(const int nice)
+{
+ return NICE_TO_RLIMIT_NICE(nice);
+}
+
+/**
* idle_cpu - is a given cpu idle currently?
* @cpu: the processor in question.
*/
@@ -3139,6 +3156,7 @@ recheck:

retval = -EPERM;
if ((policy == SCHED_FIFO || policy == SCHED_RR) &&
+ lp.sched_priority > p->signal->rlim[RLIMIT_RT].rlim_cur &&
!capable(CAP_SYS_NICE))
goto out_unlock;
if ((current->euid != p->euid) && (current->euid != p->uid) &&
diff -Nrup linux-2.6.10/kernel/sys.c linux-2.6.10-prio4/kernel/sys.c
--- linux-2.6.10/kernel/sys.c 2004-12-24 22:33:59.000000000 +0100
+++ linux-2.6.10-prio4/kernel/sys.c 2005-01-10 17:29:50.378989385 +0100
@@ -224,7 +224,10 @@ static int set_one_prio(struct task_stru
error = -EPERM;
goto out;
}
- if (niceval < task_nice(p) && !capable(CAP_SYS_NICE)) {
+ if (niceval < task_nice(p) &&
+ nice_to_rlimit_nice(niceval) >
+ p->signal->rlim[RLIMIT_NICE].rlim_cur &&
+ !capable(CAP_SYS_NICE)) {
error = -EACCES;
goto out;
}
diff -Nrup linux-2.6.10/include/asm-i386/resource.h linux-2.6.10-prio4/include/asm-i386/resource.h
--- linux-2.6.10/include/asm-i386/resource.h 2004-12-24 22:35:50.000000000 +0100
+++ linux-2.6.10-prio4/include/asm-i386/resource.h 2005-01-10 16:55:43.480164770 +0100
@@ -18,8 +18,11 @@
#define RLIMIT_LOCKS 10 /* maximum file locks held */
#define RLIMIT_SIGPENDING 11 /* max number of pending signals */
#define RLIMIT_MSGQUEUE 12 /* maximum bytes in POSIX mqueues */
+#define RLIMIT_NICE 13 /* max nice prio allowed to raise to
+ 0-39 for nice level 19 .. -20 */
+#define RLIMIT_RT 14 /* maximum realtime priority */

-#define RLIM_NLIMITS 13
+#define RLIM_NLIMITS 15


/*
@@ -45,6 +48,8 @@
{ RLIM_INFINITY, RLIM_INFINITY }, \
{ MAX_SIGPENDING, MAX_SIGPENDING }, \
{ MQ_BYTES_MAX, MQ_BYTES_MAX }, \
+ { 0, 0 }, \
+ { 0, 0 }, \
}

#endif /* __KERNEL__ */