diff options
author | Eric Dumazet <edumazet@google.com> | 2013-06-06 11:43:22 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-06-11 05:51:03 -0400 |
commit | 45203a3b380cee28f570475c0d28c169f908c209 (patch) | |
tree | 9d9b00da9accbc0ea01c91c206cb86a2f9dd7609 /net/core/gen_stats.c | |
parent | b41abb42bf62a85a32c41dab873220598a6ee266 (diff) |
net_sched: add 64bit rate estimators
struct gnet_stats_rate_est contains u32 fields, so the bytes per second
field can wrap at 34360Mbit.
Add a new gnet_stats_rate_est64 structure to get 64bit bps/pps fields,
and switch the kernel to use this structure natively.
This structure is dumped to user space as a new attribute :
TCA_STATS_RATE_EST64
Old tc command will now display the capped bps (to 34360Mbit), instead
of wrapped values, and updated tc command will display correct
information.
Old tc command output, after patch :
eric:~# tc -s -d qd sh dev lo
qdisc pfifo 8001: root refcnt 2 limit 1000p
Sent 80868245400 bytes 1978837 pkt (dropped 0, overlimits 0 requeues 0)
rate 34360Mbit 189696pps backlog 0b 0p requeues 0
This patch carefully reorganizes "struct Qdisc" layout to get optimal
performance on SMP.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/gen_stats.c')
-rw-r--r-- | net/core/gen_stats.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/net/core/gen_stats.c b/net/core/gen_stats.c index ddedf211e588..9d3d9e78397b 100644 --- a/net/core/gen_stats.c +++ b/net/core/gen_stats.c | |||
@@ -143,18 +143,30 @@ EXPORT_SYMBOL(gnet_stats_copy_basic); | |||
143 | int | 143 | int |
144 | gnet_stats_copy_rate_est(struct gnet_dump *d, | 144 | gnet_stats_copy_rate_est(struct gnet_dump *d, |
145 | const struct gnet_stats_basic_packed *b, | 145 | const struct gnet_stats_basic_packed *b, |
146 | struct gnet_stats_rate_est *r) | 146 | struct gnet_stats_rate_est64 *r) |
147 | { | 147 | { |
148 | struct gnet_stats_rate_est est; | ||
149 | int res; | ||
150 | |||
148 | if (b && !gen_estimator_active(b, r)) | 151 | if (b && !gen_estimator_active(b, r)) |
149 | return 0; | 152 | return 0; |
150 | 153 | ||
154 | est.bps = min_t(u64, UINT_MAX, r->bps); | ||
155 | /* we have some time before reaching 2^32 packets per second */ | ||
156 | est.pps = r->pps; | ||
157 | |||
151 | if (d->compat_tc_stats) { | 158 | if (d->compat_tc_stats) { |
152 | d->tc_stats.bps = r->bps; | 159 | d->tc_stats.bps = est.bps; |
153 | d->tc_stats.pps = r->pps; | 160 | d->tc_stats.pps = est.pps; |
154 | } | 161 | } |
155 | 162 | ||
156 | if (d->tail) | 163 | if (d->tail) { |
157 | return gnet_stats_copy(d, TCA_STATS_RATE_EST, r, sizeof(*r)); | 164 | res = gnet_stats_copy(d, TCA_STATS_RATE_EST, &est, sizeof(est)); |
165 | if (res < 0 || est.bps == r->bps) | ||
166 | return res; | ||
167 | /* emit 64bit stats only if needed */ | ||
168 | return gnet_stats_copy(d, TCA_STATS_RATE_EST64, r, sizeof(*r)); | ||
169 | } | ||
158 | 170 | ||
159 | return 0; | 171 | return 0; |
160 | } | 172 | } |