1

Recently I'm using the function sched_getcpu() from the header file sched.h on Linux.

However, I'm wondering where could I find the source code of this function?

Thanks.

S.Wan
  • 396
  • 3
  • 18

1 Answers1

5

Under Linux, the sched_getcpu() function is a glibc wrapper to sys_getcpu() system call, which is architecture specific.

For the x86_64 architecture, it is defined under arch/x86/include/asm/vgtod.h as __getcpu() (tree 4.x):

#ifdef CONFIG_X86_64

#define VGETCPU_CPU_MASK 0xfff

static inline unsigned int __getcpu(void)
{
        unsigned int p;

        /*
         * Load per CPU data from GDT.  LSL is faster than RDTSCP and
         * works on all CPUs.  This is volatile so that it orders
         * correctly wrt barrier() and to keep gcc from cleverly
         * hoisting it out of the calling function.
         */
        asm volatile ("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG));

        return p;
}

#endif /* CONFIG_X86_64 */

Being this function called by __vdso_getcpu() declared in arch/entry/vdso/vgetcpu.c:

notrace long
__vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused)
{
        unsigned int p;

        p = __getcpu();

        if (cpu)
                *cpu = p & VGETCPU_CPU_MASK;
        if (node)
                *node = p >> 12;
        return 0;
}

(See vDSO for details regarding what vdso prefix is).

EDIT 1: (in reply to arm code location)

ARM code location

It can be found in the arch/arm/include/asm/thread_info.h file:

static inline struct thread_info *current_thread_info(void)
{
        return (struct thread_info *)
                (current_stack_pointer & ~(THREAD_SIZE - 1));
}

This function is used by raw_smp_processor_id() that is defined in the file arch/arm/include/asm/smp.h as:

#define raw_smp_processor_id() (current_thread_info()->cpu)

And it's called by getcpu system call declared in the file kernel/sys.c:

SYSCALL_DEFINE3(getcpu, unsigned __user *, cpup, unsigned __user *, nodep, struct getcpu_cache __user *, unused)
{
        int err = 0;
        int cpu = raw_smp_processor_id();

        if (cpup)
                err |= put_user(cpu, cpup);
        if (nodep)
                err |= put_user(cpu_to_node(cpu), nodep);
        return err ? -EFAULT : 0;
}
pah
  • 4,700
  • 6
  • 28
  • 37
  • Thank you for the replying. Actually I'm working on ARM arch. I just searched the folder arch/arm64 and I only got a file named 'unistd32.h' which included the sys_getcpu. However, there is still no details like your x86 example. Do you have any idea about where is this function of ARM? Thank you again for replying and hope you have a great weekend! – S.Wan Aug 07 '16 at 20:22
  • @S.Wan Now complete and accurate. Let me know if you need further details. – pah Aug 07 '16 at 23:56
  • that's a very detailed answer for me. However, I have another related question about the getcpu. Now I want to deploy a function like sched_getcpu but I don't want to use the system call or include the header file like 'sched.h', is there any way to achieve this? I know for x86 there is an instruction called 'CPUID' but I'm new to the ARM part, thank you! – S.Wan Aug 09 '16 at 17:34
  • You can reuse the code from `current_thread_info()` / `raw_smp_processor_id()`. – pah Aug 09 '16 at 18:00