Skip to content

Commit

Permalink
net: reorder struct Qdisc for better SMP performance
Browse files Browse the repository at this point in the history
dev_queue_xmit() needs to dirty fields "state", "q", "bstats" and "qstats"

On x86_64 arch, they currently span three cache lines, involving more
cache line ping pongs than necessary, making longer holding of queue spinlock.

We can reduce this to one cache line, by grouping all read-mostly fields
at the beginning of structure. (Or should I say, all highly modified fields
at the end :) )

Before patch :

offsetof(struct Qdisc, state)=0x38
offsetof(struct Qdisc, q)=0x48
offsetof(struct Qdisc, bstats)=0x80
offsetof(struct Qdisc, qstats)=0x90
sizeof(struct Qdisc)=0xc8

After patch :

offsetof(struct Qdisc, state)=0x80
offsetof(struct Qdisc, q)=0x88
offsetof(struct Qdisc, bstats)=0xa0
offsetof(struct Qdisc, qstats)=0xac
sizeof(struct Qdisc)=0xc0

Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Eric Dumazet authored and David S. Miller committed Mar 20, 2009
1 parent 408896d commit 5e140df
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 10 deletions.
2 changes: 1 addition & 1 deletion include/linux/gen_stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct gnet_stats_basic
{
__u64 bytes;
__u32 packets;
};
} __attribute__ ((packed));

/**
* struct gnet_stats_rate_est - rate estimator
Expand Down
21 changes: 12 additions & 9 deletions include/net/sch_generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,10 @@ struct Qdisc
int padded;
struct Qdisc_ops *ops;
struct qdisc_size_table *stab;
struct list_head list;
u32 handle;
u32 parent;
atomic_t refcnt;
unsigned long state;
struct sk_buff *gso_skb;
struct sk_buff_head q;
struct netdev_queue *dev_queue;
struct Qdisc *next_sched;
struct list_head list;

struct gnet_stats_basic bstats;
struct gnet_stats_queue qstats;
struct gnet_stats_rate_est rate_est;
int (*reshape_fail)(struct sk_buff *skb,
struct Qdisc *q);
Expand All @@ -71,6 +63,17 @@ struct Qdisc
* and it will live until better solution will be invented.
*/
struct Qdisc *__parent;
struct netdev_queue *dev_queue;
struct Qdisc *next_sched;

struct sk_buff *gso_skb;
/*
* For performance sake on SMP, we put highly modified fields at the end
*/
unsigned long state;
struct sk_buff_head q;
struct gnet_stats_basic bstats;
struct gnet_stats_queue qstats;
};

struct Qdisc_class_ops
Expand Down

0 comments on commit 5e140df

Please sign in to comment.