[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>
This commit is contained in:
parent
7d2681a6ff
commit
94de78d195
|
@ -150,6 +150,11 @@ struct tc_sfq_qopt
|
||||||
unsigned flows; /* Maximal number of flows */
|
unsigned flows; /* Maximal number of flows */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct tc_sfq_xstats
|
||||||
|
{
|
||||||
|
__s32 allot;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE: limit, divisor and flows are hardwired to code at the moment.
|
* NOTE: limit, divisor and flows are hardwired to code at the moment.
|
||||||
*
|
*
|
||||||
|
|
|
@ -566,15 +566,54 @@ static struct tcf_proto **sfq_find_tcf(struct Qdisc *sch, unsigned long cl)
|
||||||
return &q->filter_list;
|
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)
|
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 = {
|
static const struct Qdisc_class_ops sfq_class_ops = {
|
||||||
.get = sfq_get,
|
.get = sfq_get,
|
||||||
.change = sfq_change_class,
|
.change = sfq_change_class,
|
||||||
.tcf_chain = sfq_find_tcf,
|
.tcf_chain = sfq_find_tcf,
|
||||||
|
.dump = sfq_dump_class,
|
||||||
|
.dump_stats = sfq_dump_class_stats,
|
||||||
.walk = sfq_walk,
|
.walk = sfq_walk,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue