commit d55db74d5dbb56eb8f4fc874a97af7294a3b3008
Author: Herbert Xu <[EMAIL PROTECTED]>
Date:   Sun Apr 6 23:41:50 2008 -0700

    NET: Add preemption point in qdisc_run
    
    Upstream commit: 2ba2506ca7ca62c56edaa334b0fe61eb5eab6ab0
    
    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 <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
    Signed-off-by: Chris Wright <[EMAIL PROTECTED]>

diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index e595e65..7888955 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -178,10 +178,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);
 }
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to