diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /net/sched/sch_teql.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'net/sched/sch_teql.c')
-rw-r--r-- | net/sched/sch_teql.c | 57 |
1 files changed, 31 insertions, 26 deletions
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index 47416716294..4f4c52c0eeb 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c | |||
@@ -67,6 +67,7 @@ struct teql_master { | |||
67 | struct teql_sched_data { | 67 | struct teql_sched_data { |
68 | struct Qdisc *next; | 68 | struct Qdisc *next; |
69 | struct teql_master *m; | 69 | struct teql_master *m; |
70 | struct neighbour *ncache; | ||
70 | struct sk_buff_head q; | 71 | struct sk_buff_head q; |
71 | }; | 72 | }; |
72 | 73 | ||
@@ -87,7 +88,9 @@ teql_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
87 | return NET_XMIT_SUCCESS; | 88 | return NET_XMIT_SUCCESS; |
88 | } | 89 | } |
89 | 90 | ||
90 | return qdisc_drop(skb, sch); | 91 | kfree_skb(skb); |
92 | sch->qstats.drops++; | ||
93 | return NET_XMIT_DROP; | ||
91 | } | 94 | } |
92 | 95 | ||
93 | static struct sk_buff * | 96 | static struct sk_buff * |
@@ -133,6 +136,7 @@ teql_reset(struct Qdisc *sch) | |||
133 | 136 | ||
134 | skb_queue_purge(&dat->q); | 137 | skb_queue_purge(&dat->q); |
135 | sch->q.qlen = 0; | 138 | sch->q.qlen = 0; |
139 | teql_neigh_release(xchg(&dat->ncache, NULL)); | ||
136 | } | 140 | } |
137 | 141 | ||
138 | static void | 142 | static void |
@@ -164,6 +168,7 @@ teql_destroy(struct Qdisc *sch) | |||
164 | } | 168 | } |
165 | } | 169 | } |
166 | skb_queue_purge(&dat->q); | 170 | skb_queue_purge(&dat->q); |
171 | teql_neigh_release(xchg(&dat->ncache, NULL)); | ||
167 | break; | 172 | break; |
168 | } | 173 | } |
169 | 174 | ||
@@ -222,25 +227,21 @@ static int teql_qdisc_init(struct Qdisc *sch, struct nlattr *opt) | |||
222 | static int | 227 | static int |
223 | __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, | 228 | __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, |
224 | struct net_device *dev, struct netdev_queue *txq, | 229 | struct net_device *dev, struct netdev_queue *txq, |
225 | struct dst_entry *dst) | 230 | struct neighbour *mn) |
226 | { | 231 | { |
227 | struct neighbour *n; | 232 | struct teql_sched_data *q = qdisc_priv(txq->qdisc); |
228 | int err = 0; | 233 | struct neighbour *n = q->ncache; |
229 | 234 | ||
230 | n = dst_neigh_lookup_skb(dst, skb); | 235 | if (mn->tbl == NULL) |
231 | if (!n) | 236 | return -EINVAL; |
232 | return -ENOENT; | 237 | if (n && n->tbl == mn->tbl && |
233 | 238 | memcmp(n->primary_key, mn->primary_key, mn->tbl->key_len) == 0) { | |
234 | if (dst->dev != dev) { | 239 | atomic_inc(&n->refcnt); |
235 | struct neighbour *mn; | 240 | } else { |
236 | 241 | n = __neigh_lookup_errno(mn->tbl, mn->primary_key, dev); | |
237 | mn = __neigh_lookup_errno(n->tbl, n->primary_key, dev); | 242 | if (IS_ERR(n)) |
238 | neigh_release(n); | 243 | return PTR_ERR(n); |
239 | if (IS_ERR(mn)) | ||
240 | return PTR_ERR(mn); | ||
241 | n = mn; | ||
242 | } | 244 | } |
243 | |||
244 | if (neigh_event_send(n, skb_res) == 0) { | 245 | if (neigh_event_send(n, skb_res) == 0) { |
245 | int err; | 246 | int err; |
246 | char haddr[MAX_ADDR_LEN]; | 247 | char haddr[MAX_ADDR_LEN]; |
@@ -249,13 +250,15 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, | |||
249 | err = dev_hard_header(skb, dev, ntohs(skb->protocol), haddr, | 250 | err = dev_hard_header(skb, dev, ntohs(skb->protocol), haddr, |
250 | NULL, skb->len); | 251 | NULL, skb->len); |
251 | 252 | ||
252 | if (err < 0) | 253 | if (err < 0) { |
253 | err = -EINVAL; | 254 | neigh_release(n); |
254 | } else { | 255 | return -EINVAL; |
255 | err = (skb_res == NULL) ? -EAGAIN : 1; | 256 | } |
257 | teql_neigh_release(xchg(&q->ncache, n)); | ||
258 | return 0; | ||
256 | } | 259 | } |
257 | neigh_release(n); | 260 | neigh_release(n); |
258 | return err; | 261 | return (skb_res == NULL) ? -EAGAIN : 1; |
259 | } | 262 | } |
260 | 263 | ||
261 | static inline int teql_resolve(struct sk_buff *skb, | 264 | static inline int teql_resolve(struct sk_buff *skb, |
@@ -264,6 +267,7 @@ static inline int teql_resolve(struct sk_buff *skb, | |||
264 | struct netdev_queue *txq) | 267 | struct netdev_queue *txq) |
265 | { | 268 | { |
266 | struct dst_entry *dst = skb_dst(skb); | 269 | struct dst_entry *dst = skb_dst(skb); |
270 | struct neighbour *mn; | ||
267 | int res; | 271 | int res; |
268 | 272 | ||
269 | if (txq->qdisc == &noop_qdisc) | 273 | if (txq->qdisc == &noop_qdisc) |
@@ -273,7 +277,8 @@ static inline int teql_resolve(struct sk_buff *skb, | |||
273 | return 0; | 277 | return 0; |
274 | 278 | ||
275 | rcu_read_lock(); | 279 | rcu_read_lock(); |
276 | res = __teql_resolve(skb, skb_res, dev, txq, dst); | 280 | mn = dst_get_neighbour(dst); |
281 | res = mn ? __teql_resolve(skb, skb_res, dev, txq, mn) : 0; | ||
277 | rcu_read_unlock(); | 282 | rcu_read_unlock(); |
278 | 283 | ||
279 | return res; | 284 | return res; |
@@ -305,7 +310,7 @@ restart: | |||
305 | 310 | ||
306 | if (slave_txq->qdisc_sleeping != q) | 311 | if (slave_txq->qdisc_sleeping != q) |
307 | continue; | 312 | continue; |
308 | if (netif_xmit_stopped(netdev_get_tx_queue(slave, subq)) || | 313 | if (__netif_subqueue_stopped(slave, subq) || |
309 | !netif_running(slave)) { | 314 | !netif_running(slave)) { |
310 | busy = 1; | 315 | busy = 1; |
311 | continue; | 316 | continue; |
@@ -316,7 +321,7 @@ restart: | |||
316 | if (__netif_tx_trylock(slave_txq)) { | 321 | if (__netif_tx_trylock(slave_txq)) { |
317 | unsigned int length = qdisc_pkt_len(skb); | 322 | unsigned int length = qdisc_pkt_len(skb); |
318 | 323 | ||
319 | if (!netif_xmit_frozen_or_stopped(slave_txq) && | 324 | if (!netif_tx_queue_frozen_or_stopped(slave_txq) && |
320 | slave_ops->ndo_start_xmit(skb, slave) == NETDEV_TX_OK) { | 325 | slave_ops->ndo_start_xmit(skb, slave) == NETDEV_TX_OK) { |
321 | txq_trans_update(slave_txq); | 326 | txq_trans_update(slave_txq); |
322 | __netif_tx_unlock(slave_txq); | 327 | __netif_tx_unlock(slave_txq); |
@@ -328,7 +333,7 @@ restart: | |||
328 | } | 333 | } |
329 | __netif_tx_unlock(slave_txq); | 334 | __netif_tx_unlock(slave_txq); |
330 | } | 335 | } |
331 | if (netif_xmit_stopped(netdev_get_tx_queue(dev, 0))) | 336 | if (netif_queue_stopped(dev)) |
332 | busy = 1; | 337 | busy = 1; |
333 | break; | 338 | break; |
334 | case 1: | 339 | case 1: |