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

Commit b791072b authored by Will Schmidt's avatar Will Schmidt Committed by Paul Mackerras
Browse files

[POWERPC] hvc_console: Polling mode timer backoff



Add a back-off mechanism to hvc_console's polling logic.   This change
drops the timers/second ratio from ~90 to ~1/2 while the console is
idle.
This change is most noticeable when watching /proc/timer_stats output.

This only affects when the hvc_console is running in poll mode, i.e.
power4 and cell systems.

I've tested on Power4, Michael Ellerman has both contributed to the
patch and tested on cell.

Signed-off-by: default avatarWill Schmidt <will_schmidt@vnet.ibm.com>
Signed-off-by: default avatarMichael Ellerman <michael@ellerman.id.au>
Acked-by: default avatarLinas Vepstas <linas@austin.ibm.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent b3a6d2a5
Loading
Loading
Loading
Loading
+25 −6
Original line number Diff line number Diff line
@@ -47,8 +47,6 @@
#define HVC_MAJOR	229
#define HVC_MINOR	0

#define TIMEOUT		(10)

/*
 * Wait this long per iteration while trying to push buffered data to the
 * hypervisor before allowing the tty to complete a close operation.
@@ -550,6 +548,18 @@ static int hvc_chars_in_buffer(struct tty_struct *tty)
	return hp->n_outbuf;
}

/*
 * timeout will vary between the MIN and MAX values defined here.  By default
 * and during console activity we will use a default MIN_TIMEOUT of 10.  When
 * the console is idle, we increase the timeout value on each pass through
 * msleep until we reach the max.  This may be noticeable as a brief (average
 * one second) delay on the console before the console responds to input when
 * there has been no input for some time.
 */
#define MIN_TIMEOUT		(10)
#define MAX_TIMEOUT		(2000)
static u32 timeout = MIN_TIMEOUT;

#define HVC_POLL_READ	0x00000001
#define HVC_POLL_WRITE	0x00000002

@@ -642,8 +652,13 @@ static int hvc_poll(struct hvc_struct *hp)
 bail:
	spin_unlock_irqrestore(&hp->lock, flags);

	if (read_total)
	if (read_total) {
		/* Activity is occurring, so reset the polling backoff value to
		   a minimum for performance. */
		timeout = MIN_TIMEOUT;

		tty_flip_buffer_push(tty);
	}

	return poll_mask;
}
@@ -688,8 +703,12 @@ int khvcd(void *unused)
		if (!hvc_kicked) {
			if (poll_mask == 0)
				schedule();
			else
				msleep_interruptible(TIMEOUT);
			else {
				if (timeout < MAX_TIMEOUT)
					timeout += (timeout >> 6) + 1;

				msleep_interruptible(timeout);
			}
		}
		__set_current_state(TASK_RUNNING);
	} while (!kthread_should_stop());