diff options
Diffstat (limited to 'net/sched')
| -rw-r--r-- | net/sched/sch_cbq.c | 5 | ||||
| -rw-r--r-- | net/sched/sch_fq_codel.c | 2 | ||||
| -rw-r--r-- | net/sched/sch_gred.c | 38 | ||||
| -rw-r--r-- | net/sched/sch_qfq.c | 5 | 
4 files changed, 30 insertions, 20 deletions
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index 6aabd77d1cf..564b9fc8efd 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -250,10 +250,11 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)  			else if ((cl = defmap[res.classid & TC_PRIO_MAX]) == NULL)  				cl = defmap[TC_PRIO_BESTEFFORT]; -			if (cl == NULL || cl->level >= head->level) +			if (cl == NULL)  				goto fallback;  		} - +		if (cl->level >= head->level) +			goto fallback;  #ifdef CONFIG_NET_CLS_ACT  		switch (result) {  		case TC_ACT_QUEUED: diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c index 9fc1c62ec80..4e606fcb253 100644 --- a/net/sched/sch_fq_codel.c +++ b/net/sched/sch_fq_codel.c @@ -191,7 +191,6 @@ static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch)  	if (list_empty(&flow->flowchain)) {  		list_add_tail(&flow->flowchain, &q->new_flows); -		codel_vars_init(&flow->cvars);  		q->new_flow_count++;  		flow->deficit = q->quantum;  		flow->dropped = 0; @@ -418,6 +417,7 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt)  			struct fq_codel_flow *flow = q->flows + i;  			INIT_LIST_HEAD(&flow->flowchain); +			codel_vars_init(&flow->cvars);  		}  	}  	if (sch->limit >= 1) diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index e901583e4ea..d42234c0f13 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c @@ -102,9 +102,8 @@ static inline int gred_wred_mode_check(struct Qdisc *sch)  		if (q == NULL)  			continue; -		for (n = 0; n < table->DPs; n++) -			if (table->tab[n] && table->tab[n] != q && -			    table->tab[n]->prio == q->prio) +		for (n = i + 1; n < table->DPs; n++) +			if (table->tab[n] && table->tab[n]->prio == q->prio)  				return 1;  	} @@ -137,6 +136,7 @@ static inline void gred_store_wred_set(struct gred_sched *table,  				       struct gred_sched_data *q)  {  	table->wred_set.qavg = q->vars.qavg; +	table->wred_set.qidlestart = q->vars.qidlestart;  }  static inline int gred_use_ecn(struct gred_sched *t) @@ -176,7 +176,7 @@ static int gred_enqueue(struct sk_buff *skb, struct Qdisc *sch)  		skb->tc_index = (skb->tc_index & ~GRED_VQ_MASK) | dp;  	} -	/* sum up all the qaves of prios <= to ours to get the new qave */ +	/* sum up all the qaves of prios < ours to get the new qave */  	if (!gred_wred_mode(t) && gred_rio_mode(t)) {  		int i; @@ -260,16 +260,18 @@ static struct sk_buff *gred_dequeue(struct Qdisc *sch)  		} else {  			q->backlog -= qdisc_pkt_len(skb); -			if (!q->backlog && !gred_wred_mode(t)) -				red_start_of_idle_period(&q->vars); +			if (gred_wred_mode(t)) { +				if (!sch->qstats.backlog) +					red_start_of_idle_period(&t->wred_set); +			} else { +				if (!q->backlog) +					red_start_of_idle_period(&q->vars); +			}  		}  		return skb;  	} -	if (gred_wred_mode(t) && !red_is_idling(&t->wred_set)) -		red_start_of_idle_period(&t->wred_set); -  	return NULL;  } @@ -291,19 +293,20 @@ static unsigned int gred_drop(struct Qdisc *sch)  			q->backlog -= len;  			q->stats.other++; -			if (!q->backlog && !gred_wred_mode(t)) -				red_start_of_idle_period(&q->vars); +			if (gred_wred_mode(t)) { +				if (!sch->qstats.backlog) +					red_start_of_idle_period(&t->wred_set); +			} else { +				if (!q->backlog) +					red_start_of_idle_period(&q->vars); +			}  		}  		qdisc_drop(skb, sch);  		return len;  	} -	if (gred_wred_mode(t) && !red_is_idling(&t->wred_set)) -		red_start_of_idle_period(&t->wred_set); -  	return 0; -  }  static void gred_reset(struct Qdisc *sch) @@ -535,6 +538,7 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)  	for (i = 0; i < MAX_DPs; i++) {  		struct gred_sched_data *q = table->tab[i];  		struct tc_gred_qopt opt; +		unsigned long qavg;  		memset(&opt, 0, sizeof(opt)); @@ -566,7 +570,9 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)  		if (gred_wred_mode(table))  			gred_load_wred_set(table, q); -		opt.qave = red_calc_qavg(&q->parms, &q->vars, q->vars.qavg); +		qavg = red_calc_qavg(&q->parms, &q->vars, +				     q->vars.qavg >> q->parms.Wlog); +		opt.qave = qavg >> q->parms.Wlog;  append_opt:  		if (nla_append(skb, sizeof(opt), &opt) < 0) diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index e4723d31fdd..211a2121704 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c @@ -865,7 +865,10 @@ static void qfq_update_start(struct qfq_sched *q, struct qfq_class *cl)  		if (mask) {  			struct qfq_group *next = qfq_ffs(q, mask);  			if (qfq_gt(roundedF, next->F)) { -				cl->S = next->F; +				if (qfq_gt(limit, next->F)) +					cl->S = next->F; +				else /* preserve timestamp correctness */ +					cl->S = limit;  				return;  			}  		}  |