diff options
Diffstat (limited to 'net/sched/sch_generic.c')
-rw-r--r-- | net/sched/sch_generic.c | 167 |
1 files changed, 86 insertions, 81 deletions
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 9461e8ae0529..983c32caf713 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -34,9 +34,6 @@ | |||
34 | #include <net/sock.h> | 34 | #include <net/sock.h> |
35 | #include <net/pkt_sched.h> | 35 | #include <net/pkt_sched.h> |
36 | 36 | ||
37 | #define SCHED_TX_DROP -2 | ||
38 | #define SCHED_TX_QUEUE -3 | ||
39 | |||
40 | /* Main transmission queue. */ | 37 | /* Main transmission queue. */ |
41 | 38 | ||
42 | /* Modifications to data participating in scheduling must be protected with | 39 | /* Modifications to data participating in scheduling must be protected with |
@@ -68,41 +65,24 @@ static inline int qdisc_qlen(struct Qdisc *q) | |||
68 | return q->q.qlen; | 65 | return q->q.qlen; |
69 | } | 66 | } |
70 | 67 | ||
71 | static inline int handle_dev_cpu_collision(struct net_device *dev) | 68 | static inline int dev_requeue_skb(struct sk_buff *skb, struct net_device *dev, |
72 | { | 69 | struct Qdisc *q) |
73 | if (unlikely(dev->xmit_lock_owner == smp_processor_id())) { | ||
74 | if (net_ratelimit()) | ||
75 | printk(KERN_WARNING | ||
76 | "Dead loop on netdevice %s, fix it urgently!\n", | ||
77 | dev->name); | ||
78 | return SCHED_TX_DROP; | ||
79 | } | ||
80 | __get_cpu_var(netdev_rx_stat).cpu_collision++; | ||
81 | return SCHED_TX_QUEUE; | ||
82 | } | ||
83 | |||
84 | static inline int | ||
85 | do_dev_requeue(struct sk_buff *skb, struct net_device *dev, struct Qdisc *q) | ||
86 | { | 70 | { |
87 | |||
88 | if (unlikely(skb->next)) | 71 | if (unlikely(skb->next)) |
89 | dev->gso_skb = skb; | 72 | dev->gso_skb = skb; |
90 | else | 73 | else |
91 | q->ops->requeue(skb, q); | 74 | q->ops->requeue(skb, q); |
92 | /* XXX: Could netif_schedule fail? Or is the fact we are | 75 | |
93 | * requeueing imply the hardware path is closed | ||
94 | * and even if we fail, some interupt will wake us | ||
95 | */ | ||
96 | netif_schedule(dev); | 76 | netif_schedule(dev); |
97 | return 0; | 77 | return 0; |
98 | } | 78 | } |
99 | 79 | ||
100 | static inline struct sk_buff * | 80 | static inline struct sk_buff *dev_dequeue_skb(struct net_device *dev, |
101 | try_get_tx_pkt(struct net_device *dev, struct Qdisc *q) | 81 | struct Qdisc *q) |
102 | { | 82 | { |
103 | struct sk_buff *skb = dev->gso_skb; | 83 | struct sk_buff *skb; |
104 | 84 | ||
105 | if (skb) | 85 | if ((skb = dev->gso_skb)) |
106 | dev->gso_skb = NULL; | 86 | dev->gso_skb = NULL; |
107 | else | 87 | else |
108 | skb = q->dequeue(q); | 88 | skb = q->dequeue(q); |
@@ -110,92 +90,117 @@ try_get_tx_pkt(struct net_device *dev, struct Qdisc *q) | |||
110 | return skb; | 90 | return skb; |
111 | } | 91 | } |
112 | 92 | ||
113 | static inline int | 93 | static inline int handle_dev_cpu_collision(struct sk_buff *skb, |
114 | tx_islocked(struct sk_buff *skb, struct net_device *dev, struct Qdisc *q) | 94 | struct net_device *dev, |
95 | struct Qdisc *q) | ||
115 | { | 96 | { |
116 | int ret = handle_dev_cpu_collision(dev); | 97 | int ret; |
117 | 98 | ||
118 | if (ret == SCHED_TX_DROP) { | 99 | if (unlikely(dev->xmit_lock_owner == smp_processor_id())) { |
100 | /* | ||
101 | * Same CPU holding the lock. It may be a transient | ||
102 | * configuration error, when hard_start_xmit() recurses. We | ||
103 | * detect it by checking xmit owner and drop the packet when | ||
104 | * deadloop is detected. Return OK to try the next skb. | ||
105 | */ | ||
119 | kfree_skb(skb); | 106 | kfree_skb(skb); |
120 | return qdisc_qlen(q); | 107 | if (net_ratelimit()) |
108 | printk(KERN_WARNING "Dead loop on netdevice %s, " | ||
109 | "fix it urgently!\n", dev->name); | ||
110 | ret = qdisc_qlen(q); | ||
111 | } else { | ||
112 | /* | ||
113 | * Another cpu is holding lock, requeue & delay xmits for | ||
114 | * some time. | ||
115 | */ | ||
116 | __get_cpu_var(netdev_rx_stat).cpu_collision++; | ||
117 | ret = dev_requeue_skb(skb, dev, q); | ||
121 | } | 118 | } |
122 | 119 | ||
123 | return do_dev_requeue(skb, dev, q); | 120 | return ret; |
124 | } | 121 | } |
125 | 122 | ||
126 | |||
127 | /* | 123 | /* |
128 | NOTE: Called under dev->queue_lock with locally disabled BH. | 124 | * NOTE: Called under dev->queue_lock with locally disabled BH. |
129 | 125 | * | |
130 | __LINK_STATE_QDISC_RUNNING guarantees only one CPU | 126 | * __LINK_STATE_QDISC_RUNNING guarantees only one CPU can process this |
131 | can enter this region at a time. | 127 | * device at a time. dev->queue_lock serializes queue accesses for |
132 | 128 | * this device AND dev->qdisc pointer itself. | |
133 | dev->queue_lock serializes queue accesses for this device | 129 | * |
134 | AND dev->qdisc pointer itself. | 130 | * netif_tx_lock serializes accesses to device driver. |
135 | 131 | * | |
136 | netif_tx_lock serializes accesses to device driver. | 132 | * dev->queue_lock and netif_tx_lock are mutually exclusive, |
137 | 133 | * if one is grabbed, another must be free. | |
138 | dev->queue_lock and netif_tx_lock are mutually exclusive, | 134 | * |
139 | if one is grabbed, another must be free. | 135 | * Note, that this procedure can be called by a watchdog timer |
140 | 136 | * | |
141 | Multiple CPUs may contend for the two locks. | 137 | * Returns to the caller: |
142 | 138 | * 0 - queue is empty or throttled. | |
143 | Note, that this procedure can be called by a watchdog timer | 139 | * >0 - queue is not empty. |
144 | 140 | * | |
145 | Returns to the caller: | 141 | */ |
146 | Returns: 0 - queue is empty or throttled. | ||
147 | >0 - queue is not empty. | ||
148 | |||
149 | */ | ||
150 | |||
151 | static inline int qdisc_restart(struct net_device *dev) | 142 | static inline int qdisc_restart(struct net_device *dev) |
152 | { | 143 | { |
153 | struct Qdisc *q = dev->qdisc; | 144 | struct Qdisc *q = dev->qdisc; |
154 | unsigned lockless = (dev->features & NETIF_F_LLTX); | ||
155 | struct sk_buff *skb; | 145 | struct sk_buff *skb; |
146 | unsigned lockless; | ||
156 | int ret; | 147 | int ret; |
157 | 148 | ||
158 | skb = try_get_tx_pkt(dev, q); | 149 | /* Dequeue packet */ |
159 | if (skb == NULL) | 150 | if (unlikely((skb = dev_dequeue_skb(dev, q)) == NULL)) |
160 | return 0; | 151 | return 0; |
161 | 152 | ||
162 | /* we have a packet to send */ | 153 | /* |
163 | if (!lockless) { | 154 | * When the driver has LLTX set, it does its own locking in |
164 | if (!netif_tx_trylock(dev)) | 155 | * start_xmit. These checks are worth it because even uncongested |
165 | return tx_islocked(skb, dev, q); | 156 | * locks can be quite expensive. The driver can do a trylock, as |
157 | * is being done here; in case of lock contention it should return | ||
158 | * NETDEV_TX_LOCKED and the packet will be requeued. | ||
159 | */ | ||
160 | lockless = (dev->features & NETIF_F_LLTX); | ||
161 | |||
162 | if (!lockless && !netif_tx_trylock(dev)) { | ||
163 | /* Another CPU grabbed the driver tx lock */ | ||
164 | return handle_dev_cpu_collision(skb, dev, q); | ||
166 | } | 165 | } |
167 | /* all clear .. */ | 166 | |
167 | /* And release queue */ | ||
168 | spin_unlock(&dev->queue_lock); | 168 | spin_unlock(&dev->queue_lock); |
169 | 169 | ||
170 | ret = NETDEV_TX_BUSY; | 170 | ret = NETDEV_TX_BUSY; |
171 | if (!netif_queue_stopped(dev)) | 171 | if (!netif_queue_stopped(dev)) |
172 | /* churn baby churn .. */ | ||
173 | ret = dev_hard_start_xmit(skb, dev); | 172 | ret = dev_hard_start_xmit(skb, dev); |
174 | 173 | ||
175 | if (!lockless) | 174 | if (!lockless) |
176 | netif_tx_unlock(dev); | 175 | netif_tx_unlock(dev); |
177 | 176 | ||
178 | spin_lock(&dev->queue_lock); | 177 | spin_lock(&dev->queue_lock); |
179 | |||
180 | /* we need to refresh q because it may be invalid since | ||
181 | * we dropped dev->queue_lock earlier ... | ||
182 | * So dont try to be clever grasshopper | ||
183 | */ | ||
184 | q = dev->qdisc; | 178 | q = dev->qdisc; |
185 | /* most likely result, packet went ok */ | ||
186 | if (ret == NETDEV_TX_OK) | ||
187 | return qdisc_qlen(q); | ||
188 | /* only for lockless drivers .. */ | ||
189 | if (ret == NETDEV_TX_LOCKED && lockless) | ||
190 | return tx_islocked(skb, dev, q); | ||
191 | 179 | ||
192 | if (unlikely (ret != NETDEV_TX_BUSY && net_ratelimit())) | 180 | switch (ret) { |
193 | printk(KERN_WARNING " BUG %s code %d qlen %d\n",dev->name, ret, q->q.qlen); | 181 | case NETDEV_TX_OK: |
182 | /* Driver sent out skb successfully */ | ||
183 | ret = qdisc_qlen(q); | ||
184 | break; | ||
185 | |||
186 | case NETDEV_TX_LOCKED: | ||
187 | /* Driver try lock failed */ | ||
188 | ret = handle_dev_cpu_collision(skb, dev, q); | ||
189 | break; | ||
190 | |||
191 | default: | ||
192 | /* Driver returned NETDEV_TX_BUSY - requeue skb */ | ||
193 | if (unlikely (ret != NETDEV_TX_BUSY && net_ratelimit())) | ||
194 | printk(KERN_WARNING "BUG %s code %d qlen %d\n", | ||
195 | dev->name, ret, q->q.qlen); | ||
196 | |||
197 | ret = dev_requeue_skb(skb, dev, q); | ||
198 | break; | ||
199 | } | ||
194 | 200 | ||
195 | return do_dev_requeue(skb, dev, q); | 201 | return ret; |
196 | } | 202 | } |
197 | 203 | ||
198 | |||
199 | void __qdisc_run(struct net_device *dev) | 204 | void __qdisc_run(struct net_device *dev) |
200 | { | 205 | { |
201 | do { | 206 | do { |