瀏覽代碼

[PKT_SCHED]: GRED: Cleanup dumping

Avoids the allocation of a buffer by appending the VQs directly
to the skb and simplifies the code by using the appropriate
message construction macros.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Thomas Graf 19 年之前
父節點
當前提交
05f1cc01b4
共有 1 個文件被更改,包括 34 次插入58 次删除
  1. 34 58
      net/sched/sch_gred.c

+ 34 - 58
net/sched/sch_gred.c

@@ -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)