Relationships among nice, priority and weight in Linux kernel
nice value
On Linux, the nice value ranges from -20 to 19.
nice and weight
In the Linux’s Completely Fair Scheduler (CFS), mapping of nice to weight of a process is critical to calculating the virtual runtime (vruntime) of its scheduler entity structure (struct sched_entity). In Linux 2.6.34, this is defined in prio_to_weight (kernel/sched.c#L1356). The weight is roughly equivalent to 1024/(1.25)^(nice):
static const int prio_to_weight[40] = {
/* -20 */ 88761, 71755, 56483, 46273, 36291,
/* -15 */ 29154, 23254, 18705, 14949, 11916,
/* -10 */ 9548, 7620, 6100, 4904, 3906,
/* -5 */ 3121, 2501, 1991, 1586, 1277,
/* 0 */ 1024, 820, 655, 526, 423,
/* 5 */ 335, 272, 215, 172, 137,
/* 10 */ 110, 87, 70, 56, 45,
/* 15 */ 36, 29, 23, 18, 15,
};
nice and priority
The conversion between nice and static priority (priority for SCHED_NORMAL, or non-“real-time” tasks) is defined by the NICE_TO_PRIO and PRIO_TO_NICE macros. Before Linux 3.15, for example, 2.6.34, this is defined in kernel/sched.c; since Linux 3.15, it is defined in include/linux/sched/prio.h. The relation is literally prio = nice + 120, so the priority ranges from 100 to 139.
The following is the macro definition from the 2.6.34 source code
#define NICE_TO_PRIO(nice) (MAX_RT_PRIO + (nice) + 20)
#define PRIO_TO_NICE(prio) ((prio) - MAX_RT_PRIO - 20)
nice value and rlimit style value
In the recent man page on setpriority(2), there is a formula unice = 20 - knice that converts “user” nice values (-20..19) to “kernel” nice values (40..1), which is said to be handled by glibc wrapper functions for setpriority() and getpriority() system calls. This seems vague in definition.
Since Linux 3.16, a new nice_to_rlimit function is added to include/linux/sched/prio.h, which seems to match the above description. This function converts nice value [19,-20] to rlimit style value [1,40]. The formula is equivalent to that on the man page. The rlimit_to_nice does the reverse operation.
static inline long nice_to_rlimit(long nice)
{
return (MAX_NICE - nice + 1);
}
Here, MAX_NICE is defined to be 19, so it is essentially rlimit = 20 - nice.
Note that the rlimit style value is not to be confused with “user priority” (include/linux/sched/prio.h#L40), which has a range of 0 to 39.