Skip to content

Commit

Permalink
[NET]: Add preemption point in qdisc_run
Browse files Browse the repository at this point in the history
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: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Herbert Xu authored and David S. Miller committed Mar 28, 2008
1 parent 32aced7 commit 2ba2506
Showing 1 changed file with 15 additions and 3 deletions.
18 changes: 15 additions & 3 deletions net/sched/sch_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/*
* 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;
} while (!netif_queue_stopped(dev));
}
}

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

0 comments on commit 2ba2506

Please sign in to comment.