Search code examples
linuxheader-filesschedulingcpu-usagescheduler

Where could I find the code of "sched_getcpu()"


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.


Solution

  • 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;
    }