aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2013-06-06 11:43:22 -0400
committerDavid S. Miller <davem@davemloft.net>2013-06-11 05:51:03 -0400
commit45203a3b380cee28f570475c0d28c169f908c209 (patch)
tree9d9b00da9accbc0ea01c91c206cb86a2f9dd7609 /include
parentb41abb42bf62a85a32c41dab873220598a6ee266 (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.h2
-rw-r--r--include/net/gen_stats.h10
-rw-r--r--include/net/netfilter/xt_rateest.h2
-rw-r--r--include/net/sch_generic.h13
-rw-r--r--include/uapi/linux/gen_stats.h11
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);
31extern int gnet_stats_copy_rate_est(struct gnet_dump *d, 31extern 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);
34extern int gnet_stats_copy_queue(struct gnet_dump *d, 34extern int gnet_stats_copy_queue(struct gnet_dump *d,
35 struct gnet_stats_queue *q); 35 struct gnet_stats_queue *q);
36extern int gnet_stats_copy_app(struct gnet_dump *d, void *st, int len); 36extern 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);
38extern int gnet_stats_finish_copy(struct gnet_dump *d); 38extern int gnet_stats_finish_copy(struct gnet_dump *d);
39 39
40extern int gen_new_estimator(struct gnet_stats_basic_packed *bstats, 40extern 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);
43extern void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, 43extern 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);
45extern int gen_replace_estimator(struct gnet_stats_basic_packed *bstats, 45extern 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);
48extern bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats, 48extern 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
95static inline bool qdisc_is_running(const struct Qdisc *qdisc) 96static 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 */
46struct 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