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 /include | |
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 'include')
-rw-r--r-- | include/net/act_api.h | 2 | ||||
-rw-r--r-- | include/net/gen_stats.h | 10 | ||||
-rw-r--r-- | include/net/netfilter/xt_rateest.h | 2 | ||||
-rw-r--r-- | include/net/sch_generic.h | 13 | ||||
-rw-r--r-- | include/uapi/linux/gen_stats.h | 11 |
5 files changed, 25 insertions, 13 deletions
diff --git a/include/net/act_api.h b/include/net/act_api.h index 06ef7e926a66..b8ffac7b6bab 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h | |||
@@ -18,7 +18,7 @@ struct tcf_common { | |||
18 | struct tcf_t tcfc_tm; | 18 | struct tcf_t tcfc_tm; |
19 | struct gnet_stats_basic_packed tcfc_bstats; | 19 | struct gnet_stats_basic_packed tcfc_bstats; |
20 | struct gnet_stats_queue tcfc_qstats; | 20 | struct gnet_stats_queue tcfc_qstats; |
21 | struct gnet_stats_rate_est tcfc_rate_est; | 21 | struct gnet_stats_rate_est64 tcfc_rate_est; |
22 | spinlock_t tcfc_lock; | 22 | spinlock_t tcfc_lock; |
23 | struct rcu_head tcfc_rcu; | 23 | struct rcu_head tcfc_rcu; |
24 | }; | 24 | }; |
diff --git a/include/net/gen_stats.h b/include/net/gen_stats.h index a79b6cfb02a8..cf8439ba4d11 100644 --- a/include/net/gen_stats.h +++ b/include/net/gen_stats.h | |||
@@ -30,7 +30,7 @@ extern int gnet_stats_copy_basic(struct gnet_dump *d, | |||
30 | struct gnet_stats_basic_packed *b); | 30 | struct gnet_stats_basic_packed *b); |
31 | extern int gnet_stats_copy_rate_est(struct gnet_dump *d, | 31 | extern int gnet_stats_copy_rate_est(struct gnet_dump *d, |
32 | const struct gnet_stats_basic_packed *b, | 32 | const struct gnet_stats_basic_packed *b, |
33 | struct gnet_stats_rate_est *r); | 33 | struct gnet_stats_rate_est64 *r); |
34 | extern int gnet_stats_copy_queue(struct gnet_dump *d, | 34 | extern int gnet_stats_copy_queue(struct gnet_dump *d, |
35 | struct gnet_stats_queue *q); | 35 | struct gnet_stats_queue *q); |
36 | extern int gnet_stats_copy_app(struct gnet_dump *d, void *st, int len); | 36 | extern int gnet_stats_copy_app(struct gnet_dump *d, void *st, int len); |
@@ -38,13 +38,13 @@ extern int gnet_stats_copy_app(struct gnet_dump *d, void *st, int len); | |||
38 | extern int gnet_stats_finish_copy(struct gnet_dump *d); | 38 | extern int gnet_stats_finish_copy(struct gnet_dump *d); |
39 | 39 | ||
40 | extern int gen_new_estimator(struct gnet_stats_basic_packed *bstats, | 40 | extern int gen_new_estimator(struct gnet_stats_basic_packed *bstats, |
41 | struct gnet_stats_rate_est *rate_est, | 41 | struct gnet_stats_rate_est64 *rate_est, |
42 | spinlock_t *stats_lock, struct nlattr *opt); | 42 | spinlock_t *stats_lock, struct nlattr *opt); |
43 | extern void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, | 43 | extern void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, |
44 | struct gnet_stats_rate_est *rate_est); | 44 | struct gnet_stats_rate_est64 *rate_est); |
45 | extern int gen_replace_estimator(struct gnet_stats_basic_packed *bstats, | 45 | extern int gen_replace_estimator(struct gnet_stats_basic_packed *bstats, |
46 | struct gnet_stats_rate_est *rate_est, | 46 | struct gnet_stats_rate_est64 *rate_est, |
47 | spinlock_t *stats_lock, struct nlattr *opt); | 47 | spinlock_t *stats_lock, struct nlattr *opt); |
48 | extern bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats, | 48 | extern bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats, |
49 | const struct gnet_stats_rate_est *rate_est); | 49 | const struct gnet_stats_rate_est64 *rate_est); |
50 | #endif | 50 | #endif |
diff --git a/include/net/netfilter/xt_rateest.h b/include/net/netfilter/xt_rateest.h index 5a2978d1cb22..495c71f66e7e 100644 --- a/include/net/netfilter/xt_rateest.h +++ b/include/net/netfilter/xt_rateest.h | |||
@@ -6,7 +6,7 @@ struct xt_rateest { | |||
6 | struct gnet_stats_basic_packed bstats; | 6 | struct gnet_stats_basic_packed bstats; |
7 | spinlock_t lock; | 7 | spinlock_t lock; |
8 | /* keep rstats and lock on same cache line to speedup xt_rateest_mt() */ | 8 | /* keep rstats and lock on same cache line to speedup xt_rateest_mt() */ |
9 | struct gnet_stats_rate_est rstats; | 9 | struct gnet_stats_rate_est64 rstats; |
10 | 10 | ||
11 | /* following fields not accessed in hot path */ | 11 | /* following fields not accessed in hot path */ |
12 | struct hlist_node list; | 12 | struct hlist_node list; |
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index e7f4e21cc3e1..df5676029827 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h | |||
@@ -58,14 +58,12 @@ struct Qdisc { | |||
58 | * multiqueue device. | 58 | * multiqueue device. |
59 | */ | 59 | */ |
60 | #define TCQ_F_WARN_NONWC (1 << 16) | 60 | #define TCQ_F_WARN_NONWC (1 << 16) |
61 | int padded; | 61 | u32 limit; |
62 | const struct Qdisc_ops *ops; | 62 | const struct Qdisc_ops *ops; |
63 | struct qdisc_size_table __rcu *stab; | 63 | struct qdisc_size_table __rcu *stab; |
64 | struct list_head list; | 64 | struct list_head list; |
65 | u32 handle; | 65 | u32 handle; |
66 | u32 parent; | 66 | u32 parent; |
67 | atomic_t refcnt; | ||
68 | struct gnet_stats_rate_est rate_est; | ||
69 | int (*reshape_fail)(struct sk_buff *skb, | 67 | int (*reshape_fail)(struct sk_buff *skb, |
70 | struct Qdisc *q); | 68 | struct Qdisc *q); |
71 | 69 | ||
@@ -76,8 +74,9 @@ struct Qdisc { | |||
76 | */ | 74 | */ |
77 | struct Qdisc *__parent; | 75 | struct Qdisc *__parent; |
78 | struct netdev_queue *dev_queue; | 76 | struct netdev_queue *dev_queue; |
79 | struct Qdisc *next_sched; | ||
80 | 77 | ||
78 | struct gnet_stats_rate_est64 rate_est; | ||
79 | struct Qdisc *next_sched; | ||
81 | struct sk_buff *gso_skb; | 80 | struct sk_buff *gso_skb; |
82 | /* | 81 | /* |
83 | * For performance sake on SMP, we put highly modified fields at the end | 82 | * For performance sake on SMP, we put highly modified fields at the end |
@@ -88,8 +87,10 @@ struct Qdisc { | |||
88 | unsigned int __state; | 87 | unsigned int __state; |
89 | struct gnet_stats_queue qstats; | 88 | struct gnet_stats_queue qstats; |
90 | struct rcu_head rcu_head; | 89 | struct rcu_head rcu_head; |
91 | spinlock_t busylock; | 90 | int padded; |
92 | u32 limit; | 91 | atomic_t refcnt; |
92 | |||
93 | spinlock_t busylock ____cacheline_aligned_in_smp; | ||
93 | }; | 94 | }; |
94 | 95 | ||
95 | static inline bool qdisc_is_running(const struct Qdisc *qdisc) | 96 | static inline bool qdisc_is_running(const struct Qdisc *qdisc) |
diff --git a/include/uapi/linux/gen_stats.h b/include/uapi/linux/gen_stats.h index 552c8a0a12d1..6487317ea619 100644 --- a/include/uapi/linux/gen_stats.h +++ b/include/uapi/linux/gen_stats.h | |||
@@ -9,6 +9,7 @@ enum { | |||
9 | TCA_STATS_RATE_EST, | 9 | TCA_STATS_RATE_EST, |
10 | TCA_STATS_QUEUE, | 10 | TCA_STATS_QUEUE, |
11 | TCA_STATS_APP, | 11 | TCA_STATS_APP, |
12 | TCA_STATS_RATE_EST64, | ||
12 | __TCA_STATS_MAX, | 13 | __TCA_STATS_MAX, |
13 | }; | 14 | }; |
14 | #define TCA_STATS_MAX (__TCA_STATS_MAX - 1) | 15 | #define TCA_STATS_MAX (__TCA_STATS_MAX - 1) |
@@ -38,6 +39,16 @@ struct gnet_stats_rate_est { | |||
38 | }; | 39 | }; |
39 | 40 | ||
40 | /** | 41 | /** |
42 | * struct gnet_stats_rate_est64 - rate estimator | ||
43 | * @bps: current byte rate | ||
44 | * @pps: current packet rate | ||
45 | */ | ||
46 | struct gnet_stats_rate_est64 { | ||
47 | __u64 bps; | ||
48 | __u64 pps; | ||
49 | }; | ||
50 | |||
51 | /** | ||
41 | * struct gnet_stats_queue - queuing statistics | 52 | * struct gnet_stats_queue - queuing statistics |
42 | * @qlen: queue length | 53 | * @qlen: queue length |
43 | * @backlog: backlog size of queue | 54 | * @backlog: backlog size of queue |