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; } |
