|
@@ -700,8 +700,13 @@ cbq_update(struct cbq_sched_data *q)
|
|
struct cbq_class *this = q->tx_class;
|
|
struct cbq_class *this = q->tx_class;
|
|
struct cbq_class *cl = this;
|
|
struct cbq_class *cl = this;
|
|
int len = q->tx_len;
|
|
int len = q->tx_len;
|
|
|
|
+ psched_time_t now;
|
|
|
|
|
|
q->tx_class = NULL;
|
|
q->tx_class = NULL;
|
|
|
|
+ /* Time integrator. We calculate EOS time
|
|
|
|
+ * by adding expected packet transmission time.
|
|
|
|
+ */
|
|
|
|
+ now = q->now + L2T(&q->link, len);
|
|
|
|
|
|
for ( ; cl; cl = cl->share) {
|
|
for ( ; cl; cl = cl->share) {
|
|
long avgidle = cl->avgidle;
|
|
long avgidle = cl->avgidle;
|
|
@@ -717,7 +722,7 @@ cbq_update(struct cbq_sched_data *q)
|
|
* idle = (now - last) - last_pktlen/rate
|
|
* idle = (now - last) - last_pktlen/rate
|
|
*/
|
|
*/
|
|
|
|
|
|
- idle = q->now - cl->last;
|
|
|
|
|
|
+ idle = now - cl->last;
|
|
if ((unsigned long)idle > 128*1024*1024) {
|
|
if ((unsigned long)idle > 128*1024*1024) {
|
|
avgidle = cl->maxidle;
|
|
avgidle = cl->maxidle;
|
|
} else {
|
|
} else {
|
|
@@ -761,7 +766,7 @@ cbq_update(struct cbq_sched_data *q)
|
|
idle -= L2T(&q->link, len);
|
|
idle -= L2T(&q->link, len);
|
|
idle += L2T(cl, len);
|
|
idle += L2T(cl, len);
|
|
|
|
|
|
- cl->undertime = q->now + idle;
|
|
|
|
|
|
+ cl->undertime = now + idle;
|
|
} else {
|
|
} else {
|
|
/* Underlimit */
|
|
/* Underlimit */
|
|
|
|
|
|
@@ -771,7 +776,8 @@ cbq_update(struct cbq_sched_data *q)
|
|
else
|
|
else
|
|
cl->avgidle = avgidle;
|
|
cl->avgidle = avgidle;
|
|
}
|
|
}
|
|
- cl->last = q->now;
|
|
|
|
|
|
+ if ((s64)(now - cl->last) > 0)
|
|
|
|
+ cl->last = now;
|
|
}
|
|
}
|
|
|
|
|
|
cbq_update_toplevel(q, this, q->tx_borrowed);
|
|
cbq_update_toplevel(q, this, q->tx_borrowed);
|
|
@@ -943,30 +949,13 @@ cbq_dequeue(struct Qdisc *sch)
|
|
struct sk_buff *skb;
|
|
struct sk_buff *skb;
|
|
struct cbq_sched_data *q = qdisc_priv(sch);
|
|
struct cbq_sched_data *q = qdisc_priv(sch);
|
|
psched_time_t now;
|
|
psched_time_t now;
|
|
- psched_tdiff_t incr;
|
|
|
|
|
|
|
|
now = psched_get_time();
|
|
now = psched_get_time();
|
|
- incr = now - q->now_rt;
|
|
|
|
-
|
|
|
|
- if (q->tx_class) {
|
|
|
|
- psched_tdiff_t incr2;
|
|
|
|
- /* Time integrator. We calculate EOS time
|
|
|
|
- * by adding expected packet transmission time.
|
|
|
|
- * If real time is greater, we warp artificial clock,
|
|
|
|
- * so that:
|
|
|
|
- *
|
|
|
|
- * cbq_time = max(real_time, work);
|
|
|
|
- */
|
|
|
|
- incr2 = L2T(&q->link, q->tx_len);
|
|
|
|
- q->now += incr2;
|
|
|
|
|
|
+
|
|
|
|
+ if (q->tx_class)
|
|
cbq_update(q);
|
|
cbq_update(q);
|
|
- if ((incr -= incr2) < 0)
|
|
|
|
- incr = 0;
|
|
|
|
- q->now += incr;
|
|
|
|
- } else {
|
|
|
|
- if (now > q->now)
|
|
|
|
- q->now = now;
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ q->now = now;
|
|
q->now_rt = now;
|
|
q->now_rt = now;
|
|
|
|
|
|
for (;;) {
|
|
for (;;) {
|