/*
* Called from the timer interrupt handler to charge one tick to the current
* process. user_tick is 1 if the tick is user time, 0 for system.
*/voidupdate_process_times(int user_tick){structtask_struct*p = current;/* Note: this timer irq context must be accounted for as well. */account_process_tick(p, user_tick);// 统计单词tick的cpu时间run_local_timers();rcu_check_callbacks(user_tick);#ifdefCONFIG_IRQ_WORKif(in_irq())irq_work_tick();#endifscheduler_tick();if(IS_ENABLED(CONFIG_POSIX_TIMERS))run_posix_cpu_timers(p);}
统计单次cpu的单次时钟时间
1. account_user_time()
/*
* Account a single tick of CPU time.
* @p: the process that the CPU time gets accounted to
* @user_tick: indicates if the tick is a user or a system tick
*/voidaccount_process_tick(structtask_struct*p,int user_tick){
u64 cputime, steal;structrq*rq =this_rq();/*
* Checks if vtime is enabled on some CPU. Cputime readers want to be careful
* in that case and compute the tickless cputime.
* For now vtime state is tied to context tracking. We might want to decouple
* those later if necessary.
*/if(vtime_accounting_cpu_enabled())return;if(sched_clock_irqtime){irqtime_account_process_tick(p, user_tick, rq,1);return;}
cputime = TICK_NSEC;
steal =steal_account_process_time(ULONG_MAX);//guest用户(虚拟机)在计算自己运行时间时减去自己实际未抢到物理cpu的时间,用在虚拟机上;if(steal >= cputime)return;
cputime -= steal;if(user_tick)account_user_time(p, cputime);elseif((p != rq->idle)||(irq_count()!= HARDIRQ_OFFSET))account_system_time(p, HARDIRQ_OFFSET, cputime);elseaccount_idle_time(cputime);}/*
* Account user CPU time to a process.
* @p: the process that the CPU time gets accounted to
* @cputime: the CPU time spent in user space since the last update
*/voidaccount_user_time(structtask_struct*p, u64 cputime){int index;/* Add user time to process. */
p->utime += cputime;account_group_user_time(p, cputime);//增加cgroup的运行时间 struct thread_group_cputimer* cputimer = &tsk->signal->cputimer
index =(task_nice(p)>0)? CPUTIME_NICE : CPUTIME_USER;/* Add user time to cpustat. */task_group_account_field(p, index, cputime);/* Account for user time used */acct_account_cputime(p);}
Linux周期性cpu调度触发时机update_process_timers统计单次cpu的单次时钟时间结构体链接链接触发时机1. tick_handle_periodic为每个clock_event_device的中断处理函数,在每次时钟中断时会进行调用;2. 调用链为:tick_handle_periodic->tick_periodic->update_process_times->scheduler_tickupdate_process_timers/* * Cal