Hi,
ggodw000 wrote:if you are running a kernel with multiple processes running on MP systems, is there a way to know which CPU socket/core/thread the current process is running?
First, a multi-threaded process may be running on multiple CPUs at the same time.
Second; typically (for OSs that support pre-emption) due to race conditions you can only know which CPU you were running on (which may be different to which CPU you are currently running on). For a simple example, you can use the RDTSCP instruction (in user-space) to get the "CPU ID" set by the kernel, but immediately after you've executed this instruction the OS can do a task switch and the next instruction might be using a different CPU - the "which CPU" information can be stale/obsolete before you can use it for anything.
It's only possible if something prevents the "running on a different CPU" problem. In kernel-space this is likely easy to do temporarily (just disable task switches). For user-space (and kernel, for longer periods of time) kernel can support "CPU affinity" (e.g. a flag for each CPU saying if the thread is/isn't allowed to use the CPU) that user-space can change, so user-space code can get the CPU it was running on, set the CPU affinity to that CPU, and then know that it is running on that CPU from that point on. Of course if kernel does support "CPU affinity" (either per thread, or per process) it should be easy to determine the set of CPUs that a process (or thread) might use.
Fortunately; for user-space there's very few reasons to actually care which CPU you're using that doesn't require CPU affinity anyway. For example, if one CPU supports a feature and another CPU doesn't then you can't do "If running on CPU that supports feature, use code that uses feature, else use alternative code that doesn't use the feature", and you'd have to use CPU affinity to ensure you're only ever run on the CPUs that support the feature.
For kernel space; most OS's have some form of "per CPU data" (e.g. using a segment register like FS or GS to point to the "per CPU data" for the current CPU, or using paging). In this case kernel code can use "per CPU data" without caring which CPU it is. For example, maybe you can do "mov eax,[gs:CPUdata.CPUload]" to get the current CPU's load. You can also store a "CPU ID" in the "per CPU data".
For the other part of your question (determining socket/core/thread from the "CPU ID"), there's a
"Detecting CPU Topology" wiki page. This information can be put into each CPU's "per CPU data" too; so that (e.g.) kernel can do "mov eax,[gs:CPUdata.CPUsocket]" to determine which socket (or which core within the socket, or which logical CPU/thread within the core).
Cheers,
Brendan