Commit d5d75cd6 authored by Stephen Hemminger's avatar Stephen Hemminger Committed by David S. Miller

[PKT_SCHED]: netetm: adjust parent qlen when duplicating

Fix qlen underrun when doing duplication with netem. If netem is used
as leaf discipline, then the parent needs to be tweaked when packets
are duplicated.
Signed-off-by: default avatarStephen Hemminger <shemminger@osdl.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 771018e7
...@@ -1289,6 +1289,7 @@ static int __init pktsched_init(void) ...@@ -1289,6 +1289,7 @@ static int __init pktsched_init(void)
subsys_initcall(pktsched_init); subsys_initcall(pktsched_init);
EXPORT_SYMBOL(qdisc_lookup);
EXPORT_SYMBOL(qdisc_get_rtab); EXPORT_SYMBOL(qdisc_get_rtab);
EXPORT_SYMBOL(qdisc_put_rtab); EXPORT_SYMBOL(qdisc_put_rtab);
EXPORT_SYMBOL(register_qdisc); EXPORT_SYMBOL(register_qdisc);
......
...@@ -206,7 +206,6 @@ static int netem_run(struct Qdisc *sch) ...@@ -206,7 +206,6 @@ static int netem_run(struct Qdisc *sch)
static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
{ {
struct netem_sched_data *q = qdisc_priv(sch); struct netem_sched_data *q = qdisc_priv(sch);
struct sk_buff *skb2;
int ret; int ret;
pr_debug("netem_enqueue skb=%p\n", skb); pr_debug("netem_enqueue skb=%p\n", skb);
...@@ -220,11 +219,21 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) ...@@ -220,11 +219,21 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
} }
/* Random duplication */ /* Random duplication */
if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor) if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor)) {
&& (skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) { struct sk_buff *skb2;
pr_debug("netem_enqueue: dup %p\n", skb2);
skb2 = skb_clone(skb, GFP_ATOMIC);
if (skb2 && netem_delay(sch, skb2) == NET_XMIT_SUCCESS) {
struct Qdisc *qp;
/* Since one packet can generate two packets in the
* queue, the parent's qlen accounting gets confused,
* so fix it.
*/
qp = qdisc_lookup(sch->dev, TC_H_MAJ(sch->parent));
if (qp)
qp->q.qlen++;
if (netem_delay(sch, skb2)) {
sch->q.qlen++; sch->q.qlen++;
sch->bstats.bytes += skb2->len; sch->bstats.bytes += skb2->len;
sch->bstats.packets++; sch->bstats.packets++;
...@@ -253,6 +262,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) ...@@ -253,6 +262,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
} else } else
sch->qstats.drops++; sch->qstats.drops++;
pr_debug("netem: enqueue ret %d\n", ret);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment