/* * Account a tick to a process and cpustat * @p: the process that the cpu time gets accounted to * @user_tick: is the tick from userspace * @rq: the pointer to rq * * Tick demultiplexing follows the order * - pending hardirq update * - pending softirq update * - user_time * - idle_time * - system time * - check for guest_time * - else account as system_time * * Check for hardirq is done both for system and user time as there is * no timer going off while we are on hardirq and hence we may never get an * opportunity to update it solely in system time. * p->stime and friends are only updated on system time and not on irq * softirq as those do not count in task exec_runtime any more. */ static void irqtime_account_process_tick(struct task_struct *p, int user_tick, struct rq *rq) { cputime_t one_jiffy_scaled = cputime_to_scaled(cputime_one_jiffy); u64 *cpustat = kcpustat_this_cpu->cpustat; if (steal_account_process_tick()) return; if (irqtime_account_hi_update()) { cpustat[CPUTIME_IRQ] += (__force u64) cputime_one_jiffy; } else if (irqtime_account_si_update()) { cpustat[CPUTIME_SOFTIRQ] += (__force u64) cputime_one_jiffy; } else if (this_cpu_ksoftirqd() == p) { /* * ksoftirqd time do not get accounted in cpu_softirq_time. * So, we have to handle it separately here. * Also, p->stime needs to be updated for ksoftirqd. */ __account_system_time(p, cputime_one_jiffy, one_jiffy_scaled, CPUTIME_SOFTIRQ); } else if (user_tick) { account_user_time(p, cputime_one_jiffy, one_jiffy_scaled); } else if (p == rq->idle) { account_idle_time(cputime_one_jiffy); } else if (p->flags & PF_VCPU) { /* System time or guest time */ account_guest_time(p, cputime_one_jiffy, one_jiffy_scaled); } else { __account_system_time(p, cputime_one_jiffy, one_jiffy_scaled, CPUTIME_SYSTEM); } }
void enabled_wait(void) { struct s390_idle_data *idle = this_cpu_ptr(&s390_idle); unsigned long long idle_time; unsigned long psw_mask; trace_hardirqs_on(); /* Wait for external, I/O or machine check interrupt. */ psw_mask = PSW_KERNEL_BITS | PSW_MASK_WAIT | PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; clear_cpu_flag(CIF_NOHZ_DELAY); /* Call the assembler magic in entry.S */ psw_idle(idle, psw_mask); trace_hardirqs_off(); /* Account time spent with enabled wait psw loaded as idle time. */ write_seqcount_begin(&idle->seqcount); idle_time = idle->clock_idle_exit - idle->clock_idle_enter; idle->clock_idle_enter = idle->clock_idle_exit = 0ULL; idle->idle_time += idle_time; idle->idle_count++; account_idle_time(idle_time); write_seqcount_end(&idle->seqcount); }
/* * Account multiple ticks of idle time. * @ticks: number of stolen ticks */ void account_idle_ticks(unsigned long ticks) { if (sched_clock_irqtime) { irqtime_account_idle_ticks(ticks); return; } account_idle_time(jiffies_to_cputime(ticks)); }
/* * 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 */ void account_process_tick(struct task_struct *p, int user_tick) { cputime_t one_jiffy_scaled = cputime_to_scaled(cputime_one_jiffy); struct rq *rq = this_rq(); if (sched_clock_irqtime) { irqtime_account_process_tick(p, user_tick, rq); return; } if (steal_account_process_tick()) return; if (user_tick) account_user_time(p, cputime_one_jiffy, one_jiffy_scaled); else if ((p != rq->idle) || (irq_count() != HARDIRQ_OFFSET)) account_system_time(p, HARDIRQ_OFFSET, cputime_one_jiffy, one_jiffy_scaled); else account_idle_time(cputime_one_jiffy); }
/* * Account time for a transition between system, hard irq or soft irq state. * Note that this function is called with interrupts enabled. */ void account_system_vtime(struct task_struct *tsk) { struct thread_info *ti = task_thread_info(tsk); unsigned long flags; cputime_t delta_stime; __u64 now; local_irq_save(flags); now = ia64_get_itc(); delta_stime = cycle_to_cputime(ti->ac_stime + (now - ti->ac_stamp)); if (irq_count() || idle_task(smp_processor_id()) != tsk) account_system_time(tsk, 0, delta_stime, delta_stime); else account_idle_time(delta_stime); ti->ac_stime = 0; ti->ac_stamp = now; local_irq_restore(flags); }
/* * Called from the context switch with interrupts disabled, to charge all * accumulated times to the current process, and to prepare accounting on * the next process. */ void ia64_account_on_switch(struct task_struct *prev, struct task_struct *next) { struct thread_info *pi = task_thread_info(prev); struct thread_info *ni = task_thread_info(next); cputime_t delta_stime, delta_utime; __u64 now; now = ia64_get_itc(); delta_stime = cycle_to_cputime(pi->ac_stime + (now - pi->ac_stamp)); if (idle_task(smp_processor_id()) != prev) account_system_time(prev, 0, delta_stime, delta_stime); else account_idle_time(delta_stime); if (pi->ac_utime) { delta_utime = cycle_to_cputime(pi->ac_utime); account_user_time(prev, delta_utime, delta_utime); } pi->ac_stamp = ni->ac_stamp = now; ni->ac_stime = ni->ac_utime = 0; }
void vtime_flush(struct task_struct *tsk) { struct thread_info *ti = task_thread_info(tsk); u64 delta; if (ti->utime) account_user_time(tsk, cycle_to_nsec(ti->utime)); if (ti->gtime) account_guest_time(tsk, cycle_to_nsec(ti->gtime)); if (ti->idle_time) account_idle_time(cycle_to_nsec(ti->idle_time)); if (ti->stime) { delta = cycle_to_nsec(ti->stime); account_system_index_time(tsk, delta, CPUTIME_SYSTEM); } if (ti->hardirq_time) { delta = cycle_to_nsec(ti->hardirq_time); account_system_index_time(tsk, delta, CPUTIME_IRQ); } if (ti->softirq_time) { delta = cycle_to_nsec(ti->softirq_time); account_system_index_time(tsk, delta, CPUTIME_SOFTIRQ); } ti->utime = 0; ti->gtime = 0; ti->idle_time = 0; ti->stime = 0; ti->hardirq_time = 0; ti->softirq_time = 0; }
void vtime_account_idle(struct task_struct *tsk) { account_idle_time(vtime_delta(tsk)); }
void vtime_account_idle(struct task_struct *tsk) { cputime_t delta_cpu = get_vtime_delta(tsk); account_idle_time(delta_cpu); }