|
@@ -559,50 +559,44 @@ static int gred_init(struct Qdisc *sch, struct rtattr *opt)
|
|
|
|
|
|
static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)
|
|
static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)
|
|
{
|
|
{
|
|
- unsigned long qave;
|
|
|
|
- struct rtattr *rta;
|
|
|
|
- struct tc_gred_qopt *opt = NULL ;
|
|
|
|
- struct tc_gred_qopt *dst;
|
|
|
|
struct gred_sched *table = qdisc_priv(sch);
|
|
struct gred_sched *table = qdisc_priv(sch);
|
|
- struct gred_sched_data *q;
|
|
|
|
|
|
+ struct rtattr *parms, *opts = NULL;
|
|
int i;
|
|
int i;
|
|
- unsigned char *b = skb->tail;
|
|
|
|
-
|
|
|
|
- rta = (struct rtattr*)b;
|
|
|
|
- RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
|
|
|
|
|
|
|
|
- opt=kmalloc(sizeof(struct tc_gred_qopt)*MAX_DPs, GFP_KERNEL);
|
|
|
|
-
|
|
|
|
- if (opt == NULL) {
|
|
|
|
- DPRINTK("gred_dump:failed to malloc for %Zd\n",
|
|
|
|
- sizeof(struct tc_gred_qopt)*MAX_DPs);
|
|
|
|
- goto rtattr_failure;
|
|
|
|
- }
|
|
|
|
|
|
+ opts = RTA_NEST(skb, TCA_OPTIONS);
|
|
|
|
+ parms = RTA_NEST(skb, TCA_GRED_PARMS);
|
|
|
|
|
|
- memset(opt, 0, (sizeof(struct tc_gred_qopt))*table->DPs);
|
|
|
|
-
|
|
|
|
- if (!table->initd) {
|
|
|
|
- DPRINTK("NO GRED Queues setup!\n");
|
|
|
|
- }
|
|
|
|
|
|
+ for (i = 0; i < MAX_DPs; i++) {
|
|
|
|
+ struct gred_sched_data *q = table->tab[i];
|
|
|
|
+ struct tc_gred_qopt opt;
|
|
|
|
|
|
- for (i=0;i<MAX_DPs;i++) {
|
|
|
|
- dst= &opt[i];
|
|
|
|
- q= table->tab[i];
|
|
|
|
|
|
+ memset(&opt, 0, sizeof(opt));
|
|
|
|
|
|
if (!q) {
|
|
if (!q) {
|
|
/* hack -- fix at some point with proper message
|
|
/* hack -- fix at some point with proper message
|
|
This is how we indicate to tc that there is no VQ
|
|
This is how we indicate to tc that there is no VQ
|
|
at this DP */
|
|
at this DP */
|
|
|
|
|
|
- dst->DP=MAX_DPs+i;
|
|
|
|
- continue;
|
|
|
|
|
|
+ opt.DP = MAX_DPs + i;
|
|
|
|
+ goto append_opt;
|
|
}
|
|
}
|
|
|
|
|
|
- dst->limit=q->limit;
|
|
|
|
- dst->qth_min=q->qth_min>>q->Wlog;
|
|
|
|
- dst->qth_max=q->qth_max>>q->Wlog;
|
|
|
|
- dst->DP=q->DP;
|
|
|
|
- dst->backlog=q->backlog;
|
|
|
|
|
|
+ opt.limit = q->limit;
|
|
|
|
+ opt.DP = q->DP;
|
|
|
|
+ opt.backlog = q->backlog;
|
|
|
|
+ opt.prio = q->prio;
|
|
|
|
+ opt.qth_min = q->qth_min >> q->Wlog;
|
|
|
|
+ opt.qth_max = q->qth_max >> q->Wlog;
|
|
|
|
+ opt.Wlog = q->Wlog;
|
|
|
|
+ opt.Plog = q->Plog;
|
|
|
|
+ opt.Scell_log = q->Scell_log;
|
|
|
|
+ opt.other = q->other;
|
|
|
|
+ opt.early = q->early;
|
|
|
|
+ opt.forced = q->forced;
|
|
|
|
+ opt.pdrop = q->pdrop;
|
|
|
|
+ opt.packets = q->packetsin;
|
|
|
|
+ opt.bytesin = q->bytesin;
|
|
|
|
+
|
|
if (q->qave) {
|
|
if (q->qave) {
|
|
if (gred_wred_mode(table)) {
|
|
if (gred_wred_mode(table)) {
|
|
q->qidlestart=table->tab[table->def]->qidlestart;
|
|
q->qidlestart=table->tab[table->def]->qidlestart;
|
|
@@ -610,46 +604,28 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)
|
|
}
|
|
}
|
|
if (!PSCHED_IS_PASTPERFECT(q->qidlestart)) {
|
|
if (!PSCHED_IS_PASTPERFECT(q->qidlestart)) {
|
|
long idle;
|
|
long idle;
|
|
|
|
+ unsigned long qave;
|
|
psched_time_t now;
|
|
psched_time_t now;
|
|
PSCHED_GET_TIME(now);
|
|
PSCHED_GET_TIME(now);
|
|
idle = PSCHED_TDIFF_SAFE(now, q->qidlestart, q->Scell_max);
|
|
idle = PSCHED_TDIFF_SAFE(now, q->qidlestart, q->Scell_max);
|
|
qave = q->qave >> q->Stab[(idle>>q->Scell_log)&0xFF];
|
|
qave = q->qave >> q->Stab[(idle>>q->Scell_log)&0xFF];
|
|
- dst->qave = qave >> q->Wlog;
|
|
|
|
|
|
+ opt.qave = qave >> q->Wlog;
|
|
|
|
|
|
} else {
|
|
} else {
|
|
- dst->qave = q->qave >> q->Wlog;
|
|
|
|
|
|
+ opt.qave = q->qave >> q->Wlog;
|
|
}
|
|
}
|
|
- } else {
|
|
|
|
- dst->qave = 0;
|
|
|
|
}
|
|
}
|
|
-
|
|
|
|
-
|
|
|
|
- dst->Wlog = q->Wlog;
|
|
|
|
- dst->Plog = q->Plog;
|
|
|
|
- dst->Scell_log = q->Scell_log;
|
|
|
|
- dst->other = q->other;
|
|
|
|
- dst->forced = q->forced;
|
|
|
|
- dst->early = q->early;
|
|
|
|
- dst->pdrop = q->pdrop;
|
|
|
|
- dst->prio = q->prio;
|
|
|
|
- dst->packets=q->packetsin;
|
|
|
|
- dst->bytesin=q->bytesin;
|
|
|
|
|
|
+
|
|
|
|
+append_opt:
|
|
|
|
+ RTA_APPEND(skb, sizeof(opt), &opt);
|
|
}
|
|
}
|
|
|
|
|
|
- RTA_PUT(skb, TCA_GRED_PARMS, sizeof(struct tc_gred_qopt)*MAX_DPs, opt);
|
|
|
|
- rta->rta_len = skb->tail - b;
|
|
|
|
|
|
+ RTA_NEST_END(skb, parms);
|
|
|
|
|
|
- kfree(opt);
|
|
|
|
- return skb->len;
|
|
|
|
|
|
+ return RTA_NEST_END(skb, opts);
|
|
|
|
|
|
rtattr_failure:
|
|
rtattr_failure:
|
|
- if (opt)
|
|
|
|
- kfree(opt);
|
|
|
|
- DPRINTK("gred_dump: FAILURE!!!!\n");
|
|
|
|
-
|
|
|
|
-/* also free the opt struct here */
|
|
|
|
- skb_trim(skb, b - skb->data);
|
|
|
|
- return -1;
|
|
|
|
|
|
+ return RTA_NEST_CANCEL(skb, opts);
|
|
}
|
|
}
|
|
|
|
|
|
static void gred_destroy(struct Qdisc *sch)
|
|
static void gred_destroy(struct Qdisc *sch)
|