Linux - Difference between migrations and switches?
Migration is when a thread, usually after a context switch, get scheduled on a different CPU than it was scheduled before.
EDIT 1:
Here is more info on Wikipedia about the migration: https://en.wikipedia.org/wiki/Process_migration
Here is the kernel code increasing the counter:https://github.com/torvalds/linux/blob/master/kernel/sched/core.c#L1175
if (task_cpu(p) != new_cpu) { ... p->se.nr_migrations++;
EDIT 2:
A thread can migrate to another CPU in the following cases:
- During
exec()
- During
fork()
- During thread wake-up.
- If thread affinity mask has changed.
- When the current CPU is getting offline.
For more info please have a look at functions set_task_cpu()
, move_queued_task()
, migrate_tasks()
in the same source file: https://github.com/torvalds/linux/blob/master/kernel/sched/core.c
The policies scheduler follows are described in select_task_rq()
, which depend on the class of scheduler you are using. The basic version of the policier:
if (p->nr_cpus_allowed > 1) cpu = p->sched_class->select_task_rq(p, cpu, sd_flags, wake_flags);else cpu = cpumask_any(&p->cpus_allowed);
Source: https://github.com/torvalds/linux/blob/master/kernel/sched/core.c#L1534
So in order to avoid the migration, set the CPU affinity mask for your threads using sched_setaffinity(2)
system call or corresponding POSIX API pthread_setaffinity_np(3)
.
Here is the definition of select_task_rq() for the Completely Fair Scheduler:https://github.com/torvalds/linux/blob/master/kernel/sched/fair.c#L5860
The logic is quite complicated, but basically, we either select sibling idle CPU or find a least busy new one.
Hope this answers your question.