net: restore gnet_stats_basic to previous definition
In 5e140dfc1f "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 <mspang@csclub.uwaterloo.ca>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
c6ba973b8f
commit
c1a8f1f1c8
@@ -19,6 +19,11 @@ enum {
|
||||
* @packets: number of seen packets
|
||||
*/
|
||||
struct gnet_stats_basic
|
||||
{
|
||||
__u64 bytes;
|
||||
__u32 packets;
|
||||
};
|
||||
struct gnet_stats_basic_packed
|
||||
{
|
||||
__u64 bytes;
|
||||
__u32 packets;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user