Stage 3 · Build
Users, Permissions & Processes
Process Priority
nice, renice, ionice, CPU scheduling classes, and identifying priority inversions.
Nice Values
Nice values control CPU scheduling priority. Lower nice values mean higher priority. The range is -20 (highest priority) to 19 (lowest priority). Default is 0.
# Check nice value of a process
ps -eo pid,ni,comm --sort=-ni | head -10
# PID NI COMMAND
# 12345 -5 sshd
# 12346 19 bash
# 12347 0 nginx
# Check nice value with ps
ps -p 12345 -o pid,ni,comm
# PID NI COMMAND
# 12345 -5 sshd
# Check scheduling priority
ps -eo pid,cls,rtprio,ni,comm | head -10
# PID CLS RTPRIO NI COMMAND
# 12345 TS - 0 sshd
# 12346 RR 50 -5 nginx
# 12347 TS - 19 batch_jobnice values affect CFS (Completely Fair Scheduler). Lower nice values get more CPU time. RT (real-time) processes have even higher priority.
Changing Priority
# Start a process with lower priority
nice -n 10 ./heavy_computation.sh
# Runs with nice value 10 (lower priority)
# Start with higher priority (requires root)
sudo nice -n -5 ./important_task.sh
# Change priority of running process
renice -n 10 -p 12345
# Set PID 12345 to nice value 10
# Change priority to highest (requires root)
sudo renice -n -20 -p 12345
# Change priority of all processes in a group
sudo renice -n 5 -g mygroup
# Change priority by name
renice -n 10 -p $(pgrep nginx)
# Check the result
ps -p 12345 -o pid,ni,comm
# PID NI COMMAND
# 12345 10 nginxnice lowers priority, renice changes it. Only root can increase priority (negative nice values). Regular users can only decrease priority.
I/O Priority
# Check I/O priority
ionice -p 12345
# best-effort: pid 12345, class 2, prio 4
# Classes:
# 0 = none (use best-effort)
# 1 = real-time (highest I/O priority)
# 2 = best-effort (normal scheduling)
# 3 = idle (only when no other I/O)
# Set I/O priority
ionice -c 3 ./backup.sh # Idle I/O priority
ionice -c 2 -n 0 ./critical # Best-effort, highest priority
ionice -c 1 ./emergency # Real-time I/O priority
# Check I/O priority of all processes
ionice -p $(pgrep -f ".sh") 2>/dev/null | head -10I/O priority controls disk access scheduling. Use idle (class 3) for background tasks and best-effort for normal workloads.
CPU Scheduling Classes
| Class | Range | Description |
|---|---|---|
| SCHED_OTHER (TS) | Nice -20 to 19 | Default CFS scheduling |
| SCHED_BATCH | Nice -20 to 19 | Optimized for batch workloads |
| SCHED_IDLE | Nice 19 | Very low priority |
| SCHED_FIFO | RT 1-99 | Real-time FIFO |
| SCHED_RR | RT 1-99 | Real-time round-robin |
# Set real-time priority (requires root)
sudo chrt -f 50 ./realtime_task.sh
# FIFO, priority 50
# Set batch scheduling
sudo chrt -b 0 ./batch_job.sh
# Check scheduling policy
chrt -p 12345
# pid 12345's current scheduling policy: SCHED_OTHER
# pid 12345's current scheduling priority: 0
# List all real-time processes
ps -eo pid,cls,rtprio,comm | grep -E "FF|RR"
# 12345 FF 50 nginx
# 12346 RR 50 nginxReal-time scheduling (SCHED_FIFO, SCHED_RR) preempts all CFS processes. Use it only for truly time-critical tasks.
Priority Inversion
Priority inversion occurs when a high-priority process waits for a low-priority process that holds a shared resource. The low-priority process may be preempted by medium-priority processes, causing the high-priority process to wait indefinitely.
# Check for high-priority processes blocked on locks
sudo perf record -g -a sleep 5
sudo perf report
# Look for futex calls in stack traces
sudo bpftrace -e 'kprobe:futex_wait_queue { @[comm, pid] = count(); }'
# Check for processes stuck in D state (disk sleep)
ps -eo pid,stat,ni,comm | grep " D "
# High-priority processes stuck in D state may indicate inversion
# Priority inheritance (PI) mutexes
# Linux kernel uses PI futexes to prevent inversion
# Check with:
cat /proc/sys/kernel/sched_rt_runtime_us
# 950000 (95% of CPU for RT processes)Priority inversion is a classic real-time systems problem. Linux uses priority inheritance futexes to mitigate it for mutex-protected critical sections.
Real-World Tuning
# Lower priority for batch jobs
nice -n 10 tar czf backup.tar.gz /data
# Lower I/O priority for backups
ionice -c 3 -n 7 rsync -av /data/ /backup/
# Higher priority for interactive services
sudo renice -n -5 -p $(pgrep sshd)
# Higher I/O priority for databases
sudo ionice -c 1 -p $(pgrep postgres)
# Background tasks at lowest priority
nice -n 19 ionice -c 3 ./maintenance.sh &
# Check if tuning worked
ps -eo pid,ni,cls,rtprio,comm | grep nginxCombine nice and ionice for comprehensive priority control. nice affects CPU, ionice affects disk I/O.
Always run batch jobs (backups, compression, analytics) with nice -n 10 or higher to avoid starving interactive services.
SCHED_FIFO processes preempt all CFS processes. A runaway real-time process can freeze the system. Limit RT processes with /proc/sys/kernel/sched_rt_runtime_us.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.