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

Commit 2ba2506c authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller
Browse files

[NET]: Add preemption point in qdisc_run



The qdisc_run loop is currently unbounded and runs entirely in a
softirq.  This is bad as it may create an unbounded softirq run.

This patch fixes this by calling need_resched and breaking out if
necessary.

It also adds a break out if the jiffies value changes since that would
indicate we've been transmitting for too long which starves other
softirqs.

Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 32aced75
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -184,10 +184,22 @@ static inline int qdisc_restart(struct net_device *dev)

void __qdisc_run(struct net_device *dev)
{
	do {
		if (!qdisc_restart(dev))
	unsigned long start_time = jiffies;

	while (qdisc_restart(dev)) {
		if (netif_queue_stopped(dev))
			break;
	} while (!netif_queue_stopped(dev));

		/*
		 * Postpone processing if
		 * 1. another process needs the CPU;
		 * 2. we've been doing it for too long.
		 */
		if (need_resched() || jiffies != start_time) {
			netif_schedule(dev);
			break;
		}
	}

	clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state);
}