diff options
Diffstat (limited to 'net/core/gen_stats.c')
| -rw-r--r-- | net/core/gen_stats.c | 25 | 
1 files changed, 19 insertions, 6 deletions
diff --git a/net/core/gen_stats.c b/net/core/gen_stats.c index 0452eb27a27..9d3d9e78397 100644 --- a/net/core/gen_stats.c +++ b/net/core/gen_stats.c @@ -27,7 +27,8 @@  static inline int  gnet_stats_copy(struct gnet_dump *d, int type, void *buf, int size)  { -	NLA_PUT(d->skb, type, size, buf); +	if (nla_put(d->skb, type, size, buf)) +		goto nla_put_failure;  	return 0;  nla_put_failure: @@ -142,18 +143,30 @@ EXPORT_SYMBOL(gnet_stats_copy_basic);  int  gnet_stats_copy_rate_est(struct gnet_dump *d,  			 const struct gnet_stats_basic_packed *b, -			 struct gnet_stats_rate_est *r) +			 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 = r->bps; -		d->tc_stats.pps = r->pps; +		d->tc_stats.bps = est.bps; +		d->tc_stats.pps = est.pps;  	} -	if (d->tail) -		return gnet_stats_copy(d, TCA_STATS_RATE_EST, r, sizeof(*r)); +	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;  }  | 
