I am now studying about the scheduler of Linux. Regarding CPU core affinity, I would like to know the following:
1) How is each process(thread) pinned to a core?
there is a system call sched_setaffinity
to change the core affinity on which a process is executed. But internally, when a process(or a thread) is generated, how does the default Linux scheduler assign the process(thread) to a specific core? I modified sched_setaffinity
system call to dump information about the task being moved from one core to another.
printk(KERN_INFO "%d %d %ld %lu %s\n", current->pid, current->tgid,
current->state, current->cpus_allowed,
current->comm);
It seems that there is no dump of the above information in /var/log/messages
. So the default scheduler pins each process in a different way, but I cannot figure out how.
2) Is it possible to get core ID by PID or other information?
This is what I want to implement inside of Linux kernel. In task_struct
, there is a member called cpus_allowed
. But this is a mask for setting affinity, not core ID. I want to retrieve a data identifying the core on which specified process is running.
Thanks,
Using taskset , you can pin (or assign) a running process to particular CPU core(s). For that, use the following command. For example, to assign a process to CPU core 0 and 4, do the following. With -c option, you can specify a list of numeric CPU core IDs separated by commas, or even include ranges (e.g., 0,2,5,6-10).
As per Wikipedia, Processor affinity, or CPU pinning or “cache affinity”, enables the binding and unbinding of a process or a thread to a central processing unit (CPU) or a range of CPUs, so that the process or thread will execute only on the designated CPU or CPUs rather than any CPU.
Pinning a process (group) to a CPU can improve performance by e.g., reducing CPU cache misses, or to ensure resources are used fairly, or to prevent a group of processes from interfering with other jobs.
Each CPU has its own runqueue, AFAIK we can find out current CPU of a process by looking for which runqueue it belongs to. Given task_struct *p
, we can get its runqueue by struct rq = task_rq(p)
, and struct rq has a field named cpu, I guess this should be the answer.
I have not tried this in practice, just read some code online, and am not quite sure it it will work or not. Wish it could help you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With