From c1a8f1f1c8e01eab5862c8db39b49ace814e6c66 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 16 Aug 2009 09:36:49 +0000 Subject: net: restore gnet_stats_basic to previous definition In 5e140dfc1fe87eae27846f193086724806b33c7d "net: reorder struct Qdisc for better SMP performance" the definition of struct gnet_stats_basic changed incompatibly, as copies of this struct are shipped to userland via netlink. Restoring old behavior is not welcome, for performance reason. Fix is to use a private structure for kernel, and teach gnet_stats_copy_basic() to convert from kernel to user land, using legacy structure (struct gnet_stats_basic) Based on a report and initial patch from Michael Spang. Reported-by: Michael Spang Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/linux/gen_stats.h | 5 +++++ include/net/act_api.h | 2 +- include/net/gen_stats.h | 10 +++++----- include/net/netfilter/xt_rateest.h | 2 +- include/net/sch_generic.h | 2 +- 5 files changed, 13 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/linux/gen_stats.h b/include/linux/gen_stats.h index 0ffa41d..710e901 100644 --- a/include/linux/gen_stats.h +++ b/include/linux/gen_stats.h @@ -22,6 +22,11 @@ struct gnet_stats_basic { __u64 bytes; __u32 packets; +}; +struct gnet_stats_basic_packed +{ + __u64 bytes; + __u32 packets; } __attribute__ ((packed)); /** diff --git a/include/net/act_api.h b/include/net/act_api.h index 565eed8..c05fd71 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -16,7 +16,7 @@ struct tcf_common { u32 tcfc_capab; int tcfc_action; struct tcf_t tcfc_tm; - struct gnet_stats_basic tcfc_bstats; + struct gnet_stats_basic_packed tcfc_bstats; struct gnet_stats_queue tcfc_qstats; struct gnet_stats_rate_est tcfc_rate_est; spinlock_t tcfc_lock; diff --git a/include/net/gen_stats.h b/include/net/gen_stats.h index d136b52..c148855 100644 --- a/include/net/gen_stats.h +++ b/include/net/gen_stats.h @@ -28,7 +28,7 @@ extern int gnet_stats_start_copy_compat(struct sk_buff *skb, int type, spinlock_t *lock, struct gnet_dump *d); extern int gnet_stats_copy_basic(struct gnet_dump *d, - struct gnet_stats_basic *b); + struct gnet_stats_basic_packed *b); extern int gnet_stats_copy_rate_est(struct gnet_dump *d, struct gnet_stats_rate_est *r); extern int gnet_stats_copy_queue(struct gnet_dump *d, @@ -37,14 +37,14 @@ extern int gnet_stats_copy_app(struct gnet_dump *d, void *st, int len); extern int gnet_stats_finish_copy(struct gnet_dump *d); -extern int gen_new_estimator(struct gnet_stats_basic *bstats, +extern int gen_new_estimator(struct gnet_stats_basic_packed *bstats, struct gnet_stats_rate_est *rate_est, spinlock_t *stats_lock, struct nlattr *opt); -extern void gen_kill_estimator(struct gnet_stats_basic *bstats, +extern void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, struct gnet_stats_rate_est *rate_est); -extern int gen_replace_estimator(struct gnet_stats_basic *bstats, +extern int gen_replace_estimator(struct gnet_stats_basic_packed *bstats, struct gnet_stats_rate_est *rate_est, spinlock_t *stats_lock, struct nlattr *opt); -extern bool gen_estimator_active(const struct gnet_stats_basic *bstats, +extern bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats, const struct gnet_stats_rate_est *rate_est); #endif diff --git a/include/net/netfilter/xt_rateest.h b/include/net/netfilter/xt_rateest.h index 65d594d..ddbf37e 100644 --- a/include/net/netfilter/xt_rateest.h +++ b/include/net/netfilter/xt_rateest.h @@ -8,7 +8,7 @@ struct xt_rateest { spinlock_t lock; struct gnet_estimator params; struct gnet_stats_rate_est rstats; - struct gnet_stats_basic bstats; + struct gnet_stats_basic_packed bstats; }; extern struct xt_rateest *xt_rateest_lookup(const char *name); diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 964ffa0..5482e95 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -72,7 +72,7 @@ struct Qdisc */ unsigned long state; struct sk_buff_head q; - struct gnet_stats_basic bstats; + struct gnet_stats_basic_packed bstats; struct gnet_stats_queue qstats; }; -- cgit v1.1