Reputation: 2735
I spent a lot of time figuring out the function in the code level and I really got confused now.
First in the core.c, the function __schedule()
or schedule()
seem to be the most promising ones. Typically in __schedule()
, I have found the code hrtick_clear(rq)
which seems to be a timer. Then also in __schedule()
, the function next = pick_next_task(rq)
will be called which will try to find the next task to schedule. For the normal task, the CFS algorithm is used. So then I went into the fair.c file to check the pick_next_task_fair function. By tracking that function, I have seen the hrtick_start(rq, delta)
has been called.
So obviously it seems that there is a timer based on hrtick is used to periodically activate the scheduling algorithm. But the strange thing is that in the core.c file, I really can not find how the timer is configured to call the __schedule()
or schedule()
periodically. I didn't see that timer is configured to call this function.
Is there other function used? Can linux task scheduler expert give me a hint:>
Upvotes: 0
Views: 2089
Reputation: 189
There are actually two schedulers, or rather two scheduling codes in the Linux kernel. There is a core scheduler, which you yourself mentioned called schedule() which calls __schedule(). schedule() is called from many points in the kernel, like after system calls etc.
There is another scheduler code with the name scheduler_tick()[this too resides in core.c], which is a periodic scheduler and is called by the timer code(timer.c) via interrupt with a frequency of HZ, i.e. scheduler_tick() is called HZ times in one second. HZ is hardware dependent and its value varies between 100-1024. scheduler_tick() calls the task_tick() of the scheduling class to which the current task on the processor belongs.
Upvotes: 1
Reputation: 182743
Nothing special is needed. The timer just triggers an interrupt, and the interrupt logic already has to handle figuring out which task to run when you return from an interrupt. See, for example this code from entry_32.S which handles returning from an interrupt:
358 ENTRY(resume_userspace)
359 LOCKDEP_SYS_EXIT
360 DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
361 # setting need_resched or sigpending
362 # between sampling and the iret
363 TRACE_IRQS_OFF
364 movl TI_flags(%ebp), %ecx
365 andl $_TIF_WORK_MASK, %ecx # is there any work to be done on
366 # int/exception return?
367 jne work_pending
368 jmp restore_all
369 END(ret_from_exception)
...
615 work_pending:
616 testb $_TIF_NEED_RESCHED, %cl
617 jz work_notifysig
618 work_resched:
619 call schedule
Upvotes: 4