Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3c5d92a0 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Thomas Gleixner
Browse files

nohz: Introduce arch_needs_cpu



Allow the architecture to request a normal jiffy tick when the system
goes idle and tick_nohz_stop_sched_tick is called . On s390 the hook is
used to prevent the system going fully idle if there has been an
interrupt other than a clock comparator interrupt since the last wakeup.

On s390 the HiperSockets response time for 1 connection ping-pong goes
down from 42 to 34 microseconds. The CPU cost decreases by 27%.

Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
LKML-Reference: <20090929122533.402715150@de.ibm.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent eed3b9cf
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -183,6 +183,7 @@ struct s390_idle_data {
	unsigned long long idle_count;
	unsigned long long idle_enter;
	unsigned long long idle_time;
	int nohz_delay;
};

DECLARE_PER_CPU(struct s390_idle_data, s390_idle);
@@ -198,4 +199,11 @@ static inline void s390_idle_check(void)
		vtime_start_cpu();
}

static inline int s390_nohz_delay(int cpu)
{
	return per_cpu(s390_idle, cpu).nohz_delay != 0;
}

#define arch_needs_cpu(cpu) s390_nohz_delay(cpu)

#endif /* _S390_CPUTIME_H */
+2 −0
Original line number Diff line number Diff line
@@ -126,6 +126,8 @@ void __irq_entry do_extint(struct pt_regs *regs, unsigned short code)
		/* Serve timer interrupts first. */
		clock_comparator_work();
	kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
	if (code != 0x1004)
		__get_cpu_var(s390_idle).nohz_delay = 1;
        index = ext_hash(code);
	for (p = ext_int_hash[index]; p; p = p->next) {
		if (likely(p->code == code))
+2 −0
Original line number Diff line number Diff line
@@ -167,6 +167,8 @@ void vtime_stop_cpu(void)
	/* Wait for external, I/O or machine check interrupt. */
	psw.mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_IO | PSW_MASK_EXT;

	idle->nohz_delay = 0;

	/* Check if the CPU timer needs to be reprogrammed. */
	if (vq->do_spt) {
		__u64 vmax = VTIMER_MAX_SLICE;
+1 −0
Original line number Diff line number Diff line
@@ -618,6 +618,7 @@ void __irq_entry do_IRQ(struct pt_regs *regs)
	old_regs = set_irq_regs(regs);
	s390_idle_check();
	irq_enter();
	__get_cpu_var(s390_idle).nohz_delay = 1;
	if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
		/* Serve timer interrupts first. */
		clock_comparator_work();
+3 −0
Original line number Diff line number Diff line
@@ -98,6 +98,9 @@ extern int tick_check_oneshot_change(int allow_nohz);
extern struct tick_sched *tick_get_tick_sched(int cpu);
extern void tick_check_idle(int cpu);
extern int tick_oneshot_mode_active(void);
#  ifndef arch_needs_cpu
#   define arch_needs_cpu(cpu) (0)
#  endif
# else
static inline void tick_clock_notify(void) { }
static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
Loading