Multiple CPUs - what to share
Posted: Mon Oct 21, 2024 9:39 am
I'm looking at how best to handle multiple x86 CPUs (or CPU cores, if you prefer) on a single machine, and the question arises: what should be shared between all the cores and what should be per-core? Advice would be welcome!
At one extreme I could have every CPU use the same sets of page tables, the same GDT, process table, etc. At the other extreme each CPU could have its own sets of page tables, its own GDT, its own processes etc (almost as though they were separate machines) with inter-CPU communications being used to balance resources between them.
Or there could be a compromise such as having some address space shared and some exclusive to each CPU. For example, each CPU could have its own high 4M, say, and share the rest. In that scenario, assuming a 32-bit 4G environment for the sake of simplicity, each PDBR would have its highest entry refer to an exclusive 4k page table and the rest point to nearly 4M of shared page tables.
I'm not at the point of handling multiple CPUs yet but I've been including code such as
if (this_cpu() == 0) /* boot CPU */
and
tasks = this_cpu_workspace()->tasks
where each such function call returns either the current CPU number or a pointer to a struct which has data for the current CPU - i.e. the one which is running the code. So such questions are relevant as to how it's best to proceed to handle such structures as the GDT (or GDTs). Even more so about IDT handling.
Hence, what do you share or intend to share? What kind of approach looks best to you? As I say, comments would be welcomed!
At one extreme I could have every CPU use the same sets of page tables, the same GDT, process table, etc. At the other extreme each CPU could have its own sets of page tables, its own GDT, its own processes etc (almost as though they were separate machines) with inter-CPU communications being used to balance resources between them.
Or there could be a compromise such as having some address space shared and some exclusive to each CPU. For example, each CPU could have its own high 4M, say, and share the rest. In that scenario, assuming a 32-bit 4G environment for the sake of simplicity, each PDBR would have its highest entry refer to an exclusive 4k page table and the rest point to nearly 4M of shared page tables.
I'm not at the point of handling multiple CPUs yet but I've been including code such as
if (this_cpu() == 0) /* boot CPU */
and
tasks = this_cpu_workspace()->tasks
where each such function call returns either the current CPU number or a pointer to a struct which has data for the current CPU - i.e. the one which is running the code. So such questions are relevant as to how it's best to proceed to handle such structures as the GDT (or GDTs). Even more so about IDT handling.
Hence, what do you share or intend to share? What kind of approach looks best to you? As I say, comments would be welcomed!