Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 94de78d1 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

[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: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7d2681a6
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -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.
 *
 *
+40 −1
Original line number Original line Diff line number Diff line
@@ -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)
{
{
	struct sfq_sched_data *q = qdisc_priv(sch);
	unsigned int i;

	if (arg->stop)
		return;
		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,
};
};