Calculate the number of kernel threads spawned per CPU core for common kernel subsystems.
kthreadd (PID 2) is the kernel's thread spawner — every kernel thread (kworker pools, migration/N, ksoftirqd/N, rcu_sched, writeback workers, etc.) is a descendant of it, visible via `ps --ppid 2` or `ps -ef | grep '\[.*\]'` (kernel threads are shown in square brackets). Many kernel thread types are per-CPU (one instance per core, like ksoftirqd/N and migration/N), so total kernel thread count scales with core count for that subset, plus a smaller set of global (single-instance) threads that don't multiply per core.
Expected thread count
expected_total = per_cpu_thread_types × cores + global_threads
`ps --ppid 2 -o pid,comm` lists direct kthreadd children (kernel threads shown in brackets), while `ps -ef | awk '$3==2'` gives a similar view; `ps -eLf | wc -l` includes all threads (kernel + userspace) for a total system thread count.
Since Linux 4.10+, unbound kworker pools are created and destroyed dynamically based on workqueue demand (replacing the older fixed-per-CPU model), so the exact kworker/N:M count you observe varies with recent I/O and workqueue activity rather than being a fixed number tied only to core count.
Kernel threads share the kernel's address space (no separate page tables) and never execute user-mode code, so they're lighter weight than typical user processes, but they still consume a task_struct, a kernel stack, and appear in scheduler accounting exactly like any other schedulable task.