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

Commit 64015853 authored by John Fastabend's avatar John Fastabend Committed by David S. Miller
Browse files

net: sched: restrict use of qstats qlen



This removes the use of qstats->qlen variable from the classifiers
and makes it an explicit argument to gnet_stats_copy_queue().

The qlen represents the qdisc queue length and is packed into
the qstats at the last moment before passnig to user space. By
handling it explicitely we avoid, in the percpu stats case, having
to figure out which per_cpu variable to put it in.

It would probably be best to remove it from qstats completely
but qstats is a user space ABI and can't be broken. A future
patch could make an internal only qstats structure that would
avoid having to allocate an additional u32 variable on the
Qdisc struct. This would make the qstats struct 128bits instead
of 128+32.

Signed-off-by: default avatarJohn Fastabend <john.r.fastabend@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 25331d6c
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -40,7 +40,8 @@ void __gnet_stats_copy_basic(struct gnet_stats_basic_packed *bstats,
int gnet_stats_copy_rate_est(struct gnet_dump *d,
int gnet_stats_copy_rate_est(struct gnet_dump *d,
			     const struct gnet_stats_basic_packed *b,
			     const struct gnet_stats_basic_packed *b,
			     struct gnet_stats_rate_est64 *r);
			     struct gnet_stats_rate_est64 *r);
int gnet_stats_copy_queue(struct gnet_dump *d, struct gnet_stats_queue *q);
int gnet_stats_copy_queue(struct gnet_dump *d,
			  struct gnet_stats_queue *q, __u32 len);
int gnet_stats_copy_app(struct gnet_dump *d, void *st, int len);
int gnet_stats_copy_app(struct gnet_dump *d, void *st, int len);


int gnet_stats_finish_copy(struct gnet_dump *d);
int gnet_stats_finish_copy(struct gnet_dump *d);
+5 −1
Original line number Original line Diff line number Diff line
@@ -219,6 +219,7 @@ EXPORT_SYMBOL(gnet_stats_copy_rate_est);
 * gnet_stats_copy_queue - copy queue statistics into statistics TLV
 * gnet_stats_copy_queue - copy queue statistics into statistics TLV
 * @d: dumping handle
 * @d: dumping handle
 * @q: queue statistics
 * @q: queue statistics
 * @qlen: queue length statistics
 *
 *
 * Appends the queue statistics to the top level TLV created by
 * Appends the queue statistics to the top level TLV created by
 * gnet_stats_start_copy().
 * gnet_stats_start_copy().
@@ -227,8 +228,11 @@ EXPORT_SYMBOL(gnet_stats_copy_rate_est);
 * if the room in the socket buffer was not sufficient.
 * if the room in the socket buffer was not sufficient.
 */
 */
int
int
gnet_stats_copy_queue(struct gnet_dump *d, struct gnet_stats_queue *q)
gnet_stats_copy_queue(struct gnet_dump *d,
		      struct gnet_stats_queue *q, __u32 qlen)
{
{
	q->qlen = qlen;

	if (d->compat_tc_stats) {
	if (d->compat_tc_stats) {
		d->tc_stats.drops = q->drops;
		d->tc_stats.drops = q->drops;
		d->tc_stats.qlen = q->qlen;
		d->tc_stats.qlen = q->qlen;
+3 −1
Original line number Original line Diff line number Diff line
@@ -623,7 +623,9 @@ int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a,
	if (gnet_stats_copy_basic(&d, NULL, &p->tcfc_bstats) < 0 ||
	if (gnet_stats_copy_basic(&d, NULL, &p->tcfc_bstats) < 0 ||
	    gnet_stats_copy_rate_est(&d, &p->tcfc_bstats,
	    gnet_stats_copy_rate_est(&d, &p->tcfc_bstats,
				     &p->tcfc_rate_est) < 0 ||
				     &p->tcfc_rate_est) < 0 ||
	    gnet_stats_copy_queue(&d, &p->tcfc_qstats) < 0)
	    gnet_stats_copy_queue(&d,
				  &p->tcfc_qstats,
				  p->tcfc_qstats.qlen) < 0)
		goto errout;
		goto errout;


	if (gnet_stats_finish_copy(&d) < 0)
	if (gnet_stats_finish_copy(&d) < 0)
+3 −2
Original line number Original line Diff line number Diff line
@@ -1318,6 +1318,7 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
	unsigned char *b = skb_tail_pointer(skb);
	unsigned char *b = skb_tail_pointer(skb);
	struct gnet_dump d;
	struct gnet_dump d;
	struct qdisc_size_table *stab;
	struct qdisc_size_table *stab;
	__u32 qlen;


	cond_resched();
	cond_resched();
	nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags);
	nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags);
@@ -1335,7 +1336,7 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
		goto nla_put_failure;
		goto nla_put_failure;
	if (q->ops->dump && q->ops->dump(q, skb) < 0)
	if (q->ops->dump && q->ops->dump(q, skb) < 0)
		goto nla_put_failure;
		goto nla_put_failure;
	q->qstats.qlen = q->q.qlen;
	qlen = q->q.qlen;


	stab = rtnl_dereference(q->stab);
	stab = rtnl_dereference(q->stab);
	if (stab && qdisc_dump_stab(skb, stab) < 0)
	if (stab && qdisc_dump_stab(skb, stab) < 0)
@@ -1353,7 +1354,7 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,


	if (gnet_stats_copy_basic(&d, cpu_bstats, &q->bstats) < 0 ||
	if (gnet_stats_copy_basic(&d, cpu_bstats, &q->bstats) < 0 ||
	    gnet_stats_copy_rate_est(&d, &q->bstats, &q->rate_est) < 0 ||
	    gnet_stats_copy_rate_est(&d, &q->bstats, &q->rate_est) < 0 ||
	    gnet_stats_copy_queue(&d, &q->qstats) < 0)
	    gnet_stats_copy_queue(&d, &q->qstats, qlen) < 0)
		goto nla_put_failure;
		goto nla_put_failure;


	if (gnet_stats_finish_copy(&d) < 0)
	if (gnet_stats_finish_copy(&d) < 0)
+1 −3
Original line number Original line Diff line number Diff line
@@ -637,10 +637,8 @@ atm_tc_dump_class_stats(struct Qdisc *sch, unsigned long arg,
{
{
	struct atm_flow_data *flow = (struct atm_flow_data *)arg;
	struct atm_flow_data *flow = (struct atm_flow_data *)arg;


	flow->qstats.qlen = flow->q->q.qlen;

	if (gnet_stats_copy_basic(d, NULL, &flow->bstats) < 0 ||
	if (gnet_stats_copy_basic(d, NULL, &flow->bstats) < 0 ||
	    gnet_stats_copy_queue(d, &flow->qstats) < 0)
	    gnet_stats_copy_queue(d, &flow->qstats, flow->q->q.qlen) < 0)
		return -1;
		return -1;


	return 0;
	return 0;
Loading