diff options
Diffstat (limited to 'net/sched/sch_generic.c')
-rw-r--r-- | net/sched/sch_generic.c | 34 |
1 files changed, 14 insertions, 20 deletions
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index a08a98e7b943..8bb7c47191ea 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -311,6 +311,8 @@ static const u8 prio2band[TC_PRIO_MAX+1] = | |||
311 | generic prio+fifo combination. | 311 | generic prio+fifo combination. |
312 | */ | 312 | */ |
313 | 313 | ||
314 | #define PFIFO_FAST_BANDS 3 | ||
315 | |||
314 | static inline struct sk_buff_head *prio2list(struct sk_buff *skb, | 316 | static inline struct sk_buff_head *prio2list(struct sk_buff *skb, |
315 | struct Qdisc *qdisc) | 317 | struct Qdisc *qdisc) |
316 | { | 318 | { |
@@ -318,8 +320,7 @@ static inline struct sk_buff_head *prio2list(struct sk_buff *skb, | |||
318 | return list + prio2band[skb->priority & TC_PRIO_MAX]; | 320 | return list + prio2band[skb->priority & TC_PRIO_MAX]; |
319 | } | 321 | } |
320 | 322 | ||
321 | static int | 323 | static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc) |
322 | pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc) | ||
323 | { | 324 | { |
324 | struct sk_buff_head *list = prio2list(skb, qdisc); | 325 | struct sk_buff_head *list = prio2list(skb, qdisc); |
325 | 326 | ||
@@ -331,36 +332,34 @@ pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc) | |||
331 | return qdisc_drop(skb, qdisc); | 332 | return qdisc_drop(skb, qdisc); |
332 | } | 333 | } |
333 | 334 | ||
334 | static struct sk_buff * | 335 | static struct sk_buff *pfifo_fast_dequeue(struct Qdisc* qdisc) |
335 | pfifo_fast_dequeue(struct Qdisc* qdisc) | ||
336 | { | 336 | { |
337 | int prio; | 337 | int prio; |
338 | struct sk_buff_head *list = qdisc_priv(qdisc); | 338 | struct sk_buff_head *list = qdisc_priv(qdisc); |
339 | 339 | ||
340 | for (prio = 0; prio < 3; prio++, list++) { | 340 | for (prio = 0; prio < PFIFO_FAST_BANDS; prio++, list++) { |
341 | struct sk_buff *skb = __qdisc_dequeue_head(qdisc, list); | 341 | struct sk_buff *skb = __qdisc_dequeue_head(qdisc, list); |
342 | if (skb) { | 342 | if (skb) { |
343 | qdisc->q.qlen--; | 343 | qdisc->q.qlen--; |
344 | return skb; | 344 | return skb; |
345 | } | 345 | } |
346 | } | 346 | } |
347 | |||
347 | return NULL; | 348 | return NULL; |
348 | } | 349 | } |
349 | 350 | ||
350 | static int | 351 | static int pfifo_fast_requeue(struct sk_buff *skb, struct Qdisc* qdisc) |
351 | pfifo_fast_requeue(struct sk_buff *skb, struct Qdisc* qdisc) | ||
352 | { | 352 | { |
353 | qdisc->q.qlen++; | 353 | qdisc->q.qlen++; |
354 | return __qdisc_requeue(skb, qdisc, prio2list(skb, qdisc)); | 354 | return __qdisc_requeue(skb, qdisc, prio2list(skb, qdisc)); |
355 | } | 355 | } |
356 | 356 | ||
357 | static void | 357 | static void pfifo_fast_reset(struct Qdisc* qdisc) |
358 | pfifo_fast_reset(struct Qdisc* qdisc) | ||
359 | { | 358 | { |
360 | int prio; | 359 | int prio; |
361 | struct sk_buff_head *list = qdisc_priv(qdisc); | 360 | struct sk_buff_head *list = qdisc_priv(qdisc); |
362 | 361 | ||
363 | for (prio=0; prio < 3; prio++) | 362 | for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) |
364 | __qdisc_reset_queue(qdisc, list + prio); | 363 | __qdisc_reset_queue(qdisc, list + prio); |
365 | 364 | ||
366 | qdisc->qstats.backlog = 0; | 365 | qdisc->qstats.backlog = 0; |
@@ -369,35 +368,30 @@ pfifo_fast_reset(struct Qdisc* qdisc) | |||
369 | 368 | ||
370 | static int pfifo_fast_dump(struct Qdisc *qdisc, struct sk_buff *skb) | 369 | static int pfifo_fast_dump(struct Qdisc *qdisc, struct sk_buff *skb) |
371 | { | 370 | { |
372 | unsigned char *b = skb->tail; | 371 | struct tc_prio_qopt opt = { .bands = PFIFO_FAST_BANDS }; |
373 | struct tc_prio_qopt opt; | ||
374 | 372 | ||
375 | opt.bands = 3; | ||
376 | memcpy(&opt.priomap, prio2band, TC_PRIO_MAX+1); | 373 | memcpy(&opt.priomap, prio2band, TC_PRIO_MAX+1); |
377 | RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt); | 374 | RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt); |
378 | return skb->len; | 375 | return skb->len; |
379 | 376 | ||
380 | rtattr_failure: | 377 | rtattr_failure: |
381 | skb_trim(skb, b - skb->data); | ||
382 | return -1; | 378 | return -1; |
383 | } | 379 | } |
384 | 380 | ||
385 | static int pfifo_fast_init(struct Qdisc *qdisc, struct rtattr *opt) | 381 | static int pfifo_fast_init(struct Qdisc *qdisc, struct rtattr *opt) |
386 | { | 382 | { |
387 | int i; | 383 | int prio; |
388 | struct sk_buff_head *list = qdisc_priv(qdisc); | 384 | struct sk_buff_head *list = qdisc_priv(qdisc); |
389 | 385 | ||
390 | for (i=0; i<3; i++) | 386 | for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) |
391 | skb_queue_head_init(list+i); | 387 | skb_queue_head_init(list + prio); |
392 | 388 | ||
393 | return 0; | 389 | return 0; |
394 | } | 390 | } |
395 | 391 | ||
396 | static struct Qdisc_ops pfifo_fast_ops = { | 392 | static struct Qdisc_ops pfifo_fast_ops = { |
397 | .next = NULL, | ||
398 | .cl_ops = NULL, | ||
399 | .id = "pfifo_fast", | 393 | .id = "pfifo_fast", |
400 | .priv_size = 3 * sizeof(struct sk_buff_head), | 394 | .priv_size = PFIFO_FAST_BANDS * sizeof(struct sk_buff_head), |
401 | .enqueue = pfifo_fast_enqueue, | 395 | .enqueue = pfifo_fast_enqueue, |
402 | .dequeue = pfifo_fast_dequeue, | 396 | .dequeue = pfifo_fast_dequeue, |
403 | .requeue = pfifo_fast_requeue, | 397 | .requeue = pfifo_fast_requeue, |