Пример #1
0
/*
 * Update process times based on virtual cpu times stored by entry.S
 * to the lowcore fields user_timer, system_timer & steal_clock.
 */
void account_process_tick(struct task_struct *tsk, int user_tick)
{
	cputime_t cputime;
	__u64 timer, clock;
	int rcu_user_flag;

	timer = S390_lowcore.last_update_timer;
	clock = S390_lowcore.last_update_clock;
	asm volatile ("  STPT %0\n"    /* Store current cpu timer value */
		      "  STCK %1"      /* Store current tod clock value */
		      : "=m" (S390_lowcore.last_update_timer),
		        "=m" (S390_lowcore.last_update_clock) );
	S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer;
	S390_lowcore.steal_clock += S390_lowcore.last_update_clock - clock;

	cputime = S390_lowcore.user_timer >> 12;
	rcu_user_flag = cputime != 0;
	S390_lowcore.user_timer -= cputime << 12;
	S390_lowcore.steal_clock -= cputime << 12;
	account_user_time(tsk, cputime);

	cputime =  S390_lowcore.system_timer >> 12;
	S390_lowcore.system_timer -= cputime << 12;
	S390_lowcore.steal_clock -= cputime << 12;
	account_system_time(tsk, HARDIRQ_OFFSET, cputime);

	cputime = S390_lowcore.steal_clock;
	if ((__s64) cputime > 0) {
		cputime >>= 12;
		S390_lowcore.steal_clock -= cputime << 12;
		account_steal_time(tsk, cputime);
	}
Пример #2
0
/*
 * 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);
}
Пример #3
0
/*
 * 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);
}
Пример #4
0
/*
 * 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;
}
Пример #5
0
void vtime_account_system(struct task_struct *tsk)
{
	cputime_t delta = vtime_delta(tsk);

	account_system_time(tsk, 0, delta, delta);
}
Пример #6
0
/**
 * nohz_restart_sched_tick - restart the idle tick from the idle task
 *
 * Restart the idle tick when the CPU is woken up from idle
 */
void tick_nohz_restart_sched_tick(void)
{
	int cpu = smp_processor_id();
	struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
	unsigned long ticks;
	ktime_t now, delta;

	if (!ts->tick_stopped)
		return;

	/* Update jiffies first */
	now = ktime_get();

	local_irq_disable();
	tick_do_update_jiffies64(now);
	cpu_clear(cpu, nohz_cpu_mask);

	/* Account the idle time */
	delta = ktime_sub(now, ts->idle_entrytime);
	ts->idle_sleeptime = ktime_add(ts->idle_sleeptime, delta);

	/*
	 * We stopped the tick in idle. Update process times would miss the
	 * time we slept as update_process_times does only a 1 tick
	 * accounting. Enforce that this is accounted to idle !
	 */
	ticks = jiffies - ts->idle_jiffies;
	/*
	 * We might be one off. Do not randomly account a huge number of ticks!
	 */
	if (ticks && ticks < LONG_MAX) {
		add_preempt_count(HARDIRQ_OFFSET);
		account_system_time(current, HARDIRQ_OFFSET,
				    jiffies_to_cputime(ticks));
		sub_preempt_count(HARDIRQ_OFFSET);
	}

	/*
	 * Cancel the scheduled timer and restore the tick
	 */
	ts->tick_stopped  = 0;
	hrtimer_cancel(&ts->sched_timer);
	ts->sched_timer.expires = ts->idle_tick;

	while (1) {
		/* Forward the time to expire in the future */
		hrtimer_forward(&ts->sched_timer, now, tick_period);

		if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
			hrtimer_start(&ts->sched_timer,
				      ts->sched_timer.expires,
				      HRTIMER_MODE_ABS);
			/* Check, if the timer was already in the past */
			if (hrtimer_active(&ts->sched_timer))
				break;
		} else {
			if (!tick_program_event(ts->sched_timer.expires, 0))
				break;
		}
		/* Update jiffies and reread time */
		tick_do_update_jiffies64(now);
		now = ktime_get();
	}
	local_irq_enable();
}
Пример #7
0
static void __vtime_account_system(struct task_struct *tsk)
{
    cputime_t delta_cpu = get_vtime_delta(tsk);

    account_system_time(tsk, irq_count(), delta_cpu, cputime_to_scaled(delta_cpu));
}