Commit 152e9b86 authored by Martin Schwidefsky's avatar Martin Schwidefsky
Browse files

s390/vtime: steal time exponential moving average



To be able to judge the current overcommitment ratio for a CPU add
a lowcore field with the exponential moving average of the steal time.
The average is updated every tick.

Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 01396a37
Loading
Loading
Loading
Loading
+31 −30
Original line number Diff line number Diff line
@@ -91,52 +91,53 @@ struct lowcore {
	__u64	hardirq_timer;			/* 0x02e8 */
	__u64	softirq_timer;			/* 0x02f0 */
	__u64	steal_timer;			/* 0x02f8 */
	__u64	last_update_timer;		/* 0x0300 */
	__u64	last_update_clock;		/* 0x0308 */
	__u64	int_clock;			/* 0x0310 */
	__u64	mcck_clock;			/* 0x0318 */
	__u64	clock_comparator;		/* 0x0320 */
	__u64	boot_clock[2];			/* 0x0328 */
	__u64	avg_steal_timer;		/* 0x0300 */
	__u64	last_update_timer;		/* 0x0308 */
	__u64	last_update_clock;		/* 0x0310 */
	__u64	int_clock;			/* 0x0318*/
	__u64	mcck_clock;			/* 0x0320 */
	__u64	clock_comparator;		/* 0x0328 */
	__u64	boot_clock[2];			/* 0x0330 */

	/* Current process. */
	__u64	current_task;			/* 0x0338 */
	__u64	kernel_stack;			/* 0x0340 */
	__u64	current_task;			/* 0x0340 */
	__u64	kernel_stack;			/* 0x0348 */

	/* Interrupt, DAT-off and restartstack. */
	__u64	async_stack;			/* 0x0348 */
	__u64	nodat_stack;			/* 0x0350 */
	__u64	restart_stack;			/* 0x0358 */
	__u64	async_stack;			/* 0x0350 */
	__u64	nodat_stack;			/* 0x0358 */
	__u64	restart_stack;			/* 0x0360 */

	/* Restart function and parameter. */
	__u64	restart_fn;			/* 0x0360 */
	__u64	restart_data;			/* 0x0368 */
	__u64	restart_source;			/* 0x0370 */
	__u64	restart_fn;			/* 0x0368 */
	__u64	restart_data;			/* 0x0370 */
	__u64	restart_source;			/* 0x0378 */

	/* Address space pointer. */
	__u64	kernel_asce;			/* 0x0378 */
	__u64	user_asce;			/* 0x0380 */
	__u64	vdso_asce;			/* 0x0388 */
	__u64	kernel_asce;			/* 0x0380 */
	__u64	user_asce;			/* 0x0388 */
	__u64	vdso_asce;			/* 0x0390 */

	/*
	 * The lpp and current_pid fields form a
	 * 64-bit value that is set as program
	 * parameter with the LPP instruction.
	 */
	__u32	lpp;				/* 0x0390 */
	__u32	current_pid;			/* 0x0394 */
	__u32	lpp;				/* 0x0398 */
	__u32	current_pid;			/* 0x039c */

	/* SMP info area */
	__u32	cpu_nr;				/* 0x0398 */
	__u32	softirq_pending;		/* 0x039c */
	__u32	preempt_count;			/* 0x03a0 */
	__u32	spinlock_lockval;		/* 0x03a4 */
	__u32	spinlock_index;			/* 0x03a8 */
	__u32	fpu_flags;			/* 0x03ac */
	__u64	percpu_offset;			/* 0x03b0 */
	__u64	vdso_per_cpu_data;		/* 0x03b8 */
	__u64	machine_flags;			/* 0x03c0 */
	__u64	gmap;				/* 0x03c8 */
	__u8	pad_0x03d0[0x0400-0x03d0];	/* 0x03d0 */
	__u32	cpu_nr;				/* 0x03a0 */
	__u32	softirq_pending;		/* 0x03a4 */
	__u32	preempt_count;			/* 0x03a8 */
	__u32	spinlock_lockval;		/* 0x03ac */
	__u32	spinlock_index;			/* 0x03b0 */
	__u32	fpu_flags;			/* 0x03b4 */
	__u64	percpu_offset;			/* 0x03b8 */
	__u64	vdso_per_cpu_data;		/* 0x03c0 */
	__u64	machine_flags;			/* 0x03c8 */
	__u64	gmap;				/* 0x03d0 */
	__u8	pad_0x03d8[0x0400-0x03d8];	/* 0x03d8 */

	/* br %r1 trampoline */
	__u16	br_r1_trampoline;		/* 0x0400 */
+2 −1
Original line number Diff line number Diff line
@@ -266,7 +266,8 @@ static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu)
	lc->percpu_offset = __per_cpu_offset[cpu];
	lc->kernel_asce = S390_lowcore.kernel_asce;
	lc->machine_flags = S390_lowcore.machine_flags;
	lc->user_timer = lc->system_timer = lc->steal_timer = 0;
	lc->user_timer = lc->system_timer =
		lc->steal_timer = lc->avg_steal_timer = 0;
	__ctl_store(lc->cregs_save_area, 0, 15);
	save_access_regs((unsigned int *) lc->access_regs_save_area);
	memcpy(lc->stfle_fac_list, S390_lowcore.stfle_fac_list,
+12 −7
Original line number Diff line number Diff line
@@ -124,7 +124,7 @@ static void account_system_index_scaled(struct task_struct *p, u64 cputime,
 */
static int do_account_vtime(struct task_struct *tsk)
{
	u64 timer, clock, user, guest, system, hardirq, softirq, steal;
	u64 timer, clock, user, guest, system, hardirq, softirq;

	timer = S390_lowcore.last_update_timer;
	clock = S390_lowcore.last_update_clock;
@@ -182,12 +182,6 @@ static int do_account_vtime(struct task_struct *tsk)
	if (softirq)
		account_system_index_scaled(tsk, softirq, CPUTIME_SOFTIRQ);

	steal = S390_lowcore.steal_timer;
	if ((s64) steal > 0) {
		S390_lowcore.steal_timer = 0;
		account_steal_time(cputime_to_nsecs(steal));
	}

	return virt_timer_forward(user + guest + system + hardirq + softirq);
}

@@ -213,8 +207,19 @@ void vtime_task_switch(struct task_struct *prev)
 */
void vtime_flush(struct task_struct *tsk)
{
	u64 steal, avg_steal;

	if (do_account_vtime(tsk))
		virt_timer_expire();

	steal = S390_lowcore.steal_timer;
	avg_steal = S390_lowcore.avg_steal_timer / 2;
	if ((s64) steal > 0) {
		S390_lowcore.steal_timer = 0;
		account_steal_time(steal);
		avg_steal += steal;
	}
	S390_lowcore.avg_steal_timer = avg_steal;
}

/*