Ejemplo n.º 1
0
void
netisr_pollmore()
{
	struct timeval t;
	int kern_load;

	mtx_lock(&poll_mtx);
	if (!netisr_pollmore_scheduled) {
		mtx_unlock(&poll_mtx);
		return;
	}
	netisr_pollmore_scheduled = 0;
	phase = 5;
	if (residual_burst > 0) {
		netisr_poll_scheduled = 1;
		netisr_pollmore_scheduled = 1;
		netisr_sched_poll();
		mtx_unlock(&poll_mtx);
		/* will run immediately on return, followed by netisrs */
		return;
	}
	/* here we can account time spent in netisr's in this tick */
	microuptime(&t);
	kern_load = (t.tv_usec - poll_start_t.tv_usec) +
		(t.tv_sec - poll_start_t.tv_sec)*1000000;	/* us */
	kern_load = (kern_load * hz) / 10000;			/* 0..100 */
	if (kern_load > (100 - user_frac)) { /* try decrease ticks */
		if (poll_burst > 1)
			poll_burst--;
	} else {
		if (poll_burst < poll_burst_max)
			poll_burst++;
	}

	pending_polls--;
	if (pending_polls == 0) /* we are done */
		phase = 0;
	else {
		/*
		 * Last cycle was long and caused us to miss one or more
		 * hardclock ticks. Restart processing again, but slightly
		 * reduce the burst size to prevent that this happens again.
		 */
		poll_burst -= (poll_burst / 8);
		if (poll_burst < 1)
			poll_burst = 1;
		netisr_poll_scheduled = 1;
		netisr_pollmore_scheduled = 1;
		netisr_sched_poll();
		phase = 6;
	}
	mtx_unlock(&poll_mtx);
}
Ejemplo n.º 2
0
/*
 * Hook from hardclock. Tries to schedule a netisr, but keeps track
 * of lost ticks due to the previous handler taking too long.
 * Normally, this should not happen, because polling handler should
 * run for a short time. However, in some cases (e.g. when there are
 * changes in link status etc.) the drivers take a very long time
 * (even in the order of milliseconds) to reset and reconfigure the
 * device, causing apparent lost polls.
 *
 * The first part of the code is just for debugging purposes, and tries
 * to count how often hardclock ticks are shorter than they should,
 * meaning either stray interrupts or delayed events.
 */
void
hardclock_device_poll(void)
{
	static struct timeval prev_t, t;
	int delta;

	if (poll_handlers == 0 || poll_shutting_down)
		return;

	microuptime(&t);
	delta = (t.tv_usec - prev_t.tv_usec) +
		(t.tv_sec - prev_t.tv_sec)*1000000;
	if (delta * hz < 500000)
		short_ticks++;
	else
		prev_t = t;

	if (pending_polls > 100) {
		/*
		 * Too much, assume it has stalled (not always true
		 * see comment above).
		 */
		stalled++;
		pending_polls = 0;
		phase = 0;
	}

	if (phase <= 2) {
		if (phase != 0)
			suspect++;
		phase = 1;
		netisr_poll_scheduled = 1;
		netisr_pollmore_scheduled = 1;
		netisr_sched_poll();
		phase = 2;
	}
	if (pending_polls++ > 0)
		lost_polls++;
}