mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-30 10:49:28 +00:00
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:
parent
c6ba973b8f
commit
c1a8f1f1c8
13 changed files with 33 additions and 23 deletions
|
@ -19,6 +19,11 @@ enum {
|
||||||
* @packets: number of seen packets
|
* @packets: number of seen packets
|
||||||
*/
|
*/
|
||||||
struct gnet_stats_basic
|
struct gnet_stats_basic
|
||||||
|
{
|
||||||
|
__u64 bytes;
|
||||||
|
__u32 packets;
|
||||||
|
};
|
||||||
|
struct gnet_stats_basic_packed
|
||||||
{
|
{
|
||||||
__u64 bytes;
|
__u64 bytes;
|
||||||
__u32 packets;
|
__u32 packets;
|
||||||
|
|
|
@ -16,7 +16,7 @@ struct tcf_common {
|
||||||
u32 tcfc_capab;
|
u32 tcfc_capab;
|
||||||
int tcfc_action;
|
int tcfc_action;
|
||||||
struct tcf_t tcfc_tm;
|
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_queue tcfc_qstats;
|
||||||
struct gnet_stats_rate_est tcfc_rate_est;
|
struct gnet_stats_rate_est tcfc_rate_est;
|
||||||
spinlock_t tcfc_lock;
|
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);
|
spinlock_t *lock, struct gnet_dump *d);
|
||||||
|
|
||||||
extern int gnet_stats_copy_basic(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,
|
extern int gnet_stats_copy_rate_est(struct gnet_dump *d,
|
||||||
struct gnet_stats_rate_est *r);
|
struct gnet_stats_rate_est *r);
|
||||||
extern int gnet_stats_copy_queue(struct gnet_dump *d,
|
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 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,
|
struct gnet_stats_rate_est *rate_est,
|
||||||
spinlock_t *stats_lock, struct nlattr *opt);
|
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);
|
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,
|
struct gnet_stats_rate_est *rate_est,
|
||||||
spinlock_t *stats_lock, struct nlattr *opt);
|
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);
|
const struct gnet_stats_rate_est *rate_est);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,7 +8,7 @@ struct xt_rateest {
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
struct gnet_estimator params;
|
struct gnet_estimator params;
|
||||||
struct gnet_stats_rate_est rstats;
|
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);
|
extern struct xt_rateest *xt_rateest_lookup(const char *name);
|
||||||
|
|
|
@ -72,7 +72,7 @@ struct Qdisc
|
||||||
*/
|
*/
|
||||||
unsigned long state;
|
unsigned long state;
|
||||||
struct sk_buff_head q;
|
struct sk_buff_head q;
|
||||||
struct gnet_stats_basic bstats;
|
struct gnet_stats_basic_packed bstats;
|
||||||
struct gnet_stats_queue qstats;
|
struct gnet_stats_queue qstats;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@
|
||||||
struct gen_estimator
|
struct gen_estimator
|
||||||
{
|
{
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
struct gnet_stats_basic *bstats;
|
struct gnet_stats_basic_packed *bstats;
|
||||||
struct gnet_stats_rate_est *rate_est;
|
struct gnet_stats_rate_est *rate_est;
|
||||||
spinlock_t *stats_lock;
|
spinlock_t *stats_lock;
|
||||||
int ewma_log;
|
int ewma_log;
|
||||||
|
@ -165,7 +165,7 @@ static void gen_add_node(struct gen_estimator *est)
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
struct gen_estimator *gen_find_node(const struct gnet_stats_basic *bstats,
|
struct gen_estimator *gen_find_node(const struct gnet_stats_basic_packed *bstats,
|
||||||
const struct gnet_stats_rate_est *rate_est)
|
const struct gnet_stats_rate_est *rate_est)
|
||||||
{
|
{
|
||||||
struct rb_node *p = est_root.rb_node;
|
struct rb_node *p = est_root.rb_node;
|
||||||
|
@ -202,7 +202,7 @@ struct gen_estimator *gen_find_node(const struct gnet_stats_basic *bstats,
|
||||||
*
|
*
|
||||||
* NOTE: Called under rtnl_mutex
|
* NOTE: Called under rtnl_mutex
|
||||||
*/
|
*/
|
||||||
int gen_new_estimator(struct gnet_stats_basic *bstats,
|
int gen_new_estimator(struct gnet_stats_basic_packed *bstats,
|
||||||
struct gnet_stats_rate_est *rate_est,
|
struct gnet_stats_rate_est *rate_est,
|
||||||
spinlock_t *stats_lock,
|
spinlock_t *stats_lock,
|
||||||
struct nlattr *opt)
|
struct nlattr *opt)
|
||||||
|
@ -262,7 +262,7 @@ static void __gen_kill_estimator(struct rcu_head *head)
|
||||||
*
|
*
|
||||||
* NOTE: Called under rtnl_mutex
|
* NOTE: Called under rtnl_mutex
|
||||||
*/
|
*/
|
||||||
void gen_kill_estimator(struct gnet_stats_basic *bstats,
|
void gen_kill_estimator(struct gnet_stats_basic_packed *bstats,
|
||||||
struct gnet_stats_rate_est *rate_est)
|
struct gnet_stats_rate_est *rate_est)
|
||||||
{
|
{
|
||||||
struct gen_estimator *e;
|
struct gen_estimator *e;
|
||||||
|
@ -292,7 +292,7 @@ EXPORT_SYMBOL(gen_kill_estimator);
|
||||||
*
|
*
|
||||||
* Returns 0 on success or a negative error code.
|
* Returns 0 on success or a negative error code.
|
||||||
*/
|
*/
|
||||||
int gen_replace_estimator(struct gnet_stats_basic *bstats,
|
int gen_replace_estimator(struct gnet_stats_basic_packed *bstats,
|
||||||
struct gnet_stats_rate_est *rate_est,
|
struct gnet_stats_rate_est *rate_est,
|
||||||
spinlock_t *stats_lock, struct nlattr *opt)
|
spinlock_t *stats_lock, struct nlattr *opt)
|
||||||
{
|
{
|
||||||
|
@ -308,7 +308,7 @@ EXPORT_SYMBOL(gen_replace_estimator);
|
||||||
*
|
*
|
||||||
* Returns true if estimator is active, and false if not.
|
* Returns true if estimator is active, and false if not.
|
||||||
*/
|
*/
|
||||||
bool gen_estimator_active(const struct gnet_stats_basic *bstats,
|
bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats,
|
||||||
const struct gnet_stats_rate_est *rate_est)
|
const struct gnet_stats_rate_est *rate_est)
|
||||||
{
|
{
|
||||||
ASSERT_RTNL();
|
ASSERT_RTNL();
|
||||||
|
|
|
@ -106,16 +106,21 @@ gnet_stats_start_copy(struct sk_buff *skb, int type, spinlock_t *lock,
|
||||||
* if the room in the socket buffer was not sufficient.
|
* if the room in the socket buffer was not sufficient.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
gnet_stats_copy_basic(struct gnet_dump *d, struct gnet_stats_basic *b)
|
gnet_stats_copy_basic(struct gnet_dump *d, struct gnet_stats_basic_packed *b)
|
||||||
{
|
{
|
||||||
if (d->compat_tc_stats) {
|
if (d->compat_tc_stats) {
|
||||||
d->tc_stats.bytes = b->bytes;
|
d->tc_stats.bytes = b->bytes;
|
||||||
d->tc_stats.packets = b->packets;
|
d->tc_stats.packets = b->packets;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->tail)
|
if (d->tail) {
|
||||||
return gnet_stats_copy(d, TCA_STATS_BASIC, b, sizeof(*b));
|
struct gnet_stats_basic sb;
|
||||||
|
|
||||||
|
memset(&sb, 0, sizeof(sb));
|
||||||
|
sb.bytes = b->bytes;
|
||||||
|
sb.packets = b->packets;
|
||||||
|
return gnet_stats_copy(d, TCA_STATS_BASIC, &sb, sizeof(sb));
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ static unsigned int
|
||||||
xt_rateest_tg(struct sk_buff *skb, const struct xt_target_param *par)
|
xt_rateest_tg(struct sk_buff *skb, const struct xt_target_param *par)
|
||||||
{
|
{
|
||||||
const struct xt_rateest_target_info *info = par->targinfo;
|
const struct xt_rateest_target_info *info = par->targinfo;
|
||||||
struct gnet_stats_basic *stats = &info->est->bstats;
|
struct gnet_stats_basic_packed *stats = &info->est->bstats;
|
||||||
|
|
||||||
spin_lock_bh(&info->est->lock);
|
spin_lock_bh(&info->est->lock);
|
||||||
stats->bytes += skb->len;
|
stats->bytes += skb->len;
|
||||||
|
|
|
@ -49,7 +49,7 @@ struct atm_flow_data {
|
||||||
struct socket *sock; /* for closing */
|
struct socket *sock; /* for closing */
|
||||||
u32 classid; /* x:y type ID */
|
u32 classid; /* x:y type ID */
|
||||||
int ref; /* reference count */
|
int ref; /* reference count */
|
||||||
struct gnet_stats_basic bstats;
|
struct gnet_stats_basic_packed bstats;
|
||||||
struct gnet_stats_queue qstats;
|
struct gnet_stats_queue qstats;
|
||||||
struct atm_flow_data *next;
|
struct atm_flow_data *next;
|
||||||
struct atm_flow_data *excess; /* flow for excess traffic;
|
struct atm_flow_data *excess; /* flow for excess traffic;
|
||||||
|
|
|
@ -128,7 +128,7 @@ struct cbq_class
|
||||||
long avgidle;
|
long avgidle;
|
||||||
long deficit; /* Saved deficit for WRR */
|
long deficit; /* Saved deficit for WRR */
|
||||||
psched_time_t penalized;
|
psched_time_t penalized;
|
||||||
struct gnet_stats_basic bstats;
|
struct gnet_stats_basic_packed bstats;
|
||||||
struct gnet_stats_queue qstats;
|
struct gnet_stats_queue qstats;
|
||||||
struct gnet_stats_rate_est rate_est;
|
struct gnet_stats_rate_est rate_est;
|
||||||
struct tc_cbq_xstats xstats;
|
struct tc_cbq_xstats xstats;
|
||||||
|
|
|
@ -22,7 +22,7 @@ struct drr_class {
|
||||||
unsigned int refcnt;
|
unsigned int refcnt;
|
||||||
unsigned int filter_cnt;
|
unsigned int filter_cnt;
|
||||||
|
|
||||||
struct gnet_stats_basic bstats;
|
struct gnet_stats_basic_packed bstats;
|
||||||
struct gnet_stats_queue qstats;
|
struct gnet_stats_queue qstats;
|
||||||
struct gnet_stats_rate_est rate_est;
|
struct gnet_stats_rate_est rate_est;
|
||||||
struct list_head alist;
|
struct list_head alist;
|
||||||
|
|
|
@ -116,7 +116,7 @@ struct hfsc_class
|
||||||
struct Qdisc_class_common cl_common;
|
struct Qdisc_class_common cl_common;
|
||||||
unsigned int refcnt; /* usage count */
|
unsigned int refcnt; /* usage count */
|
||||||
|
|
||||||
struct gnet_stats_basic bstats;
|
struct gnet_stats_basic_packed bstats;
|
||||||
struct gnet_stats_queue qstats;
|
struct gnet_stats_queue qstats;
|
||||||
struct gnet_stats_rate_est rate_est;
|
struct gnet_stats_rate_est rate_est;
|
||||||
unsigned int level; /* class level in hierarchy */
|
unsigned int level; /* class level in hierarchy */
|
||||||
|
|
|
@ -74,7 +74,7 @@ enum htb_cmode {
|
||||||
struct htb_class {
|
struct htb_class {
|
||||||
struct Qdisc_class_common common;
|
struct Qdisc_class_common common;
|
||||||
/* general class parameters */
|
/* general class parameters */
|
||||||
struct gnet_stats_basic bstats;
|
struct gnet_stats_basic_packed bstats;
|
||||||
struct gnet_stats_queue qstats;
|
struct gnet_stats_queue qstats;
|
||||||
struct gnet_stats_rate_est rate_est;
|
struct gnet_stats_rate_est rate_est;
|
||||||
struct tc_htb_xstats xstats; /* our special stats */
|
struct tc_htb_xstats xstats; /* our special stats */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue