summaryrefslogtreecommitdiffstats
path: root/net/sched/sch_sfq.c
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-02-01 03:37:16 +0100
committerDavid S. Miller <davem@davemloft.net>2008-02-01 04:28:35 +0100
commit94de78d19580143c407ff2492edf2410d0e7d48c (patch)
tree2753a5638e500101ec286fd5a02f042b4a1da129 /net/sched/sch_sfq.c
parent[NET_SCHED]: sch_sfq: add support for external classifiers (diff)
downloadlinux-94de78d19580143c407ff2492edf2410d0e7d48c.tar.xz
linux-94de78d19580143c407ff2492edf2410d0e7d48c.zip
[NET_SCHED]: sch_sfq: make internal queues visible as classes
Add support for dumping statistics and make internal queues visible as classes. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched/sch_sfq.c')
-rw-r--r--net/sched/sch_sfq.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index d818d1985cca..a20e2ef7704b 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -566,15 +566,54 @@ static struct tcf_proto **sfq_find_tcf(struct Qdisc *sch, unsigned long cl)
return &q->filter_list;
}
+static int sfq_dump_class(struct Qdisc *sch, unsigned long cl,
+ struct sk_buff *skb, struct tcmsg *tcm)
+{
+ tcm->tcm_handle |= TC_H_MIN(cl);
+ return 0;
+}
+
+static int sfq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
+ struct gnet_dump *d)
+{
+ struct sfq_sched_data *q = qdisc_priv(sch);
+ sfq_index idx = q->ht[cl-1];
+ struct gnet_stats_queue qs = { .qlen = q->qs[idx].qlen };
+ struct tc_sfq_xstats xstats = { .allot = q->allot[idx] };
+
+ if (gnet_stats_copy_queue(d, &qs) < 0)
+ return -1;
+ return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
+}
+
static void sfq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
{
- return;
+ struct sfq_sched_data *q = qdisc_priv(sch);
+ unsigned int i;
+
+ if (arg->stop)
+ return;
+
+ for (i = 0; i < SFQ_HASH_DIVISOR; i++) {
+ if (q->ht[i] == SFQ_DEPTH ||
+ arg->count < arg->skip) {
+ arg->count++;
+ continue;
+ }
+ if (arg->fn(sch, i + 1, arg) < 0) {
+ arg->stop = 1;
+ break;
+ }
+ arg->count++;
+ }
}
static const struct Qdisc_class_ops sfq_class_ops = {
.get = sfq_get,
.change = sfq_change_class,
.tcf_chain = sfq_find_tcf,
+ .dump = sfq_dump_class,
+ .dump_stats = sfq_dump_class_stats,
.walk = sfq_walk,
};