net,rcu: don't assume the size of struct rcu_head
Subsystems (3)
PATCH 4/4 net,rcu: don't assume the size of struct rcu_head
struct dst_entry assumes the size of struct rcu_head as 2 * sizeof(long) and manually adds pads for aligning for "__refcnt".
When the size of struct rcu_head is changed, these manual padding is wrong. Use __attribute__((aligned (64))) instead.
---
include/net/dst.h +3 -10
@@ -62,8 +62,6 @@ struct dst_entry {struct hh_cache *hh;#ifdef CONFIG_XFRM struct xfrm_state *xfrm; -#else -void *__pad1;#endif int (*input)(struct sk_buff *);int (*output)(struct sk_buff *);
@@ -74,23 +72,18 @@ struct dst_entry {#ifdef CONFIG_NET_CLS_ROUTE __u32 tclassid; -#else -__u32 __pad2;#endif /* * Align __refcnt to a 64 bytes alignment * (L1_CACHE_SIZE would be too much) -*/ -#ifdef CONFIG_64BIT -long __pad_to_align_refcnt[1 ]; -#endif -/* +* * __refcnt wants to be on a different cache line from * input/output/ops or performance tanks badly */ -atomic_t __refcnt;/* client references */ + atomic_t __refcnt /* client references */ + __attribute__((aligned (64)));int __use;unsigned long lastuse;union {
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
David Miller
maintainerFrom: Lai Jiangshan <[email protected]>
Date: Tue, 01 Mar 2011 16:03:44 +0800
Quoted 8 lines
struct
dst_entryassumes the size of structrcu_headas 2 * sizeof(long) and manually adds pads for aligning for "__refcnt".When the size of struct
rcu_headis changed, these manual padding is wrong. Use__attribute__((aligned (64)))instead.Signed-off-by Lai Jiangshan <[email protected]>
We don't want to use the align if it's going to waste lots of space.
Instead we want to rearrange the structure so that the alignment comes more cheaply.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 10 lines · David Miller
From: Lai Jiangshan <[email protected]>
Date: Tue, 01 Mar 2011 16:03:44 +0800Quoted 7 lines
struct
dst_entryassumes the size of structrcu_headas 2 * sizeof(long) and manually adds pads for aligning for "__refcnt".When the size of struct
rcu_headis changed, these manual padding is wrong. Use__attribute__((aligned (64)))instead.
Quoted 6 lines
Quoted 1 line
Signed-off-by Lai Jiangshan <[email protected]>We don't want to use the align if it's going to waste lots of space.
Instead we want to rearrange the structure so that the alignment comes more cheaply.
Oh well, I should have read your answer before sending mine :)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v2 4/4 net,rcu: don't assume the size of struct rcu_head
In reply to David MillerQuoted 10 lines · David Miller
From: Lai Jiangshan <[email protected]>
Date: Tue, 01 Mar 2011 16:03:44 +0800Quoted 7 lines
struct
dst_entryassumes the size of structrcu_headas 2 * sizeof(long) and manually adds pads for aligning for "__refcnt".When the size of struct
rcu_headis changed, these manual padding is wrong. Use__attribute__((aligned (64)))instead.
Quoted 6 lines
Quoted 1 line
Signed-off-by Lai Jiangshan <[email protected]>We don't want to use the align if it's going to waste lots of space.
Instead we want to rearrange the structure so that the alignment comes more cheaply.
Subject: [PATCH 4/4 V2] net,rcu: don't assume the size of struct rcu_head
struct dst_entry assumes the size of struct rcu_head as 2 * sizeof(long) and manually adds pads for aligning for "__refcnt".
When the size of struct rcu_head is changed, these manual padding are hardly suit for the changes. So we rearrange the structure, and move the seldom access rcu_head to the end of the structure.
---
include/net/dst.h +8 -8
@@ -37,7 +37,6 @@struct sk_buff ;struct dst_entry { -struct rcu_head rcu_head;struct dst_entry *child;struct net_device *dev;short error;
@@ -78,6 +77,13 @@ struct dst_entry {__u32 __pad2;#endif +unsigned long lastuse; +union { +struct dst_entry *next; +struct rtable __rcu *rt_next; +struct rt6_info *rt6_next; +struct dn_route __rcu *dn_next; + };/* * Align __refcnt to a 64 bytes alignment
@@ -92,13 +98,7 @@ struct dst_entry {*/ atomic_t __refcnt;/* client references */ int __use; -unsigned long lastuse; -union { -struct dst_entry *next; -struct rtable __rcu *rt_next; -struct rt6_info *rt6_next; -struct dn_route __rcu *dn_next; - }; +struct rcu_head rcu_head; };#ifdef __KERNEL__
Quoted 61 lines · Lai Jiangshan
Quoted 10 lines · David Miller
From: Lai Jiangshan <[email protected]>
Date: Tue, 01 Mar 2011 16:03:44 +0800Quoted 7 lines
struct
dst_entryassumes the size of structrcu_headas 2 * sizeof(long) and manually adds pads for aligning for "__refcnt".When the size of struct
rcu_headis changed, these manual padding is wrong. Use__attribute__((aligned (64)))instead.Quoted 6 lines
Quoted 1 line
Signed-off-by Lai Jiangshan <[email protected]>We don't want to use the align if it's going to waste lots of space.
Instead we want to rearrange the structure so that the alignment comes more cheaply.
Subject: [PATCH 4/4 V2] net,rcu: don't assume the size of struct
rcu_headstruct
dst_entryassumes the size of structrcu_headas 2 * sizeof(long) and manually adds pads for aligning for "__refcnt".When the size of struct
rcu_headis changed, these manual padding are hardly suit for the changes. So we rearrange the structure, and move the seldom accessrcu_headto the end of the structure.Signed-off-by Lai Jiangshan <[email protected]>---
include/net/dst.h +7
-2@@ -37,7 +37,6 @@struct sk_buff ;struct dst_entry { -struct rcu_head rcu_head;struct dst_entry *child;struct net_device *dev;short error;@@ -78,6 +77,13 @@ struct dst_entry {__u32 __pad2;#endif +unsigned long lastuse; +union { +struct dst_entry *next; +struct rtable __rcu *rt_next; +struct rt6_info *rt6_next; +struct dn_route __rcu *dn_next; + };/* * Align __refcnt to a 64 bytes alignment @@ -92,13 +98,7 @@ struct dst_entry {*/ atomic_t __refcnt;/* client references */ int __use; -unsigned long lastuse;
include/net/dst.h struct dst_entry { · line 104
Quoted 10 lines
include/net/dst.h +1
-6-union { -struct dst_entry *next; -struct rtable __rcu *rt_next; -struct rt6_info *rt6_next; -struct dn_route __rcu *dn_next; - }; +struct rcu_head rcu_head; };#ifdef __KERNEL__
Nope...
"lastuse" and "next" must be in this place, or this introduce false sharing we wanted to avoid in the past.
I suggest you leave this code as is, we will address the problem when rcu_head changes (assuming we can test a CONFIG_RCU_HEAD_DEBUG or something)
First part of "struct dst_entry" is mostly read, while part beginning after refcnt is often written.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 78 lines · Eric Dumazet
Quoted 61 lines · Lai Jiangshan
Quoted 10 lines · David Miller
From: Lai Jiangshan <[email protected]>
Date: Tue, 01 Mar 2011 16:03:44 +0800Quoted 7 lines
struct
dst_entryassumes the size of structrcu_headas 2 * sizeof(long) and manually adds pads for aligning for "__refcnt".When the size of struct
rcu_headis changed, these manual padding is wrong. Use__attribute__((aligned (64)))instead.Quoted 6 lines
Quoted 1 line
Signed-off-by Lai Jiangshan <[email protected]>We don't want to use the align if it's going to waste lots of space.
Instead we want to rearrange the structure so that the alignment comes more cheaply.
Subject: [PATCH 4/4 V2] net,rcu: don't assume the size of struct
rcu_headstruct
dst_entryassumes the size of structrcu_headas 2 * sizeof(long) and manually adds pads for aligning for "__refcnt".When the size of struct
rcu_headis changed, these manual padding are hardly suit for the changes. So we rearrange the structure, and move the seldom accessrcu_headto the end of the structure.Signed-off-by Lai Jiangshan <[email protected]>---
include/net/dst.h +7
-2@@ -37,7 +37,6 @@struct sk_buff ;struct dst_entry { -struct rcu_head rcu_head;struct dst_entry *child;struct net_device *dev;short error;@@ -78,6 +77,13 @@ struct dst_entry {__u32 __pad2;#endif +unsigned long lastuse; +union { +struct dst_entry *next; +struct rtable __rcu *rt_next; +struct rt6_info *rt6_next; +struct dn_route __rcu *dn_next; + };/* * Align __refcnt to a 64 bytes alignment @@ -92,13 +98,7 @@ struct dst_entry {*/ atomic_t __refcnt;/* client references */ int __use; -unsigned long lastuse;include/net/dst.h struct dst_entry { · line 104
Quoted 10 lines
include/net/dst.h +1
-6-union { -struct dst_entry *next; -struct rtable __rcu *rt_next; -struct rt6_info *rt6_next; -struct dn_route __rcu *dn_next; - }; +struct rcu_head rcu_head; };#ifdef __KERNEL__Nope...
"lastuse" and "next" must be in this place, or this introduce false sharing we wanted to avoid in the past.
Quoted 7 lines
I suggest you leave this code as is, we will address the problem when
rcu_headchanges (assuming we can test aCONFIG_RCU_HEAD_DEBUGor something)First part of "struct
dst_entry" is mostly read, while part beginning after refcnt is often written.
Is it the cause of false sharing? I thought that all are rare write(except __refcnt) since it is protected by RCU.
Do you allow me just move the seldom access rcu_head to the end of the structure and add pads before __refcnt? I guess it increases about 3% the size of dst_entry.
I accept that I leave this code as is, when I change rcu_head I will notify you.
Thanks,
Lai
Quoted 5 lines · Lai Jiangshan
Is it the cause of false sharing? I thought that all are rare
write(except __refcnt)since it is protected by RCU.Do you allow me just move the seldom access
rcu_headto the end of the structure and add pads before__refcnt? I guess it increases about 3% the size ofdst_entry.
dst_entry is a base class.
Its included at the beginning of other structs.
Moving rcu_head "at the end" just move it right in the middle of upper objects as a matter of fact. This might add one cache line miss on critical network object. A complete audit is needed.
David is doing some changes in this area, so things move fast anyway.
Quoted 1 line
I accept that I leave this code as is, when I change
rcu_headI will
notify you.
Quoted 1 line
Thanks
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 39 lines · Lai Jiangshan
struct
dst_entryassumes the size of structrcu_headas 2 * sizeof(long) and manually adds pads for aligning for "__refcnt".When the size of struct
rcu_headis changed, these manual padding is wrong. Use__attribute__((aligned (64)))instead.Signed-off-by Lai Jiangshan <[email protected]>---
include/net/dst.h +0
-9@@ -62,8 +62,6 @@ struct dst_entry {struct hh_cache *hh;#ifdef CONFIG_XFRM struct xfrm_state *xfrm; -#else -void *__pad1;#endif int (*input)(struct sk_buff *);int (*output)(struct sk_buff *);@@ -74,23 +72,18 @@ struct dst_entry {#ifdef CONFIG_NET_CLS_ROUTE __u32 tclassid; -#else -__u32 __pad2;#endif /* * Align __refcnt to a 64 bytes alignment * (L1_CACHE_SIZE would be too much) -*/ -#ifdef CONFIG_64BIT -long __pad_to_align_refcnt[1 ]; -#endif -/*
include/net/dst.h struct dst_entry { · line 89
Quoted 10 lines
include/net/dst.h +3
-1+* * __refcnt wants to be on a different cache line from * input/output/ops or performance tanks badly */ -atomic_t __refcnt;/* client references */ + atomic_t __refcnt /* client references */ + __attribute__((aligned (64)));int __use;unsigned long lastuse;union {
If struct rcu_head is bigger, this is for debugging purposes, so we dont care about performance, and can avoid wasting ~64 bytes.
Some machines still have about 2.000.000 active dst entries : the convoluted checks we added in include/net/dst.h are here to make sure we dont have huge holes in the dst structure.
(This might change when/if IP route cache is gone)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>