Ejemplo n.º 1
0
/**
 * gnet_stats_copy_rate_est - copy rate estimator statistics into statistics TLV
 * @d: dumping handle
 * @b: basic statistics
 * @r: rate estimator statistics
 *
 * Appends the rate estimator statistics to the top level TLV created by
 * gnet_stats_start_copy().
 *
 * Returns 0 on success or -1 with the statistic lock released
 * if the room in the socket buffer was not sufficient.
 */
int
gnet_stats_copy_rate_est(struct gnet_dump *d,
                         const struct gnet_stats_basic_packed *b,
                         struct gnet_stats_rate_est64 *r)
{
    struct gnet_stats_rate_est est;
    int res;

    if (b && !gen_estimator_active(b, r))
        return 0;

    est.bps = min_t(u64, UINT_MAX, r->bps);
    /* we have some time before reaching 2^32 packets per second */
    est.pps = r->pps;

    if (d->compat_tc_stats) {
        d->tc_stats.bps = est.bps;
        d->tc_stats.pps = est.pps;
    }

    if (d->tail) {
        res = gnet_stats_copy(d, TCA_STATS_RATE_EST, &est, sizeof(est));
        if (res < 0 || est.bps == r->bps)
            return res;
        /* emit 64bit stats only if needed */
        return gnet_stats_copy(d, TCA_STATS_RATE_EST64, r, sizeof(*r));
    }

    return 0;
}
Ejemplo n.º 2
0
/**
 * gnet_stats_copy_rate_est - copy rate estimator statistics into statistics TLV
 * @d: dumping handle
 * @rate_est: rate estimator
 *
 * Appends the rate estimator statistics to the top level TLV created by
 * gnet_stats_start_copy().
 *
 * Returns 0 on success or -1 with the statistic lock released
 * if the room in the socket buffer was not sufficient.
 */
int
gnet_stats_copy_rate_est(struct gnet_dump *d,
			 struct net_rate_estimator __rcu **rate_est)
{
	struct gnet_stats_rate_est64 sample;
	struct gnet_stats_rate_est est;
	int res;

	if (!gen_estimator_read(rate_est, &sample))
		return 0;
	est.bps = min_t(u64, UINT_MAX, sample.bps);
	/* we have some time before reaching 2^32 packets per second */
	est.pps = sample.pps;

	if (d->compat_tc_stats) {
		d->tc_stats.bps = est.bps;
		d->tc_stats.pps = est.pps;
	}

	if (d->tail) {
		res = gnet_stats_copy(d, TCA_STATS_RATE_EST, &est, sizeof(est),
				      TCA_STATS_PAD);
		if (res < 0 || est.bps == sample.bps)
			return res;
		/* emit 64bit stats only if needed */
		return gnet_stats_copy(d, TCA_STATS_RATE_EST64, &sample,
				       sizeof(sample), TCA_STATS_PAD);
	}

	return 0;
}
Ejemplo n.º 3
0
/**
 * gnet_stats_copy_app - copy application specific statistics into statistics TLV
 * @d: dumping handle
 * @st: application specific statistics data
 * @len: length of data
 *
 * Appends the application sepecific statistics to the top level TLV created by
 * gnet_stats_start_copy() and remembers the data for XSTATS if the dumping
 * handle is in backward compatibility mode.
 *
 * Returns 0 on success or -1 with the statistic lock released
 * if the room in the socket buffer was not sufficient.
 */
int
gnet_stats_copy_app(struct gnet_dump *d, void *st, int len)
{
	if (d->compat_xstats)
		d->xstats = (struct rtattr *) d->skb->tail;
	return gnet_stats_copy(d, TCA_STATS_APP, st, len);
}
Ejemplo n.º 4
0
/**
 * gnet_stats_copy_basic - copy basic statistics into statistic TLV
 * @running: seqcount_t pointer
 * @d: dumping handle
 * @cpu: copy statistic per cpu
 * @b: basic statistics
 *
 * Appends the basic statistics to the top level TLV created by
 * gnet_stats_start_copy().
 *
 * Returns 0 on success or -1 with the statistic lock released
 * if the room in the socket buffer was not sufficient.
 */
int
gnet_stats_copy_basic(const seqcount_t *running,
		      struct gnet_dump *d,
		      struct gnet_stats_basic_cpu __percpu *cpu,
		      struct gnet_stats_basic_packed *b)
{
	struct gnet_stats_basic_packed bstats = {0};

	__gnet_stats_copy_basic(running, &bstats, cpu, b);

	if (d->compat_tc_stats) {
		d->tc_stats.bytes = bstats.bytes;
		d->tc_stats.packets = bstats.packets;
	}

	if (d->tail) {
		struct gnet_stats_basic sb;

		memset(&sb, 0, sizeof(sb));
		sb.bytes = bstats.bytes;
		sb.packets = bstats.packets;
		return gnet_stats_copy(d, TCA_STATS_BASIC, &sb, sizeof(sb),
				       TCA_STATS_PAD);
	}
	return 0;
}
Ejemplo n.º 5
0
/**
 * gnet_stats_finish_copy - finish dumping procedure
 * @d: dumping handle
 *
 * Corrects the length of the top level TLV to include all TLVs added
 * by gnet_stats_copy_XXX() calls. Adds the backward compatibility TLVs
 * if gnet_stats_start_copy_compat() was used and releases the statistics
 * lock.
 *
 * Returns 0 on success or -1 with the statistic lock released
 * if the room in the socket buffer was not sufficient.
 */
int
gnet_stats_finish_copy(struct gnet_dump *d)
{
	d->tail->rta_len = d->skb->tail - (u8 *) d->tail;

	if (d->compat_tc_stats)
		if (gnet_stats_copy(d, d->compat_tc_stats, &d->tc_stats,
			sizeof(d->tc_stats)) < 0)
			return -1;

	if (d->compat_xstats && d->xstats) {
		if (gnet_stats_copy(d, d->compat_xstats, RTA_DATA(d->xstats),
			RTA_PAYLOAD(d->xstats)) < 0)
			return -1;
	}

	spin_unlock_bh(d->lock);
	return 0;
}
Ejemplo n.º 6
0
/**
 * gnet_stats_copy_rate_est - copy rate estimator statistics into statistics TLV
 * @d: dumping handle
 * @r: rate estimator statistics
 *
 * Appends the rate estimator statistics to the top level TLV created by
 * gnet_stats_start_copy().
 *
 * Returns 0 on success or -1 with the statistic lock released
 * if the room in the socket buffer was not sufficient.
 */
int
gnet_stats_copy_rate_est(struct gnet_dump *d, struct gnet_stats_rate_est *r)
{
	if (d->compat_tc_stats) {
		d->tc_stats.bps = r->bps;
		d->tc_stats.pps = r->pps;
	}

	return gnet_stats_copy(d, TCA_STATS_RATE_EST, r, sizeof(*r));
}
Ejemplo n.º 7
0
/**
 * gnet_stats_copy_basic - copy basic statistics into statistic TLV
 * @d: dumping handle
 * @b: basic statistics
 *
 * Appends the basic statistics to the top level TLV created by
 * gnet_stats_start_copy().
 *
 * Returns 0 on success or -1 with the statistic lock released
 * if the room in the socket buffer was not sufficient.
 */
int
gnet_stats_copy_basic(struct gnet_dump *d, struct gnet_stats_basic *b)
{
	if (d->compat_tc_stats) {
		d->tc_stats.bytes = b->bytes;
		d->tc_stats.packets = b->packets;
	}
	
	return gnet_stats_copy(d, TCA_STATS_BASIC, b, sizeof(*b));
}
Ejemplo n.º 8
0
int
gnet_stats_finish_copy(struct gnet_dump *d)
{
    if (d->tail)
        d->tail->nla_len = skb_tail_pointer(d->skb) - (u8 *)d->tail;

    if (d->compat_tc_stats)
        if (gnet_stats_copy(d, d->compat_tc_stats, &d->tc_stats,
                            sizeof(d->tc_stats)) < 0)
            return -1;

    if (d->compat_xstats && d->xstats) {
        if (gnet_stats_copy(d, d->compat_xstats, d->xstats,
                            d->xstats_len) < 0)
            return -1;
    }

    spin_unlock_bh(d->lock);
    return 0;
}
Ejemplo n.º 9
0
/**
 * gnet_stats_copy_queue - copy queue statistics into statistics TLV
 * @d: dumping handle
 * @q: queue statistics
 *
 * Appends the queue statistics to the top level TLV created by
 * gnet_stats_start_copy().
 *
 * Returns 0 on success or -1 with the statistic lock released
 * if the room in the socket buffer was not sufficient.
 */
int
gnet_stats_copy_queue(struct gnet_dump *d, struct gnet_stats_queue *q)
{
	if (d->compat_tc_stats) {
		d->tc_stats.drops = q->drops;
		d->tc_stats.qlen = q->qlen;
		d->tc_stats.backlog = q->backlog;
		d->tc_stats.overlimits = q->overlimits;
	}
		
	return gnet_stats_copy(d, TCA_STATS_QUEUE, q, sizeof(*q));
}
Ejemplo n.º 10
0
/**
 * gnet_stats_copy_app - copy application specific statistics into statistics TLV
 * @d: dumping handle
 * @st: application specific statistics data
 * @len: length of data
 *
 * Appends the application sepecific statistics to the top level TLV created by
 * gnet_stats_start_copy() and remembers the data for XSTATS if the dumping
 * handle is in backward compatibility mode.
 *
 * Returns 0 on success or -1 with the statistic lock released
 * if the room in the socket buffer was not sufficient.
 */
int
gnet_stats_copy_app(struct gnet_dump *d, void *st, int len)
{
	if (d->compat_xstats) {
		d->xstats = st;
		d->xstats_len = len;
	}

	if (d->tail)
		return gnet_stats_copy(d, TCA_STATS_APP, st, len);

	return 0;
}
Ejemplo n.º 11
0
/**
 * gnet_stats_finish_copy - finish dumping procedure
 * @d: dumping handle
 *
 * Corrects the length of the top level TLV to include all TLVs added
 * by gnet_stats_copy_XXX() calls. Adds the backward compatibility TLVs
 * if gnet_stats_start_copy_compat() was used and releases the statistics
 * lock.
 *
 * Returns 0 on success or -1 with the statistic lock released
 * if the room in the socket buffer was not sufficient.
 */
int
gnet_stats_finish_copy(struct gnet_dump *d)
{
	if (d->tail)
		d->tail->nla_len = skb_tail_pointer(d->skb) - (u8 *)d->tail;

	if (d->compat_tc_stats)
		if (gnet_stats_copy(d, d->compat_tc_stats, &d->tc_stats,
				    sizeof(d->tc_stats), d->padattr) < 0)
			return -1;

	if (d->compat_xstats && d->xstats) {
		if (gnet_stats_copy(d, d->compat_xstats, d->xstats,
				    d->xstats_len, d->padattr) < 0)
			return -1;
	}

	if (d->lock)
		spin_unlock_bh(d->lock);
	kfree(d->xstats);
	d->xstats = NULL;
	d->xstats_len = 0;
	return 0;
}
Ejemplo n.º 12
0
/**
 * gnet_stats_start_copy_compat - start dumping procedure in compatibility mode
 * @skb: socket buffer to put statistics TLVs into
 * @type: TLV type for top level statistic TLV
 * @tc_stats_type: TLV type for backward compatibility struct tc_stats TLV
 * @xstats_type: TLV type for backward compatibility xstats TLV
 * @lock: statistics lock
 * @d: dumping handle
 *
 * Initializes the dumping handle, grabs the statistic lock and appends
 * an empty TLV header to the socket buffer for use a container for all
 * other statistic TLVS.
 *
 * The dumping handle is marked to be in backward compatibility mode telling
 * all gnet_stats_copy_XXX() functions to fill a local copy of struct tc_stats.
 *
 * Returns 0 on success or -1 if the room in the socket buffer was not sufficient.
 */
int
gnet_stats_start_copy_compat(struct sk_buff *skb, int type, int tc_stats_type,
	int xstats_type, spinlock_t *lock, struct gnet_dump *d)
{
	spin_lock_bh(lock);
	d->lock = lock;
	d->tail = (struct rtattr *) skb->tail;
	d->skb = skb;
	d->compat_tc_stats = tc_stats_type;
	d->compat_xstats = xstats_type;
	d->xstats = NULL;

	if (d->compat_tc_stats)
		memset(&d->tc_stats, 0, sizeof(d->tc_stats));

	return gnet_stats_copy(d, type, NULL, 0);
}
Ejemplo n.º 13
0
int
gnet_stats_copy_rate_est(struct gnet_dump *d,
                         const struct gnet_stats_basic_packed *b,
                         struct gnet_stats_rate_est *r)
{
    if (b && !gen_estimator_active(b, r))
        return 0;

    if (d->compat_tc_stats) {
        d->tc_stats.bps = r->bps;
        d->tc_stats.pps = r->pps;
    }

    if (d->tail)
        return gnet_stats_copy(d, TCA_STATS_RATE_EST, r, sizeof(*r));

    return 0;
}
Ejemplo n.º 14
0
int
gnet_stats_copy_basic(struct gnet_dump *d, struct gnet_stats_basic_packed *b)
{
    if (d->compat_tc_stats) {
        d->tc_stats.bytes = b->bytes;
        d->tc_stats.packets = b->packets;
    }

    if (d->tail) {
        struct gnet_stats_basic sb;

        memset(&sb, 0, sizeof(sb));
        sb.bytes = b->bytes;
        sb.packets = b->packets;
        return gnet_stats_copy(d, TCA_STATS_BASIC, &sb, sizeof(sb));
    }
    return 0;
}
Ejemplo n.º 15
0
/**
 * gnet_stats_copy_app - copy application specific statistics into statistics TLV
 * @d: dumping handle
 * @st: application specific statistics data
 * @len: length of data
 *
 * Appends the application specific statistics to the top level TLV created by
 * gnet_stats_start_copy() and remembers the data for XSTATS if the dumping
 * handle is in backward compatibility mode.
 *
 * Returns 0 on success or -1 with the statistic lock released
 * if the room in the socket buffer was not sufficient.
 */
int
gnet_stats_copy_app(struct gnet_dump *d, void *st, int len)
{
    if (d->compat_xstats) {
        d->xstats = kmemdup(st, len, GFP_ATOMIC);
        if (!d->xstats)
            goto err_out;
        d->xstats_len = len;
    }

    if (d->tail)
        return gnet_stats_copy(d, TCA_STATS_APP, st, len);

    return 0;

err_out:
    d->xstats_len = 0;
    spin_unlock_bh(d->lock);
    return -1;
}
Ejemplo n.º 16
0
/**
 * gnet_stats_copy_queue - copy queue statistics into statistics TLV
 * @d: dumping handle
 * @cpu_q: per cpu queue statistics
 * @q: queue statistics
 * @qlen: queue length statistics
 *
 * Appends the queue statistics to the top level TLV created by
 * gnet_stats_start_copy(). Using per cpu queue statistics if
 * they are available.
 *
 * Returns 0 on success or -1 with the statistic lock released
 * if the room in the socket buffer was not sufficient.
 */
int
gnet_stats_copy_queue(struct gnet_dump *d,
                      struct gnet_stats_queue __percpu *cpu_q,
                      struct gnet_stats_queue *q, __u32 qlen)
{
    struct gnet_stats_queue qstats = {0};

    __gnet_stats_copy_queue(&qstats, cpu_q, q, qlen);

    if (d->compat_tc_stats) {
        d->tc_stats.drops = qstats.drops;
        d->tc_stats.qlen = qstats.qlen;
        d->tc_stats.backlog = qstats.backlog;
        d->tc_stats.overlimits = qstats.overlimits;
    }

    if (d->tail)
        return gnet_stats_copy(d, TCA_STATS_QUEUE,
                               &qstats, sizeof(qstats));

    return 0;
}